Пример #1
0
        bool CheckWitness(ExecutionEngineBase engine)
        {
            // Fake CheckWitness

            var context = engine.CurrentContext;

            {
                if (context == null)
                {
                    return(false);
                }

                if (!context.EvaluationStack.TryPop(out StackItemBase it))
                {
                    return(false);
                }

                using (it)
                {
                    if (it.ToByteArray() == null)
                    {
                        return(false);
                    }

                    using (var itb = engine.CreateBool(true))
                        context.EvaluationStack.Push(itb);
                }
            }

            return(true);
        }
Пример #2
0
        private bool Contract_GetStorageContext(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            var stack = ctx.EvaluationStack;

            var contract = stack.PopObject <Contract>();

            if (!_contractsCreated.TryGetValue(contract.ScriptHash, out var created))
            {
                return(false);
            }
            if (!created.Equals(new UInt160(engine.CurrentContext.ScriptHash)))
            {
                return(false);
            }

            stack.PushObject(new StorageContext
            {
                ScriptHash = contract.ScriptHash,
                IsReadOnly = false
            });

            return(true);
        }
Пример #3
0
        private StackItemBase DeserializeStackItem(ExecutionEngineBase engine, BinaryReader reader)
        {
            EStackItemType type = (EStackItemType)reader.ReadByte();

            switch (type)
            {
            case EStackItemType.ByteArray:
                return(engine.CreateByteArray(reader.ReadVarBytes()));

            case EStackItemType.Bool:
                return(engine.CreateBool(reader.ReadBoolean()));

            case EStackItemType.Integer:
                return(engine.CreateInteger(new BigInteger(reader.ReadVarBytes())));

            case EStackItemType.Array:
            case EStackItemType.Struct:
            {
                ArrayStackItemBase array;

                if (type == EStackItemType.Struct)
                {
                    array = engine.CreateStruct();
                }
                else
                {
                    array = engine.CreateArray();
                }

                ulong count = reader.ReadVarInt();
                while (count-- > 0)
                {
                    array.Add(DeserializeStackItem(engine, reader));
                }

                return(array);
            }

            case EStackItemType.Map:
            {
                var map = engine.CreateMap();

                ulong count = reader.ReadVarInt();
                while (count-- > 0)
                {
                    StackItemBase key   = DeserializeStackItem(engine, reader);
                    StackItemBase value = DeserializeStackItem(engine, reader);

                    map[key] = value;

                    key.Dispose();
                    value.Dispose();
                }

                return(map);
            }

            default: throw new FormatException();
            }
        }
Пример #4
0
        protected virtual bool Runtime_CheckWitness(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            bool result;
            var  hashOrPubkey = ctx.EvaluationStack.PopByteArray();

            if (hashOrPubkey.Length == 20)
            {
                result = CheckWitness(engine, new UInt160(hashOrPubkey));
            }
            else if (hashOrPubkey.Length == 33)
            {
                result = CheckWitness(engine, new ECPoint(hashOrPubkey));
            }
            else
            {
                return(false);
            }

            ctx.EvaluationStack.Push(result);

            return(true);
        }
Пример #5
0
        void CheckItem(ExecutionEngineBase engine, StackItemBase item)
        {
            int c = engine.ResultStack.Count;

            engine.ResultStack.Push(item);
            Assert.AreEqual(engine.ResultStack.Count, c + 1);

            Assert.IsTrue(engine.ResultStack.TryPeek(0, out StackItemBase obj));

            // PEEK

            obj.Dispose();
            obj = engine.ResultStack.Peek(0);
            Assert.IsNotNull(obj);

            Assert.AreEqual(obj.Type, item.Type);
            Assert.IsTrue(obj.Equals(item));

            // POP

            obj.Dispose();
            obj = engine.ResultStack.Pop();
            Assert.AreEqual(engine.ResultStack.Count, c);

            Assert.IsNotNull(obj);

            Assert.AreEqual(obj.Type, item.Type);
            Assert.IsTrue(obj.Equals(item));
            obj.Dispose();
        }
Пример #6
0
        private bool Contract_Destroy(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            var stack = ctx.EvaluationStack;

            var hash     = new UInt160(engine.CurrentContext.ScriptHash);
            var contract = _contracts.TryGet(hash);

            if (contract == null)
            {
                return(true);
            }

            _contracts.Delete(hash);

            if (contract.HasStorage)
            {
                foreach (var pair in _storages.Find(hash.ToArray()))
                {
                    _storages.Delete(pair.Key);
                }
            }

            return(true);
        }
