Example #1
0
        public override void Deserialize(BinaryReader reader)
        {
            byte version = reader.ReadByte();

            if (version > StateVersion)
            {
                throw new FormatException();
            }

            Hash         = reader.ReadSerializable <UInt160>();
            Name         = reader.ReadVarString();
            Owner        = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1);
            Type         = (AppChainType)reader.ReadByte();
            Timestamp    = reader.ReadUInt32();
            LastModified = version >= 1 ? reader.ReadUInt32() : Timestamp;
            SeedList     = new string[reader.ReadVarInt()];
            for (int i = 0; i < SeedList.Length; i++)
            {
                SeedList[i] = reader.ReadVarString();
            }
            StandbyValidators = new ECPoint[reader.ReadVarInt()];
            for (int i = 0; i < StandbyValidators.Length; i++)
            {
                StandbyValidators[i] = ECPoint.DeserializeFrom(reader, ECCurve.Secp256r1);
            }
        }
Example #2
0
 void ICloneable <AppChainState> .FromReplica(AppChainState replica)
 {
     Hash              = replica.Hash;
     Name              = replica.Name;
     Owner             = replica.Owner;
     Type              = replica.Type;
     Timestamp         = replica.Timestamp;
     LastModified      = replica.LastModified;
     SeedList          = replica.SeedList;
     StandbyValidators = replica.StandbyValidators;
     _names            = replica._names;
 }
Example #3
0
 public AppChainState(UInt160 hash)
 {
     this.StateVersion      = 1;
     this.Hash              = hash;
     this.Name              = "";
     this.Owner             = ECCurve.Secp256r1.Infinity;
     this.Type              = AppChainType.None;
     this.Timestamp         = 0;
     this.LastModified      = 0;
     this.SeedList          = new string[0];
     this.StandbyValidators = new ECPoint[0];
 }
Example #4
0
 public void CopyFrom(AppChainState state)
 {
     Hash              = state.Hash;
     Name              = state.Name;
     Owner             = state.Owner;
     Type              = state.Type;
     Timestamp         = state.Timestamp;
     LastModified      = state.LastModified;
     SeedList          = state.SeedList;
     StandbyValidators = state.StandbyValidators;
     _names            = state._names;
 }
Example #5
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);
        }