예제 #1
0
        public bool Create(ExecutionEngine engine)
        {
            if (Trigger != TriggerType.Application)
            {
                return(false);
            }

            // 全名
            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 1024)
            {
                return(false);
            }
            string name = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            // 简写名
            if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
            {
                return(false);
            }
            string symbol = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            // 货币总量
            Fixed8 amount = new Fixed8((long)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger());

            if (amount < Fixed8.Zero)
            {
                return(false);
            }

            // 货币精度
            byte precision = (byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

            if (precision > 8)
            {
                return(false);
            }
            if (amount.GetData() % (long)Math.Pow(10, precision) != 0)
            {
                return(false);
            }

            // 发行人
            ECPoint owner = ECPoint.DecodePoint(engine.CurrentContext.EvaluationStack.Pop().GetByteArray(), ECCurve.Secp256r1);

            // 创世块不做检查
            if (Snapshot.PersistingBlock.Index != 0)
            {
                // 检查发行人的签名
                if (owner.IsInfinity)
                {
                    return(false);
                }
                if (!Service.CheckWitness(engine, owner))
                {
                    return(false);
                }
            }

            // 管理员
            UInt160 admin = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

            // 创世块不做检查
            if (Snapshot.PersistingBlock.Index != 0)
            {
                // 检查管理员的Hash
                if (admin.Equals(UInt160.Zero))
                {
                    return(false);
                }
            }

            UInt160 assetId;

            if (Snapshot.PersistingBlock.Index == 0)
            {
                // 只有在创世块里可以自定义assetId
                assetId = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
            }
            else
            {
                // 用ScriptHash作为assetId
                assetId = new UInt160(engine.CurrentContext.ScriptHash);
            }

            NativeNEP5State state = Snapshot.NativeNEP5s.TryGet(assetId);

            if (state == null)
            {
                state = new NativeNEP5State
                {
                    AssetId     = assetId,
                    Name        = name,
                    Symbol      = symbol,
                    TotalSupply = amount,
                    Decimals    = precision,
                    Owner       = owner,
                    Admin       = admin,
                    BlockIndex  = Snapshot.Height + 1,
                    IsFrozen    = false
                };

                // 保存到数据库
                Snapshot.NativeNEP5s.Add(assetId, state);
            }

            // 设置脚本的返回值
            engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(state));
            return(true);
        }
예제 #2
0
        public bool CreateAppChain(ExecutionEngine engine)
        {
            if (Trigger != TriggerType.Application)
            {
                return(false);
            }
            try
            {
                // 只能在根链上执行创建应用链的指令
                if (!Snapshot.Blockchain.ChainHash.Equals(UInt160.Zero))
                {
                    return(false);
                }

                // 应用链的Hash
                UInt160 hash = new UInt160(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

                // 应用链的名字
                if (engine.CurrentContext.EvaluationStack.Peek().GetByteArray().Length > 252)
                {
                    return(false);
                }
                string name = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());

                // 应用链的所有者
                ECPoint owner = ECPoint.DecodePoint(engine.CurrentContext.EvaluationStack.Pop().GetByteArray(), ECCurve.Secp256r1);
                if (owner.IsInfinity)
                {
                    return(false);
                }

                // 交易的见证人里必须有应用链的所有者
                if (!Service.CheckWitness(engine, owner))
                {
                    return(false);
                }

                AppChainType type = (AppChainType)(byte)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

                // 创建时间
                uint timestamp = (uint)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

                int seedCount = (int)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

                // 种子节点的数量不能为零
                if (seedCount <= 0)
                {
                    return(false);
                }

                string[] seedList = new string[seedCount];
                for (int i = 0; i < seedCount; i++)
                {
                    seedList[i] = Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray());
                }

                // 判断输入的种子节点地址是否有效
                if (!CheckSeedList(seedList, seedCount))
                {
                    return(false);
                }

                int validatorCount = (int)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();

                // 共识节点的数量不能小于四个
                if (validatorCount < 4)
                {
                    return(false);
                }

                ECPoint[] validators = new ECPoint[validatorCount];
                for (int i = 0; i < validatorCount; i++)
                {
                    validators[i] = ECPoint.DecodePoint(Encoding.UTF8.GetString(engine.CurrentContext.EvaluationStack.Pop().GetByteArray()).HexToBytes(), ECCurve.Secp256r1);
                }

                // 判断输入的共识节点字符串格式是否有效
                if (!CheckValidators(validators, validatorCount))
                {
                    return(false);
                }

                AppChainState state = Snapshot.AppChains.TryGet(hash);
                if (state == null)
                {
                    state = new AppChainState
                    {
                        Hash              = hash,
                        Name              = name,
                        Owner             = owner,
                        Type              = type,
                        Timestamp         = timestamp,
                        LastModified      = timestamp,
                        SeedList          = seedList,
                        StandbyValidators = validators,
                    };

                    // 保存到数据库
                    Snapshot.AppChains.Add(hash, state);

                    // 添加通知事件,等待上链后处理
                    if (IsPersisting(engine))
                    {
                        Snapshot.Blockchain.AddAppChainNotification("Create", state);
                    }
                }

                // 设置脚本的返回值
                engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(state));
            }
            catch
            {
                return(false);
            }
            return(true);
        }