Пример #7
0
 protected bool CheckWitness(ExecutionEngineBase engine, UInt160 hash)
 {
     // TODO: IVerifiable?
     //IVerifiable container = (IVerifiable)engine.MessageProvider;
     //UInt160[] _hashes_for_verifying = container.GetScriptHashesForVerifying();
     //return _hashes_for_verifying.Contains(hash);
     return(true);
 }
Пример #8
0
        /// <summary>
        /// Assert result
        /// </summary>
        /// <param name="engine">Engine</param>
        /// <param name="result">Result</param>
        /// <param name="logBag">Log bag</param>
        /// <param name="notBag">Not bag</param>
        /// <param name="message">Message</param>
        private void AssertResult(ExecutionEngineBase engine, VMUTExecutionEngineState result, List <string> logBag, List <JToken> notBag, string message)
        {
            AssertAreEqual(engine.State.ToString(), result.State.ToString(), message + "State is different");
            AssertAreEqual(engine.ConsumedGas, result.ConsumedGas, message + "Consumed gas is different");

            AssertAreEqual(logBag.ToArray(), result.Logs ?? new string[0], message + "Logs are different");
            AssertAreEqual(notBag.ToArray(), result.Notifications == null ? new JToken[0] : result.Notifications.Select(u => PrepareJsonItem(u)).ToArray(), message + "Notifies are different");

            AssertResult(engine.InvocationStack, result.InvocationStack, message);
            AssertResult(engine.ResultStack, result.ResultStack, message);
        }
Пример #9
0
        private bool Asset_Create(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            var stack = ctx.EvaluationStack;

            //var tx = (InvocationTransaction)engine.MessageProvider;
            //var assetType = (AssetType)(byte)stack.PopBigInteger();
            //if (!Enum.IsDefined(typeof(AssetType), assetType) || assetType == AssetType.CreditFlag || assetType == AssetType.DutyFlag || assetType == AssetType.GoverningToken || assetType == AssetType.UtilityToken)
            //    return false;
            //if (stack.PeekByteArray().Length > 1024)
            //    return false;
            //var name = Encoding.UTF8.GetString(stack.PopByteArray());
            //var amount = new Fixed8((long)stack.PopBigInteger());
            //if (amount == Fixed8.Zero || amount < -Fixed8.Satoshi) return false;
            //if (assetType == AssetType.Invoice && amount != -Fixed8.Satoshi)
            //    return false;
            //var precision = (byte)stack.PopBigInteger();
            //if (precision > 8) return false;
            //if (assetType == AssetType.Share && precision != 0) return false;
            //if (amount != -Fixed8.Satoshi && amount.GetData() % (long)Math.Pow(10, 8 - precision) != 0)
            //    return false;
            //ECPoint owner = ECPoint.DecodePoint(stack.PopByteArray(), ECCurve.Secp256r1);
            //if (owner.IsInfinity) return false;
            //if (!CheckWitness(engine, owner))
            //    return false;
            //var admin = new UInt160(stack.PopByteArray());
            //var issuer = new UInt160(stack.PopByteArray());
            //Asset asset = _assets.GetOrAdd(tx.Hash, () => new Asset
            //{
            //    Id = tx.Hash,
            //    AssetType = assetType,
            //    Name = name,
            //    Amount = amount,
            //    Available = Fixed8.Zero,
            //    Precision = precision,
            //    Fee = Fixed8.Zero,
            //    FeeAddress = new UInt160(),
            //    Owner = owner,
            //    Admin = admin,
            //    Issuer = issuer,
            //    Expiration = Blockchain.Default.Height + 1 + 2000000,
            //    IsFrozen = false
            //});
            //stack.PushObject(asset);
            return(true);
        }
Пример #10
0
        protected virtual bool Runtime_Log(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            var message = Encoding.UTF8.GetString(ctx.EvaluationStack.PopByteArray());

            _interopService.RaiseOnLog(new LogEventArgs(ctx.ScriptHash.ToArray(), message));

            return(true);
        }
Пример #11
0
        protected virtual bool Runtime_Notify(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            var state = ctx.EvaluationStack.PopObject <StackItemBase>();

            _interopService.RaiseOnNotify(new NotifyEventArgs(ctx.ScriptHash.ToArray(), state));

            return(true);
        }
Пример #12
0
        protected virtual bool Storage_GetReadOnlyContext(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            ctx.EvaluationStack.PushObject(new StorageContext
            {
                ScriptHash = new UInt160(ctx.ScriptHash),
                IsReadOnly = true
            });

            return(true);
        }
