Exemple #1
0
 // TODO should run the script and return true if sucess or false if exception
 private bool Validate(Chain chain, out BigInteger fee)
 {
     fee = 0;
     return(true);
 }
        public Chain(Nexus nexus, string name, IEnumerable <SmartContract> contracts, Logger log = null, Chain parentChain = null, Block parentBlock = null)
        {
            Throw.IfNull(nexus, "nexus required");
            Throw.If(contracts == null || !contracts.Any(), "contracts required");

            if (parentChain != null)
            {
                Throw.IfNull(parentBlock, "parent block required");
                Throw.IfNot(nexus.ContainsChain(parentChain), "invalid chain");
                //Throw.IfNot(parentChain.ContainsBlock(parentBlock), "invalid block"); // TODO should this be required?
            }

            var bytes = System.Text.Encoding.UTF8.GetBytes(name.ToLower());
            var hash  = CryptoExtensions.SHA256(bytes);

            this.Address = new Address(hash);

            // init stores
            _transactions        = new KeyValueStore <Transaction>(this.Address, "txs", KeyStoreDataSize.Medium, nexus.CacheSize);
            _blocks              = new KeyValueStore <Block>(this.Address, "blocks", KeyStoreDataSize.Medium, nexus.CacheSize);
            _transactionBlockMap = new KeyValueStore <Hash>(this.Address, "txbk", KeyStoreDataSize.Small, nexus.CacheSize);
            _epochMap            = new KeyValueStore <Epoch>(this.Address, "epoch", KeyStoreDataSize.Medium, nexus.CacheSize);

            foreach (var contract in contracts)
            {
                if (this._contracts.ContainsKey(contract.Name))
                {
                    throw new ChainException("Duplicated contract name: " + contract.Name);
                }

                this._contracts[contract.Name]        = contract;
                this._contractContexts[contract.Name] = new NativeExecutionContext(contract);
            }

            this.Name  = name;
            this.Nexus = nexus;

            this.ParentChain = parentChain;
            this.ParentBlock = parentBlock;

            if (nexus.CacheSize == -1)
            {
                this.Storage = new MemoryStorageContext();
            }
            else
            {
                this.Storage = new DiskStorageContext(this.Address, "data", KeyStoreDataSize.Medium);
            }

            this.Log = Logger.Init(log);

            if (parentChain != null)
            {
                parentChain._childChains[name] = this;
                _level = ParentChain.Level + 1;
            }
            else
            {
                _level = 1;
            }
        }
Exemple #3
0
 public bool IsValid(Chain chain)
 {
     return(chain.Name == this.ChainName && chain.Nexus.Name == this.NexusName);
 }
Exemple #4
0
        internal Chain CreateChain(StorageContext storage, Address owner, string name, Chain parentChain, Block parentBlock, IEnumerable <string> contractNames)
        {
            if (name != RootChainName)
            {
                if (parentChain == null || parentBlock == null)
                {
                    return(null);
                }
            }

            if (!Chain.ValidateName(name))
            {
                return(null);
            }

            // check if already exists something with that name
            if (ChainExists(name))
            {
                return(null);
            }

            if (contractNames == null)
            {
                return(null);
            }

            var chain = new Chain(this, name, _logger);

            var contractSet = new HashSet <string>(contractNames);

            contractSet.Add(GasContractName);
            contractSet.Add(TokenContractName);
            chain.DeployContracts(contractSet);

            // add to persistent list of chains
            var chainList = this.Chains.ToList();

            chainList.Add(name);
            this.Chains = chainList;

            // add address and name mapping
            this._vars.Set(ChainNameMapKey + chain.Name, chain.Address.PublicKey);
            this._vars.Set(ChainAddressMapKey + chain.Address.Text, Encoding.UTF8.GetBytes(chain.Name));

            if (parentChain != null)
            {
                this._vars.Set(ChainParentNameKey + chain.Name, Encoding.UTF8.GetBytes(parentChain.Name));
                this._vars.Set(ChainParentBlockKey + chain.Name, parentBlock.Hash.ToByteArray());

                var childrenList = GetChildrenListOfChain(parentChain.Name);
                childrenList.Add <string>(chain.Name);

                var tokenList = this.Tokens;
                // copy each token current supply relative to parent to the chain new
                foreach (var tokenSymbol in tokenList)
                {
                    var parentSupply = new SupplySheet(tokenSymbol, parentChain, this);
                    var localSupply  = new SupplySheet(tokenSymbol, chain, this);
                    localSupply.Init(chain.Storage, storage, parentSupply);
                }
            }
            else
            {
                this.RootChainAddress = chain.Address;
            }

            _chainCache[chain.Name] = chain;

            return(chain);
        }