Пример #13
0
        private bool Runtime_Deserialize(ExecutionEngineBase engine)
        {
            var context = engine.CurrentContext;

            {
                if (context == null)
                {
                    return(false);
                }

                if (!context.EvaluationStack.TryPop(out StackItemBase it))
                {
                    return(false);
                }

                var data = it.ToByteArray();
                it.Dispose();

                using (MemoryStream ms = new MemoryStream(data, false))
                    using (BinaryReader reader = new BinaryReader(ms))
                    {
                        StackItemBase item = null;

                        try
                        {
                            item = DeserializeStackItem(engine, reader);
                        }
                        catch
                        {
                            if (item != null)
                            {
                                item.Dispose();
                            }
                            return(false);
                        }

                        context.EvaluationStack.Push(item);
                        if (item != null)
                        {
                            item.Dispose();
                        }
                    }
            }

            return(true);
        }
Пример #14
0
        private bool Runtime_Serialize(ExecutionEngineBase engine)
        {
            var context = engine.CurrentContext;

            {
                if (context == null)
                {
                    return(false);
                }

                if (!context.EvaluationStack.TryPop(out StackItemBase it))
                {
                    return(false);
                }

                using (it)
                {
                    using (MemoryStream ms = new MemoryStream())
                        using (BinaryWriter writer = new BinaryWriter(ms))
                        {
                            try
                            {
                                SerializeStackItem(it, writer);
                            }
                            catch
                            {
                                return(false);
                            }

                            writer.Flush();

                            using (var bi = engine.CreateByteArray(ms.ToArray()))
                                context.EvaluationStack.Push(bi);
                        }
                }
            }

            return(true);
        }
Пример #15
0
        /// <summary>
        /// Check if the engine is clean
        /// </summary>
        /// <param name="engine">Engine</param>
        /// <param name="invocationStack">True for Check invocationStack</param>
        protected void CheckClean(ExecutionEngineBase engine, bool invocationStack = true)
        {
            Assert.AreEqual(0, engine.ResultStack.Count);

            if (invocationStack)
            {
                Assert.AreEqual(0, engine.InvocationStack.Count);
            }
            else
            {
                var current = engine.CurrentContext;

                if (current == null)
                {
                    Assert.AreEqual(EVMState.Halt, engine.State);
                }
                else
                {
                    Assert.AreEqual(0, current.EvaluationStack.Count);
                    Assert.AreEqual(0, current.AltStack.Count);
                }
            }
        }
Пример #16
0
        bool Storage_GetContext(ExecutionEngineBase engine)
        {
            var context = engine.CurrentContext;

            {
                if (context == null)
                {
                    return(false);
                }

                var id = context.ScriptHash.ToHexString();
                if (!Storages.TryGetValue(id, out DummyStorageContext stContext))
                {
                    stContext = new DummyStorageContext(id, context.ScriptHash);
                    Storages[stContext.Id] = stContext;
                }

                using (var i = engine.CreateInterop(stContext))
                    context.EvaluationStack.Push(i);
            }

            return(true);
        }
Пример #17
0
        bool Storage_Get(ExecutionEngineBase engine)
        {
            var context = engine.CurrentContext;

            {
                if (context == null)
                {
                    return(false);
                }

                if (!context.EvaluationStack.TryPop(out InteropStackItemBase <DummyStorageContext> inter))
                {
                    return(false);
                }

                using (inter)
                {
                    if (!(inter.Value is DummyStorageContext stContext))
                    {
                        return(false);
                    }

                    if (!context.EvaluationStack.TryPop(out StackItemBase it))
                    {
                        return(false);
                    }

                    using (it)
                    {
                        var key = it.ToByteArray();
                        if (key == null)
                        {
                            return(false);
                        }

                        if (stContext.Storage.TryGetValue(key.ToHexString(), out byte[] value))
Пример #18
0
 protected bool CheckWitness(ExecutionEngineBase engine, ECPoint pubkey)
 {
     // TODO: Contract.CreateSignatureRedeemScript?
     //return CheckWitness(engine, Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash());
     return(true);
 }
Пример #19
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="engine">Execution Engine</param>
 /// <param name="service">Base Service</param>
 public InteropServiceAdapter(ExecutionEngineBase engine, InteropService service)
 {
     _service = service;
     _engine  = engine;
 }
Пример #20
0
 public InvocationProcess(ExecutionEngineBase executionEngine)
 {
     _executionEngine = executionEngine;
 }
Пример #21
0
        private bool Contract_Create(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            var stack = ctx.EvaluationStack;

            var script = stack.PopByteArray();

            if (script.Length > 1024 * 1024)
            {
                return(false);
            }

            var parameters = stack.PopByteArray().Select(p => (ContractParameterType)p).ToArray();

            if (parameters.Length > 252)
            {
                return(false);
            }

            // TODO: PopBigInteger to byte?
            var returnType = (ContractParameterType)(byte)stack.PopBigInteger();
            var metadata   = (ContractMetadata)(byte)stack.PopBigInteger();

            if (stack.PeekByteArray().Length > 252)
            {
                return(false);
            }
            var name = Encoding.UTF8.GetString(stack.PopByteArray());

            if (stack.PeekByteArray().Length > 252)
            {
                return(false);
            }
            var version = Encoding.UTF8.GetString(stack.PopByteArray());

            if (stack.PeekByteArray().Length > 252)
            {
                return(false);
            }
            var author = Encoding.UTF8.GetString(stack.PopByteArray());

            if (stack.PeekByteArray().Length > 252)
            {
                return(false);
            }
            var email = Encoding.UTF8.GetString(stack.PopByteArray());

            if (stack.PeekByteArray().Length > 65536)
            {
                return(false);
            }
            var description = Encoding.UTF8.GetString(stack.PopByteArray());

            var scriptHash = script.ToScriptHash();
            var contract   = _contracts.TryGet(scriptHash);

            if (contract == null)
            {
                contract = new Contract
                {
                    Code = new Code
                    {
                        Script     = script,
                        ScriptHash = scriptHash,
                        Parameters = parameters,
                        ReturnType = returnType,
                        Metadata   = metadata
                    },
                    Name        = name,
                    Version     = version,
                    Author      = author,
                    Email       = email,
                    Description = description
                };

                _contracts.Add(scriptHash, contract);
                _contractsCreated.Add(scriptHash, new UInt160(engine.CurrentContext.ScriptHash));
            }

            stack.PushObject(contract);

            return(true);
        }
Пример #22
0
        private bool Contract_Migrate(ExecutionEngineBase engine)
        {
            var ctx = engine.CurrentContext;

            if (ctx == null)
            {
                return(false);
            }

            var stack = ctx.EvaluationStack;

            var script = stack.PopByteArray();

            if (script.Length > 1024 * 1024)
            {
                return(false);
            }

            var parameters = stack.PopByteArray().Select(p => (ContractParameterType)p).ToArray();

            if (parameters.Length > 252)
            {
                return(false);
            }

            var returnType = (ContractParameterType)(byte)stack.PopBigInteger();
            var metadata   = (ContractMetadata)(byte)stack.PopBigInteger();

            if (stack.PeekByteArray().Length > 252)
            {
                return(false);
            }
            var name = Encoding.UTF8.GetString(stack.PopByteArray());

            if (stack.PeekByteArray().Length > 252)
            {
                return(false);
            }
            var version = Encoding.UTF8.GetString(stack.PopByteArray());

            if (stack.PeekByteArray().Length > 252)
            {
                return(false);
            }
            var author = Encoding.UTF8.GetString(stack.PopByteArray());

            if (stack.PeekByteArray().Length > 252)
            {
                return(false);
            }
            var email = Encoding.UTF8.GetString(stack.PopByteArray());

            if (stack.PeekByteArray().Length > 65536)
            {
                return(false);
            }
            var description = Encoding.UTF8.GetString(stack.PopByteArray());

            var scriptHash = script.ToScriptHash();
            var contract   = _contracts.TryGet(scriptHash);

            if (contract == null)
            {
                contract = new Contract
                {
                    Code = new Code
                    {
                        Script     = script,
                        ScriptHash = scriptHash,
                        Parameters = parameters,
                        ReturnType = returnType,
                        Metadata   = metadata
                    },
                    Name        = name,
                    Version     = version,
                    Author      = author,
                    Email       = email,
                    Description = description
                };

                _contracts.Add(scriptHash, contract);
                _contractsCreated.Add(scriptHash, new UInt160(engine.CurrentContext.ScriptHash));
                if (contract.HasStorage)
                {
                    foreach (var pair in _storages.Find(engine.CurrentContext.ScriptHash).ToArray())
                    {
                        _storages.Add(new StorageKey
                        {
                            ScriptHash = scriptHash,
                            Key        = pair.Key.Key
                        }, new StorageValue
                        {
                            Value = pair.Value.Value
                        });
                    }
                }
            }

            stack.PushObject(contract);

            return(Contract_Destroy(engine));
        }