コード例 #1
0
 static string StackItemToString(StackItem item, string?typeHint = null)
 {
     return(typeHint switch
     {
         "Boolean" => item.GetBoolean().ToString(),
         "Integer" => item.GetBigInteger().ToString(),
         "String" => item.GetString(),
         _ => item.GetBigInteger().ToHexString(),
     });
コード例 #2
0
        public void TestTotalSupply()
        {
            var         mockSnapshot = new Mock <Snapshot>();
            var         myDataCache  = new TestDataCache <StorageKey, StorageItem>();
            StorageItem item         = new StorageItem
            {
                Value = new byte[] { 0x01 }
            };
            var key = CreateStorageKey(Prefix_TotalSupply);

            var ServiceHash = "test".ToInteropMethodHash();

            byte[] script = null;
            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitSysCall(ServiceHash);
                script = sb.ToArray();
            }
            var Hash = script.ToScriptHash();

            key.ScriptHash = Hash;

            myDataCache.Add(key, item);
            mockSnapshot.SetupGet(p => p.Storages).Returns(myDataCache);
            TestNep5Token     test      = new TestNep5Token();
            ApplicationEngine ae        = new ApplicationEngine(TriggerType.Application, null, mockSnapshot.Object, 0);
            StackItem         stackItem = test.TotalSupply(ae, null);

            stackItem.GetBigInteger().Should().Be(1);
        }
コード例 #3
0
 static JToken StackItemToJson(StackItem item, string?typeHint)
 {
     return(typeHint switch
     {
         "Boolean" => item.GetBoolean().ToString(),
         "Integer" => item.GetBigInteger().ToString(),
         "String" => item.GetString(),
         _ => item switch
         {
             Neo.VM.Types.Boolean _ => item.GetBoolean().ToString(),
             Neo.VM.Types.ByteArray _ => $"{item.GetBigInteger().ToHexString()} ({item.GetString()})",
             Neo.VM.Types.Integer _ => item.GetBigInteger().ToString(),
             Neo.VM.Types.Array array => new JArray(array.Select(i => StackItemToJson(i, null))),
             _ => throw new NotSupportedException(item.GetType().Name),
         }
     });
コード例 #4
0
ファイル: UT_Nep5Token.cs プロジェクト: snowypowers/neo
        public void TestTotalSupplyDecimal()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot();

            TestNep5Token test        = new TestNep5Token();
            BigInteger    totalSupply = 100_000_000;

            totalSupply *= test.Factor;

            StorageItem item = new StorageItem
            {
                Value = totalSupply.ToByteArrayStandard()
            };
            var key = CreateStorageKey(Prefix_TotalSupply);

            var ServiceHash = "test".ToInteropMethodHash();

            byte[] script = null;
            using (ScriptBuilder sb = new ScriptBuilder())
            {
                sb.EmitSysCall(ServiceHash);
                script = sb.ToArray();
            }
            var Hash = script.ToScriptHash();

            key.ScriptHash = Hash;

            snapshot.Storages.Add(key, item);

            ApplicationEngine ae        = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
            StackItem         stackItem = test.TotalSupply(ae, null);

            stackItem.GetBigInteger().Should().Be(10_000_000_000_000_000);
        }
コード例 #5
0
        public static string StackItemAsString(StackItem item, bool addQuotes = false)
        {
            if (item.IsArray)
            {
                var s     = new StringBuilder();
                var items = item.GetArray();

                s.Append('[');
                for (int i = 0; i < items.Length; i++)
                {
                    var element = items[i];
                    if (i > 0)
                    {
                        s.Append(',');
                    }
                    s.Append(StackItemAsString(element));
                }
                s.Append(']');
                return(s.ToString());
            }

            if (item is Neo.VM.Types.Boolean)
            {
                return(item.GetBoolean().ToString());
            }

            if (item is Neo.VM.Types.Integer)
            {
                return(item.GetBigInteger().ToString());
            }

            if (item is Neo.VM.Types.InteropInterface)
            {
                return("{InteropInterface}");
            }

            var data = item.GetByteArray();

            if (data == null)
            {
                return("[Null]");
            }

            if (data == null || data.Length == 0)
            {
                return("False");
            }


            return(FormattingUtils.OutputData(data, addQuotes));
        }
コード例 #6
0
        private void DumpItem(StackItem item, int space = 0)
        {
            var spacestr = "";

            for (var i = 0; i < space; i++)
            {
                spacestr += "    ";
            }
            Console.WriteLine(spacestr + "got Param:" + item.GetType().ToString());

            if (item is Neo.VM.Types.Array || item is Neo.VM.Types.Struct)
            {
                var array = item as Neo.VM.Types.Array;
                for (var i = 0; i < array.Count; i++)
                {
                    var subitem = array[i];
                    DumpItem(subitem, space + 1);
                }
            }
            else if (item is Neo.VM.Types.Map)
            {
                var map = item as Neo.VM.Types.Map;
                foreach (var subitem in map)
                {
                    Console.WriteLine("---Key---");
                    DumpItemShort(subitem.Key, space + 1);
                    Console.WriteLine("---Value---");
                    DumpItem(subitem.Value, space + 1);
                }
            }
            else
            {
                Console.WriteLine(spacestr + "--as num:" + item.GetBigInteger());

                Console.WriteLine(spacestr + "--as bin:" + NeonTestTool.Bytes2HexString(item.GetByteArray()));
                if (item is Neo.VM.Types.ByteArray)
                {
                    var str = item.GetString();
                    if (CheckAsciiChar(str))
                    {
                        Console.WriteLine(spacestr + "--as str:" + item.GetString());
                    }
                }
            }
        }
コード例 #7
0
ファイル: UT_Nep5Token.cs プロジェクト: bspanda98/neo
        public void TestTotalSupply()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot();

            StorageItem item = new StorageItem
            {
                Value = new byte[] { 0x01 }
            };
            var key = CreateStorageKey(Prefix_TotalSupply);

            key.Id = test.Id;

            snapshot.Storages.Add(key, item);
            ApplicationEngine ae        = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
            StackItem         stackItem = test.TotalSupply(ae, null);

            stackItem.GetBigInteger().Should().Be(1);
        }
コード例 #8
0
        public static ContractParameter ToParameter(this StackItem item)
        {
            switch (item.GetType().Name)
            {
            case "Array":
            case "Struct":
                return(new ContractParameter
                {
                    Type = ContractParameterType.Array,
                    Value = item.GetArray().Select(p => p.ToParameter()).ToArray()
                });

            case "Boolean":
                return(new ContractParameter
                {
                    Type = ContractParameterType.Boolean,
                    Value = item.GetBoolean()
                });

            case "ByteArray":
                return(new ContractParameter
                {
                    Type = ContractParameterType.ByteArray,
                    Value = item.GetByteArray()
                });

            case "Integer":
                return(new ContractParameter
                {
                    Type = ContractParameterType.Integer,
                    Value = item.GetBigInteger()
                });

            case "InteropInterface":
                return(new ContractParameter
                {
                    Type = ContractParameterType.InteropInterface
                });

            default:
                throw new ArgumentException();
            }
        }
コード例 #9
0
        public static ContractParameter ToParameter(this StackItem item)
        {
            switch (item)
            {
            case VMArray array:
                return(new ContractParameter
                {
                    Type = ContractParameterType.Array,
                    Value = array.Select(p => p.ToParameter()).ToArray()
                });

            case VMBoolean _:
                return(new ContractParameter
                {
                    Type = ContractParameterType.Boolean,
                    Value = item.GetBoolean()
                });

            case ByteArray _:
                return(new ContractParameter
                {
                    Type = ContractParameterType.ByteArray,
                    Value = item.GetByteArray()
                });

            case Integer _:
                return(new ContractParameter
                {
                    Type = ContractParameterType.Integer,
                    Value = item.GetBigInteger()
                });

            case InteropInterface _:
                return(new ContractParameter
                {
                    Type = ContractParameterType.InteropInterface
                });

            default:
                throw new ArgumentException();
            }
        }
コード例 #10
0
ファイル: LuxUtils.cs プロジェクト: simplitech/neo-lux
 public static object FromStackItem(this StackItem item)
 {
     if (item is VM.Types.Integer)
     {
         return(item.GetBigInteger());
     }
     else
     if (item is VM.Types.Boolean)
     {
         return(item.GetBoolean());
     }
     else
     if (item is VM.Types.ByteArray)
     {
         return(item.GetByteArray());
     }
     else
     {
         throw new NotImplementedException();
     }
 }
コード例 #11
0
ファイル: Helpers.cs プロジェクト: Lichen9618/neo-debugger
        internal static bool TryGetValue(this StackItem item, string type, out string value)
        {
            if (item != null && !string.IsNullOrEmpty(type))
            {
                switch (type)
                {
                case "Boolean":
                    value = item.GetBoolean().ToString();
                    return(true);

                case "Integer":
                    value = item.GetBigInteger().ToString();
                    return(true);

                case "String":
                    value = item.GetString();
                    return(true);
                }
            }

            value = string.Empty;
            return(false);
        }
コード例 #12
0
ファイル: UT_Nep5Token.cs プロジェクト: bspanda98/neo
        public void TestTotalSupplyDecimal()
        {
            var snapshot = Blockchain.Singleton.GetSnapshot();

            BigInteger totalSupply = 100_000_000;

            totalSupply *= test.Factor;

            StorageItem item = new StorageItem
            {
                Value = totalSupply.ToByteArrayStandard()
            };
            var key = CreateStorageKey(Prefix_TotalSupply);

            key.Id = test.Id;

            snapshot.Storages.Add(key, item);

            ApplicationEngine ae        = new ApplicationEngine(TriggerType.Application, null, snapshot, 0);
            StackItem         stackItem = test.TotalSupply(ae, null);

            stackItem.GetBigInteger().Should().Be(10_000_000_000_000_000);
        }
コード例 #13
0
        private static bool Crypto_CheckMultiSig(ApplicationEngine engine)
        {
            int n;

            byte[][]  pubkeys;
            StackItem item = engine.CurrentContext.EvaluationStack.Pop();

            if (item is VMArray array1)
            {
                pubkeys = array1.Select(p => p.GetByteArray()).ToArray();
                n       = pubkeys.Length;
                if (n == 0)
                {
                    return(false);
                }
            }
            else
            {
                n = (int)item.GetBigInteger();
                if (n < 1 || n > engine.CurrentContext.EvaluationStack.Count)
                {
                    return(false);
                }
                pubkeys = new byte[n][];
                for (int i = 0; i < n; i++)
                {
                    pubkeys[i] = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
                }
            }

            int m;

            byte[][] signatures;
            item = engine.CurrentContext.EvaluationStack.Pop();
            if (item is VMArray array2)
            {
                signatures = array2.Select(p => p.GetByteArray()).ToArray();
                m          = signatures.Length;
                if (m == 0 || m > n)
                {
                    return(false);
                }
            }
            else
            {
                m = (int)item.GetBigInteger();
                if (m < 1 || m > n || m > engine.CurrentContext.EvaluationStack.Count)
                {
                    return(false);
                }
                signatures = new byte[m][];
                for (int i = 0; i < m; i++)
                {
                    signatures[i] = engine.CurrentContext.EvaluationStack.Pop().GetByteArray();
                }
            }
            byte[] message  = engine.ScriptContainer.GetHashData();
            bool   fSuccess = true;

            try
            {
                for (int i = 0, j = 0; fSuccess && i < m && j < n;)
                {
                    if (Crypto.Default.VerifySignature(message, signatures[i], pubkeys[j]))
                    {
                        i++;
                    }
                    j++;
                    if (m - i > n - j)
                    {
                        fSuccess = false;
                    }
                }
            }
            catch (ArgumentException)
            {
                fSuccess = false;
            }
            engine.CurrentContext.EvaluationStack.Push(fSuccess);
            return(true);
        }
コード例 #14
0
            private static bool Crypto_ECDsaCheckMultiSig(ApplicationEngine engine)
            {
                StackItem           item0   = engine.CurrentContext.EvaluationStack.Pop();
                ReadOnlySpan <byte> message = item0 switch
                {
                    InteropInterface _interface => _interface.GetInterface <IVerifiable>().GetHashData(),
                    Null _ => engine.ScriptContainer.GetHashData(),
                    _ => item0.GetSpan()
                };
                int n;

                byte[][]  pubkeys;
                StackItem item = engine.CurrentContext.EvaluationStack.Pop();

                if (item is Array array1)
                {
                    pubkeys = array1.Select(p => p.GetSpan().ToArray()).ToArray();
                    n       = pubkeys.Length;
                    if (n == 0)
                    {
                        return(false);
                    }
                }
                else
                {
                    n = (int)item.GetBigInteger();
                    if (n < 1 || n > engine.CurrentContext.EvaluationStack.Count)
                    {
                        return(false);
                    }
                    pubkeys = new byte[n][];
                    for (int i = 0; i < n; i++)
                    {
                        pubkeys[i] = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray();
                    }
                }
                int m;

                byte[][] signatures;
                item = engine.CurrentContext.EvaluationStack.Pop();
                if (item is Array array2)
                {
                    signatures = array2.Select(p => p.GetSpan().ToArray()).ToArray();
                    m          = signatures.Length;
                    if (m == 0 || m > n)
                    {
                        return(false);
                    }
                }
                else
                {
                    m = (int)item.GetBigInteger();
                    if (m < 1 || m > n || m > engine.CurrentContext.EvaluationStack.Count)
                    {
                        return(false);
                    }
                    signatures = new byte[m][];
                    for (int i = 0; i < m; i++)
                    {
                        signatures[i] = engine.CurrentContext.EvaluationStack.Pop().GetSpan().ToArray();
                    }
                }
                bool fSuccess = true;

                try
                {
                    for (int i = 0, j = 0; fSuccess && i < m && j < n;)
                    {
                        if (Cryptography.Crypto.VerifySignature(message, signatures[i], pubkeys[j]))
                        {
                            i++;
                        }
                        j++;
                        if (m - i > n - j)
                        {
                            fSuccess = false;
                        }
                    }
                }
                catch (ArgumentException)
                {
                    fSuccess = false;
                }
                engine.CurrentContext.EvaluationStack.Push(fSuccess);
                return(true);
            }
        }
コード例 #15
0
ファイル: FormattingUtils.cs プロジェクト: simplitech/neo-lux
        public static string StackItemAsString(StackItem item, bool addQuotes = false, VMType hintType = VMType.Unknown)
        {
            if (item is ICollection)
            {
                var bytes = item.GetByteArray();
                if (bytes != null && bytes.Length == 20)
                {
                    var signatureHash = new UInt160(bytes);
                    return(CryptoUtils.ToAddress(signatureHash));
                }

                var s     = new StringBuilder();
                var items = (ICollection)item;

                s.Append('[');
                int i = 0;
                foreach (StackItem element in items)
                {
                    if (i > 0)
                    {
                        s.Append(',');
                    }
                    s.Append(StackItemAsString(element));

                    i++;
                }
                s.Append(']');


                return(s.ToString());
            }

            if (item is VM.Types.Boolean && hintType == VMType.Unknown)
            {
                return(item.GetBoolean().ToString());
            }

            if (item is VM.Types.Integer && hintType == VMType.Unknown)
            {
                return(item.GetBigInteger().ToString());
            }

            if (item is VM.Types.InteropInterface)
            {
                var type = ((VM.Types.InteropInterface)item).GetInterfaceType();
                return($"{type.Name}");
            }

            byte[] data = null;

            try
            {
                data = item.GetByteArray();
            }
            catch
            {
            }

            if ((data == null || data.Length == 0) && hintType == VMType.Unknown)
            {
                return("Null");
            }

            if (hintType == VMType.Array)
            {
                var s = new StringBuilder();
                s.Append('[');
                int count = 0;
                if (data.Length > 0)
                {
                    var array = (VM.Types.Array)item;
                    foreach (var entry in array)
                    {
                        if (count > 0)
                        {
                            s.Append(", ");
                        }
                        count++;

                        s.Append(StackItemAsString(entry, addQuotes, VMType.Unknown));
                    }
                }
                s.Append(']');

                return(s.ToString());
            }

            return(FormattingUtils.OutputData(data, addQuotes, hintType));
        }
コード例 #16
0
        private void ExecuteOp(OpCode opcode, ExecutionContext context)
        {
            if (opcode >= OpCode.PUSHBYTES1 && opcode <= OpCode.PUSHBYTES75)
            {
                context.EvaluationStack.Push(context.OpReader.ReadBytes((byte)opcode));
            }
            else
            {
                switch (opcode)
                {
                // Push value
                case OpCode.PUSH0:
                    context.EvaluationStack.Push(new byte[0]);
                    break;

                case OpCode.PUSHDATA1:
                    context.EvaluationStack.Push(context.OpReader.ReadBytes(context.OpReader.ReadByte()));
                    break;

                case OpCode.PUSHDATA2:
                    context.EvaluationStack.Push(context.OpReader.ReadBytes(context.OpReader.ReadUInt16()));
                    break;

                case OpCode.PUSHDATA4:
                    context.EvaluationStack.Push(context.OpReader.ReadBytes(context.OpReader.ReadInt32()));
                    break;

                case OpCode.PUSHM1:
                case OpCode.PUSH1:
                case OpCode.PUSH2:
                case OpCode.PUSH3:
                case OpCode.PUSH4:
                case OpCode.PUSH5:
                case OpCode.PUSH6:
                case OpCode.PUSH7:
                case OpCode.PUSH8:
                case OpCode.PUSH9:
                case OpCode.PUSH10:
                case OpCode.PUSH11:
                case OpCode.PUSH12:
                case OpCode.PUSH13:
                case OpCode.PUSH14:
                case OpCode.PUSH15:
                case OpCode.PUSH16:
                    context.EvaluationStack.Push((int)opcode - (int)OpCode.PUSH1 + 1);
                    break;

                // Control
                case OpCode.NOP:
                    break;

                case OpCode.JMP:
                case OpCode.JMPIF:
                case OpCode.JMPIFNOT:
                {
                    int offset = context.OpReader.ReadInt16();
                    offset = context.InstructionPointer + offset - 3;
                    if (offset < 0 || offset > context.Script.Length)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    bool fValue = true;
                    if (opcode > OpCode.JMP)
                    {
                        fValue = context.EvaluationStack.Pop().GetBoolean();
                        if (opcode == OpCode.JMPIFNOT)
                        {
                            fValue = !fValue;
                        }
                    }
                    if (fValue)
                    {
                        context.InstructionPointer = offset;
                    }
                }
                break;

                case OpCode.CALL:
                {
                    ExecutionContext contextCall = LoadScript(context.Script);
                    context.EvaluationStack.CopyTo(contextCall.EvaluationStack);
                    contextCall.InstructionPointer = context.InstructionPointer;
                    context.EvaluationStack.Clear();
                    context.InstructionPointer += 2;
                    ExecuteOp(OpCode.JMP, contextCall);
                }
                break;

                case OpCode.RET:
                    using (ExecutionContext contextPop = InvocationStack.Pop())
                    {
                        int rvcount = contextPop.RVCount;
                        if (rvcount == -1)
                        {
                            rvcount = contextPop.EvaluationStack.Count;
                        }
                        if (rvcount > 0)
                        {
                            if (contextPop.EvaluationStack.Count < rvcount)
                            {
                                State |= VMState.FAULT;
                                return;
                            }
                            RandomAccessStack <StackItem> stacEval = InvocationStack.Count == 0 ? ResultStack : CurrentContext.EvaluationStack;
                            contextPop.EvaluationStack.CopyTo(stacEval, rvcount);
                        }
                        if (contextPop.RVCount == -1 && InvocationStack.Count > 0)
                        {
                            contextPop.AltStack.CopyTo(CurrentContext.AltStack);
                        }
                    }
                    if (InvocationStack.Count == 0)
                    {
                        State |= VMState.HALT;
                    }
                    break;

                case OpCode.APPCALL:
                case OpCode.TAILCALL:
                {
                    if (table == null)
                    {
                        State |= VMState.FAULT;
                        return;
                    }

                    byte[] scriptHash = context.OpReader.ReadBytes(20);
                    if (scriptHash.All(p => p == 0))
                    {
                        scriptHash = context.EvaluationStack.Pop().GetByteArray();
                    }

                    byte[] script = table.GetScript(scriptHash);
                    if (script == null)
                    {
                        State |= VMState.FAULT;
                        return;
                    }

                    ExecutionContext newContext = LoadScript(script);
                    context.EvaluationStack.CopyTo(newContext.EvaluationStack);

                    if (opcode == OpCode.TAILCALL)
                    {
                        InvocationStack.Remove(1).Dispose();
                    }
                    else
                    {
                        context.EvaluationStack.Clear();
                    }
                }
                break;

                case OpCode.SYSCALL:
                    if (!Service.Invoke(Encoding.ASCII.GetString(context.OpReader.ReadVarBytes(252)), this))
                    {
                        State |= VMState.FAULT;
                    }
                    break;

                // Stack ops
                case OpCode.DUPFROMALTSTACK:
                    context.EvaluationStack.Push(context.AltStack.Peek());
                    break;

                case OpCode.TOALTSTACK:
                    context.AltStack.Push(context.EvaluationStack.Pop());
                    break;

                case OpCode.FROMALTSTACK:
                    context.EvaluationStack.Push(context.AltStack.Pop());
                    break;

                case OpCode.XDROP:
                {
                    int n = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (n < 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    context.EvaluationStack.Remove(n);
                }
                break;

                case OpCode.XSWAP:
                {
                    int n = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (n < 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    if (n == 0)
                    {
                        break;
                    }
                    StackItem xn = context.EvaluationStack.Peek(n);
                    context.EvaluationStack.Set(n, context.EvaluationStack.Peek());
                    context.EvaluationStack.Set(0, xn);
                }
                break;

                case OpCode.XTUCK:
                {
                    int n = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (n <= 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    context.EvaluationStack.Insert(n, context.EvaluationStack.Peek());
                }
                break;

                case OpCode.DEPTH:
                    context.EvaluationStack.Push(context.EvaluationStack.Count);
                    break;

                case OpCode.DROP:
                    context.EvaluationStack.Pop();
                    break;

                case OpCode.DUP:
                    context.EvaluationStack.Push(context.EvaluationStack.Peek());
                    break;

                case OpCode.NIP:
                    context.EvaluationStack.Remove(1);
                    break;

                case OpCode.OVER:
                    context.EvaluationStack.Push(context.EvaluationStack.Peek(1));
                    break;

                case OpCode.PICK:
                {
                    int n = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (n < 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    context.EvaluationStack.Push(context.EvaluationStack.Peek(n));
                }
                break;

                case OpCode.ROLL:
                {
                    int n = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (n < 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    if (n == 0)
                    {
                        break;
                    }
                    context.EvaluationStack.Push(context.EvaluationStack.Remove(n));
                }
                break;

                case OpCode.ROT:
                    context.EvaluationStack.Push(context.EvaluationStack.Remove(2));
                    break;

                case OpCode.SWAP:
                    context.EvaluationStack.Push(context.EvaluationStack.Remove(1));
                    break;

                case OpCode.TUCK:
                    context.EvaluationStack.Insert(2, context.EvaluationStack.Peek());
                    break;

                case OpCode.CAT:
                {
                    byte[] x2 = context.EvaluationStack.Pop().GetByteArray();
                    byte[] x1 = context.EvaluationStack.Pop().GetByteArray();
                    context.EvaluationStack.Push(x1.Concat(x2).ToArray());
                }
                break;

                case OpCode.SUBSTR:
                {
                    int count = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (count < 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    int index = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (index < 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    byte[] x = context.EvaluationStack.Pop().GetByteArray();
                    context.EvaluationStack.Push(x.Skip(index).Take(count).ToArray());
                }
                break;

                case OpCode.LEFT:
                {
                    int count = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (count < 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    byte[] x = context.EvaluationStack.Pop().GetByteArray();
                    context.EvaluationStack.Push(x.Take(count).ToArray());
                }
                break;

                case OpCode.RIGHT:
                {
                    int count = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (count < 0)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    byte[] x = context.EvaluationStack.Pop().GetByteArray();
                    if (x.Length < count)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    context.EvaluationStack.Push(x.Skip(x.Length - count).ToArray());
                }
                break;

                case OpCode.SIZE:
                {
                    byte[] x = context.EvaluationStack.Pop().GetByteArray();
                    context.EvaluationStack.Push(x.Length);
                }
                break;

                // Bitwise logic
                case OpCode.INVERT:
                {
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(~x);
                }
                break;

                case OpCode.AND:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 & x2);
                }
                break;

                case OpCode.OR:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 | x2);
                }
                break;

                case OpCode.XOR:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 ^ x2);
                }
                break;

                case OpCode.EQUAL:
                {
                    StackItem x2 = context.EvaluationStack.Pop();
                    StackItem x1 = context.EvaluationStack.Pop();
                    context.EvaluationStack.Push(x1.Equals(x2));
                }
                break;

                // Numeric
                case OpCode.INC:
                {
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x + 1);
                }
                break;

                case OpCode.DEC:
                {
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x - 1);
                }
                break;

                case OpCode.SIGN:
                {
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x.Sign);
                }
                break;

                case OpCode.NEGATE:
                {
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(-x);
                }
                break;

                case OpCode.ABS:
                {
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(BigInteger.Abs(x));
                }
                break;

                case OpCode.NOT:
                {
                    bool x = context.EvaluationStack.Pop().GetBoolean();
                    context.EvaluationStack.Push(!x);
                }
                break;

                case OpCode.NZ:
                {
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x != BigInteger.Zero);
                }
                break;

                case OpCode.ADD:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 + x2);
                }
                break;

                case OpCode.SUB:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 - x2);
                }
                break;

                case OpCode.MUL:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 * x2);
                }
                break;

                case OpCode.DIV:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 / x2);
                }
                break;

                case OpCode.MOD:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 % x2);
                }
                break;

                case OpCode.SHL:
                {
                    int        n = (int)context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x << n);
                }
                break;

                case OpCode.SHR:
                {
                    int        n = (int)context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x >> n);
                }
                break;

                case OpCode.BOOLAND:
                {
                    bool x2 = context.EvaluationStack.Pop().GetBoolean();
                    bool x1 = context.EvaluationStack.Pop().GetBoolean();
                    context.EvaluationStack.Push(x1 && x2);
                }
                break;

                case OpCode.BOOLOR:
                {
                    bool x2 = context.EvaluationStack.Pop().GetBoolean();
                    bool x1 = context.EvaluationStack.Pop().GetBoolean();
                    context.EvaluationStack.Push(x1 || x2);
                }
                break;

                case OpCode.NUMEQUAL:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 == x2);
                }
                break;

                case OpCode.NUMNOTEQUAL:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 != x2);
                }
                break;

                case OpCode.LT:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 < x2);
                }
                break;

                case OpCode.GT:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 > x2);
                }
                break;

                case OpCode.LTE:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 <= x2);
                }
                break;

                case OpCode.GTE:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(x1 >= x2);
                }
                break;

                case OpCode.MIN:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(BigInteger.Min(x1, x2));
                }
                break;

                case OpCode.MAX:
                {
                    BigInteger x2 = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x1 = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(BigInteger.Max(x1, x2));
                }
                break;

                case OpCode.WITHIN:
                {
                    BigInteger b = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger a = context.EvaluationStack.Pop().GetBigInteger();
                    BigInteger x = context.EvaluationStack.Pop().GetBigInteger();
                    context.EvaluationStack.Push(a <= x && x < b);
                }
                break;

                // Crypto
                case OpCode.SHA1:
                    using (SHA1 sha = SHA1.Create())
                    {
                        byte[] x = context.EvaluationStack.Pop().GetByteArray();
                        context.EvaluationStack.Push(sha.ComputeHash(x));
                    }
                    break;

                case OpCode.SHA256:
                    using (SHA256 sha = SHA256.Create())
                    {
                        byte[] x = context.EvaluationStack.Pop().GetByteArray();
                        context.EvaluationStack.Push(sha.ComputeHash(x));
                    }
                    break;

                case OpCode.HASH160:
                {
                    byte[] x = context.EvaluationStack.Pop().GetByteArray();
                    context.EvaluationStack.Push(Crypto.Hash160(x));
                }
                break;

                case OpCode.HASH256:
                {
                    byte[] x = context.EvaluationStack.Pop().GetByteArray();
                    context.EvaluationStack.Push(Crypto.Hash256(x));
                }
                break;

                case OpCode.CHECKSIG:
                {
                    byte[] pubkey    = context.EvaluationStack.Pop().GetByteArray();
                    byte[] signature = context.EvaluationStack.Pop().GetByteArray();
                    try
                    {
                        context.EvaluationStack.Push(Crypto.VerifySignature(ScriptContainer.GetMessage(), signature, pubkey));
                    }
                    catch (ArgumentException)
                    {
                        context.EvaluationStack.Push(false);
                    }
                }
                break;

                case OpCode.VERIFY:
                {
                    byte[] pubkey    = context.EvaluationStack.Pop().GetByteArray();
                    byte[] signature = context.EvaluationStack.Pop().GetByteArray();
                    byte[] message   = context.EvaluationStack.Pop().GetByteArray();
                    try
                    {
                        context.EvaluationStack.Push(Crypto.VerifySignature(message, signature, pubkey));
                    }
                    catch (ArgumentException)
                    {
                        context.EvaluationStack.Push(false);
                    }
                }
                break;

                case OpCode.CHECKMULTISIG:
                {
                    int       n;
                    byte[][]  pubkeys;
                    StackItem item = context.EvaluationStack.Pop();
                    if (item is VMArray array1)
                    {
                        pubkeys = array1.Select(p => p.GetByteArray()).ToArray();
                        n       = pubkeys.Length;
                        if (n == 0)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                    }
                    else
                    {
                        n = (int)item.GetBigInteger();
                        if (n < 1 || n > context.EvaluationStack.Count)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                        pubkeys = new byte[n][];
                        for (int i = 0; i < n; i++)
                        {
                            pubkeys[i] = context.EvaluationStack.Pop().GetByteArray();
                        }
                    }
                    int      m;
                    byte[][] signatures;
                    item = context.EvaluationStack.Pop();
                    if (item is VMArray array2)
                    {
                        signatures = array2.Select(p => p.GetByteArray()).ToArray();
                        m          = signatures.Length;
                        if (m == 0 || m > n)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                    }
                    else
                    {
                        m = (int)item.GetBigInteger();
                        if (m < 1 || m > n || m > context.EvaluationStack.Count)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                        signatures = new byte[m][];
                        for (int i = 0; i < m; i++)
                        {
                            signatures[i] = context.EvaluationStack.Pop().GetByteArray();
                        }
                    }
                    byte[] message  = ScriptContainer.GetMessage();
                    bool   fSuccess = true;
                    try
                    {
                        for (int i = 0, j = 0; fSuccess && i < m && j < n;)
                        {
                            if (Crypto.VerifySignature(message, signatures[i], pubkeys[j]))
                            {
                                i++;
                            }
                            j++;
                            if (m - i > n - j)
                            {
                                fSuccess = false;
                            }
                        }
                    }
                    catch (ArgumentException)
                    {
                        fSuccess = false;
                    }
                    context.EvaluationStack.Push(fSuccess);
                }
                break;

                // Array
                case OpCode.ARRAYSIZE:
                {
                    StackItem item = context.EvaluationStack.Pop();
                    if (item is ICollection collection)
                    {
                        context.EvaluationStack.Push(collection.Count);
                    }
                    else
                    {
                        context.EvaluationStack.Push(item.GetByteArray().Length);
                    }
                }
                break;

                case OpCode.PACK:
                {
                    int size = (int)context.EvaluationStack.Pop().GetBigInteger();
                    if (size < 0 || size > context.EvaluationStack.Count)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    List <StackItem> items = new List <StackItem>(size);
                    for (int i = 0; i < size; i++)
                    {
                        items.Add(context.EvaluationStack.Pop());
                    }
                    context.EvaluationStack.Push(items);
                }
                break;

                case OpCode.UNPACK:
                {
                    StackItem item = context.EvaluationStack.Pop();
                    if (item is VMArray array)
                    {
                        for (int i = array.Count - 1; i >= 0; i--)
                        {
                            context.EvaluationStack.Push(array[i]);
                        }
                        context.EvaluationStack.Push(array.Count);
                    }
                    else
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                }
                break;

                case OpCode.PICKITEM:
                {
                    StackItem key = context.EvaluationStack.Pop();
                    if (key is ICollection)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    switch (context.EvaluationStack.Pop())
                    {
                    case VMArray array:
                        int index = (int)key.GetBigInteger();
                        if (index < 0 || index >= array.Count)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                        context.EvaluationStack.Push(array[index]);
                        break;

                    case Map map:
                        if (map.TryGetValue(key, out StackItem value))
                        {
                            context.EvaluationStack.Push(value);
                        }
                        else
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                        break;

                    default:
                        State |= VMState.FAULT;
                        return;
                    }
                }
                break;

                case OpCode.SETITEM:
                {
                    StackItem value = context.EvaluationStack.Pop();
                    if (value is Struct s)
                    {
                        value = s.Clone();
                    }
                    StackItem key = context.EvaluationStack.Pop();
                    if (key is ICollection)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    switch (context.EvaluationStack.Pop())
                    {
                    case VMArray array:
                        int index = (int)key.GetBigInteger();
                        if (index < 0 || index >= array.Count)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                        array[index] = value;
                        break;

                    case Map map:
                        map[key] = value;
                        break;

                    default:
                        State |= VMState.FAULT;
                        return;
                    }
                }
                break;

                case OpCode.NEWARRAY:
                {
                    int count = (int)context.EvaluationStack.Pop().GetBigInteger();
                    List <StackItem> items = new List <StackItem>(count);
                    for (var i = 0; i < count; i++)
                    {
                        items.Add(false);
                    }
                    context.EvaluationStack.Push(new VMArray(items));
                }
                break;

                case OpCode.NEWSTRUCT:
                {
                    int count = (int)context.EvaluationStack.Pop().GetBigInteger();
                    List <StackItem> items = new List <StackItem>(count);
                    for (var i = 0; i < count; i++)
                    {
                        items.Add(false);
                    }
                    context.EvaluationStack.Push(new Base.Types.Struct(items));
                }
                break;

                case OpCode.NEWMAP:
                    context.EvaluationStack.Push(new Map());
                    break;

                case OpCode.APPEND:
                {
                    StackItem newItem = context.EvaluationStack.Pop();
                    if (newItem is Base.Types.Struct s)
                    {
                        newItem = s.Clone();
                    }
                    StackItem arrItem = context.EvaluationStack.Pop();
                    if (arrItem is VMArray array)
                    {
                        array.Add(newItem);
                    }
                    else
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                }
                break;

                case OpCode.REVERSE:
                {
                    StackItem arrItem = context.EvaluationStack.Pop();
                    if (arrItem is VMArray array)
                    {
                        array.Reverse();
                    }
                    else
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                }
                break;

                case OpCode.REMOVE:
                {
                    StackItem key = context.EvaluationStack.Pop();
                    if (key is ICollection)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    switch (context.EvaluationStack.Pop())
                    {
                    case VMArray array:
                        int index = (int)key.GetBigInteger();
                        if (index < 0 || index >= array.Count)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                        array.RemoveAt(index);
                        break;

                    case Map map:
                        map.Remove(key);
                        break;

                    default:
                        State |= VMState.FAULT;
                        return;
                    }
                }
                break;

                case OpCode.HASKEY:
                {
                    StackItem key = context.EvaluationStack.Pop();
                    if (key is ICollection)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    switch (context.EvaluationStack.Pop())
                    {
                    case VMArray array:
                        int index = (int)key.GetBigInteger();
                        if (index < 0)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                        context.EvaluationStack.Push(index < array.Count);
                        break;

                    case Map map:
                        context.EvaluationStack.Push(map.ContainsKey(key));
                        break;

                    default:
                        State |= VMState.FAULT;
                        return;
                    }
                }
                break;

                case OpCode.KEYS:
                    switch (context.EvaluationStack.Pop())
                    {
                    case Map map:
                        context.EvaluationStack.Push(new VMArray(map.Keys));
                        break;

                    default:
                        State |= VMState.FAULT;
                        return;
                    }
                    break;

                case OpCode.VALUES:
                {
                    ICollection <StackItem> values;
                    switch (context.EvaluationStack.Pop())
                    {
                    case VMArray array:
                        values = array;
                        break;

                    case Map map:
                        values = map.Values;
                        break;

                    default:
                        State |= VMState.FAULT;
                        return;
                    }
                    List <StackItem> newArray = new List <StackItem>(values.Count);
                    foreach (StackItem item in values)
                    {
                        if (item is Struct s)
                        {
                            newArray.Add(s.Clone());
                        }
                        else
                        {
                            newArray.Add(item);
                        }
                    }
                    context.EvaluationStack.Push(new VMArray(newArray));
                }
                break;

                // Stack isolation
                case OpCode.CALL_I:
                {
                    int rvcount = context.OpReader.ReadByte();
                    int pcount  = context.OpReader.ReadByte();
                    if (context.EvaluationStack.Count < pcount)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    ExecutionContext contextCall = LoadScript(context.Script, rvcount);
                    context.EvaluationStack.CopyTo(contextCall.EvaluationStack, pcount);
                    contextCall.InstructionPointer = context.InstructionPointer;
                    for (int i = 0; i < pcount; i++)
                    {
                        context.EvaluationStack.Pop();
                    }
                    context.InstructionPointer += 2;
                    ExecuteOp(OpCode.JMP, contextCall);
                }
                break;

                case OpCode.CALL_E:
                case OpCode.CALL_ED:
                case OpCode.CALL_ET:
                case OpCode.CALL_EDT:
                {
                    if (table == null)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    int rvcount = context.OpReader.ReadByte();
                    int pcount  = context.OpReader.ReadByte();
                    if (context.EvaluationStack.Count < pcount)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    if (opcode == OpCode.CALL_ET || opcode == OpCode.CALL_EDT)
                    {
                        if (context.RVCount != rvcount)
                        {
                            State |= VMState.FAULT;
                            return;
                        }
                    }
                    byte[] scriptHash;
                    if (opcode == OpCode.CALL_ED || opcode == OpCode.CALL_EDT)
                    {
                        scriptHash = context.EvaluationStack.Pop().GetByteArray();
                    }
                    else
                    {
                        scriptHash = context.OpReader.ReadBytes(20);
                    }
                    byte[] script = table.GetScript(scriptHash);
                    if (script == null)
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    ExecutionContext contextNew = LoadScript(script, rvcount);
                    context.EvaluationStack.CopyTo(contextNew.EvaluationStack, pcount);
                    if (opcode == OpCode.CALL_ET || opcode == OpCode.CALL_EDT)
                    {
                        InvocationStack.Remove(1).Dispose();
                    }
                    else
                    {
                        for (int i = 0; i < pcount; i++)
                        {
                            context.EvaluationStack.Pop();
                        }
                    }
                }
                break;

                // Exceptions
                case OpCode.THROW:
                    State |= VMState.FAULT;
                    return;

                case OpCode.THROWIFNOT:
                    if (!context.EvaluationStack.Pop().GetBoolean())
                    {
                        State |= VMState.FAULT;
                        return;
                    }
                    break;

                default:
                    State |= VMState.FAULT;
                    return;
                }
            }
            if (!State.HasFlag(VMState.FAULT) && InvocationStack.Count > 0)
            {
                if (breakPoints.TryGetValue(CurrentContext.ScriptHash, out HashSet <uint> hashset) && hashset.Contains((uint)CurrentContext.InstructionPointer))
                {
                    State |= VMState.BREAK;
                }
            }
        }
コード例 #17
0
        public static string StackItemAsString(StackItem item, bool addQuotes = false, Emulator.Type hintType = Emulator.Type.Unknown)
        {
            if (item is ICollection && !(item is Map))
            {
                var bytes = item.GetByteArray();
                if (bytes != null && bytes.Length == 20)
                {
                    var signatureHash = new UInt160(bytes);
                    return(CryptoUtils.ToAddress(signatureHash));
                }

                var s     = new StringBuilder();
                var items = (ICollection)item;

                s.Append('[');
                int i = 0;
                foreach (StackItem element in items)
                {
                    if (i > 0)
                    {
                        s.Append(',');
                    }
                    s.Append(StackItemAsString(element));

                    i++;
                }
                s.Append(']');


                return(s.ToString());
            }
            else if (item is Map)
            {
                Map mapItem = (Map)item;
                var builder = new StringBuilder();
                builder.Append("{\n");
                foreach (var key in mapItem.Keys)
                {
                    builder.Append(StackItemAsString(key));
                    builder.Append(" : ");
                    builder.Append(StackItemAsString(mapItem[key]));
                    builder.Append("\n");
                }
                builder.Append("}");


                return(builder.ToString());
            }

            if (item is Neo.VM.Types.Boolean && hintType == Emulator.Type.Unknown)
            {
                return(item.GetBoolean().ToString());
            }

            if (item is Neo.VM.Types.Integer && hintType == Emulator.Type.Unknown)
            {
                return(item.GetBigInteger().ToString());
            }

            if (item is Neo.VM.Types.InteropInterface)
            {
                return("{InteropInterface}");
            }

            byte[] data = null;

            try {
                data = item.GetByteArray();
            }
            catch
            {
            }

            if ((data == null || data.Length == 0) && hintType == Emulator.Type.Unknown)
            {
                return("Null");
            }

            if (hintType == Emulator.Type.Array)
            {
                var s = new StringBuilder();
                s.Append('[');
                int count = 0;
                if (data.Length > 0)
                {
                    var array = (VM.Types.Array)item;
                    foreach (var entry in array)
                    {
                        if (count > 0)
                        {
                            s.Append(", ");
                        }
                        count++;

                        s.Append(StackItemAsString(entry, addQuotes, Emulator.Type.Unknown));
                    }
                }
                s.Append(']');

                return(s.ToString());
            }

            return(FormattingUtils.OutputData(data, addQuotes, hintType));
        }
コード例 #18
0
        public static string StackItemAsString(StackItem item, bool addQuotes = false, Emulator.Type hintType = Emulator.Type.Unknown)
        {
            if (item is ICollection)
            {
                var bytes = item.GetByteArray();
                if (bytes != null && bytes.Length == 20)
                {
                    var signatureHash = new UInt160(bytes);
                    return(Crypto.Default.ToAddress(signatureHash));
                }

                var s     = new StringBuilder();
                var items = (ICollection)item;

                s.Append('[');
                int i = 0;
                foreach (StackItem element in items)
                {
                    if (i > 0)
                    {
                        s.Append(',');
                    }
                    s.Append(StackItemAsString(element));

                    i++;
                }
                s.Append(']');


                return(s.ToString());
            }

            if (item is Neo.VM.Types.Boolean && hintType == Emulator.Type.Unknown)
            {
                return(item.GetBoolean().ToString());
            }

            if (item is Neo.VM.Types.Integer && hintType == Emulator.Type.Unknown)
            {
                return(item.GetBigInteger().ToString());
            }

            if (item is Neo.VM.Types.InteropInterface)
            {
                return("{InteropInterface}");
            }

            byte[] data = null;

            try {
                data = item.GetByteArray();
            }
            catch
            {
            }

            if ((data == null || data.Length == 0) && hintType == Emulator.Type.Unknown)
            {
                return("Null");
            }

            return(FormattingUtils.OutputData(data, addQuotes, hintType));
        }
コード例 #19
0
        public override bool Verify(IEnumerable <Transaction> mempool)
        {
            try
            {
                string          assetName;
                ExecutionEngine engine = new ExecutionEngine(this, Cryptography.Crypto.Default);
                Dictionary <CultureInfo, string> _names;
                CultureInfo culture = null;

                engine.LoadScript(this.Script, false);
                engine.Execute();

                if (engine.EvaluationStack.Count == 0)
                {
                    return(false);
                }

                StackItem val        = engine.EvaluationStack.Pop();
                AssetType asset_type = (AssetType)(byte)val.GetBigInteger();
                if (!Enum.IsDefined(typeof(AssetType), asset_type) || asset_type == AssetType.CreditFlag || asset_type == AssetType.DutyFlag || asset_type == AssetType.GoverningToken || asset_type == AssetType.UtilityToken)
                {
                    return(false);
                }

                string  name = Encoding.UTF8.GetString(engine.EvaluationStack.Pop().GetByteArray());
                JObject name_obj;
                try
                {
                    name_obj = JObject.Parse(name);
                }
                catch (FormatException)
                {
                    name_obj = name;
                }
                if (name_obj is JString)
                {
                    _names = new Dictionary <CultureInfo, string> {
                        { new CultureInfo("en"), name_obj.AsString() }
                    }
                }
                ;
                else
                {
                    _names = ((JArray)JObject.Parse(name)).ToDictionary(p => new CultureInfo(p["lang"].AsString()), p => p["name"].AsString());
                }

                if (culture == null)
                {
                    culture = CultureInfo.CurrentCulture;
                }
                if (_names.TryGetValue(culture, out assetName))
                {
                }
                else if (_names.TryGetValue(new CultureInfo("en"), out assetName))
                {
                }
                else
                {
                    assetName = _names.Values.First();
                }
                if (isDuplicatedToken(assetName))
                {
                    return(false);
                }
            }
            catch (Exception ex)
            {
            }

            if (Gas.GetData() % 100000000 != 0)
            {
                return(false);
            }
            return(base.Verify(mempool));
        }
コード例 #20
0
        public void CastTest()
        {
            // Signed integer

            StackItem item = int.MaxValue;

            Assert.IsInstanceOfType(item, typeof(Integer));
            Assert.AreEqual(new BigInteger(int.MaxValue), item.GetBigInteger());

            // Unsigned integer

            item = uint.MaxValue;

            Assert.IsInstanceOfType(item, typeof(Integer));
            Assert.AreEqual(new BigInteger(uint.MaxValue), item.GetBigInteger());

            // Signed long

            item = long.MaxValue;

            Assert.IsInstanceOfType(item, typeof(Integer));
            Assert.AreEqual(new BigInteger(long.MaxValue), item.GetBigInteger());

            // Unsigned long

            item = ulong.MaxValue;

            Assert.IsInstanceOfType(item, typeof(Integer));
            Assert.AreEqual(new BigInteger(ulong.MaxValue), item.GetBigInteger());

            // BigInteger

            item = BigInteger.MinusOne;

            Assert.IsInstanceOfType(item, typeof(Integer));
            Assert.AreEqual(new BigInteger(-1), item.GetBigInteger());

            // Boolean

            item = true;

            Assert.IsInstanceOfType(item, typeof(Boolean));
            Assert.IsTrue(item.GetBoolean());

            // ByteArray

            item = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };

            Assert.IsInstanceOfType(item, typeof(ByteArray));
            CollectionAssert.AreEqual(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }, item.GetByteArray());

            // String

            item = "NEO - 种智能经济分布式网络";

            Assert.IsInstanceOfType(item, typeof(ByteArray));
            CollectionAssert.AreEqual(Encoding.UTF8.GetBytes("NEO - 种智能经济分布式网络"), item.GetByteArray());
            Assert.AreEqual("NEO - 种智能经济分布式网络", item.GetString());

            // Array

            item = new StackItem[] { true, false };

            Assert.IsInstanceOfType(item, typeof(Array));
            Assert.IsTrue(((Array)item)[0].GetBoolean());
            Assert.IsFalse(((Array)item)[1].GetBoolean());

            // List

            item = new List <StackItem>(new StackItem[] { true, false });

            Assert.IsInstanceOfType(item, typeof(Array));
            Assert.IsTrue(((Array)item)[0].GetBoolean());
            Assert.IsFalse(((Array)item)[1].GetBoolean());

            // Interop

            var interop = new InteropInterface <Dictionary <int, int> >(new Dictionary <int, int>()
            {
                { 1, 1 }
            });

            Dictionary <int, int> value = interop;

            Assert.AreEqual(1, value.Count);
        }
コード例 #21
0
        /// <summary>
        /// Get Printable version
        /// </summary>
        /// <param name="value">Value</param>
        object GetPrintable(StackItem value)
        {
            if (value == null)
            {
                return("NULL");
            }
            else
            {
                Type tp = value.GetType();

                switch (tp.FullName)
                {
                case "Neo.VM.Types.Boolean": return(value.GetBoolean());

                case "Neo.VM.Types.ByteArray":
                {
                    byte[] v = value.GetByteArray();
                    if (v == null || v.Length == 0)
                    {
                        return("[0]");
                    }

                    if (v.Length > 200)
                    {
                        return("[" + v.Length.ToString() + "] ...");
                    }

                    return("[" + v.Length.ToString() + "] 0x" + v.ToHexString());
                }

                case "Neo.VM.Types.Integer":
                {
                    BigInteger v = value.GetBigInteger();

                    if (v.Sign >= 0 && v > ulong.MaxValue)
                    {
                        return("[BigInteger] ...");
                    }
                    else if (v.Sign < 0 && v < long.MinValue)
                    {
                        return("[-BigInteger] ...");
                    }

                    return(v.ToString());
                }

                case "Neo.VM.Types.Struct":
                case "Neo.VM.Types.Array":
                {
                    Neo.VM.Types.Array ar = value as Neo.VM.Types.Array;
                    StackItem[]        si = ar.ToArray();

                    if (si.Length > 200)
                    {
                        return("[" + si.Length.ToString() + "] ...");
                    }
                    return
                        ("[" + si.Length + "]" +
                         JsonHelper.Serialize(si.Select(u => GetPrintable(u)).ToArray(), true, false));
                }

                case "Neo.VM.Types.InteropInterface":
                {
                    if (_Interop == null)
                    {
                        _Interop = tp.GetField("_object", BindingFlags.Instance | BindingFlags.NonPublic);

                        foreach (Type txp in typeof(ApplicationEngine).Assembly.GetTypes())
                        {
                            // Extract internal type
                            if (txp.FullName == "Neo.SmartContract.StorageContext")
                            {
                                _StorageContext        = txp;
                                _StorageContextToArray = txp.GetMethod("ToArray");
                                break;
                            }
                        }
                    }

                    object ob = _Interop.GetValue(value);

                    if (ob != null && ob.GetType() == _StorageContext)
                    {
                        ob = _StorageContextToArray.Invoke(ob, new object[] { });
                    }
                    else
                    {
                    }
                    //if (ob !=null && ob is UInt160 a)

                    return(JsonHelper.Serialize(ob, true, false));
                }

                default:
                {
                    break;
                }
                }
            }

            return("");
        }
コード例 #22
0
        private static ContractParameter ToParameter(StackItem item, List <Tuple <StackItem, ContractParameter> > context)
        {
            ContractParameter parameter = null;

            switch (item)
            {
            case VMArray array:
                if (context is null)
                {
                    context = new List <Tuple <StackItem, ContractParameter> >();
                }
                else
                {
                    parameter = context.FirstOrDefault(p => ReferenceEquals(p.Item1, item))?.Item2;
                }
                if (parameter is null)
                {
                    parameter = new ContractParameter {
                        Type = ContractParameterType.Array
                    };
                    context.Add(new Tuple <StackItem, ContractParameter>(item, parameter));
                    parameter.Value = array.Select(p => ToParameter(p, context)).ToList();
                }
                break;

            case Map map:
                if (context is null)
                {
                    context = new List <Tuple <StackItem, ContractParameter> >();
                }
                else
                {
                    parameter = context.FirstOrDefault(p => ReferenceEquals(p.Item1, item))?.Item2;
                }
                if (parameter is null)
                {
                    parameter = new ContractParameter {
                        Type = ContractParameterType.Map
                    };
                    context.Add(new Tuple <StackItem, ContractParameter>(item, parameter));
                    parameter.Value = map.Select(p => new KeyValuePair <ContractParameter, ContractParameter>(ToParameter(p.Key, context), ToParameter(p.Value, context))).ToList();
                }
                break;

            case VMBoolean _:
                parameter = new ContractParameter
                {
                    Type  = ContractParameterType.Boolean,
                    Value = item.GetBoolean()
                };
                break;

            case ByteArray _:
                parameter = new ContractParameter
                {
                    Type  = ContractParameterType.ByteArray,
                    Value = item.GetByteArray()
                };
                break;

            case Integer _:
                parameter = new ContractParameter
                {
                    Type  = ContractParameterType.Integer,
                    Value = item.GetBigInteger()
                };
                break;

            case InteropContract _:
                parameter = new ContractParameter
                {
                    Type = ContractParameterType.InteropInterface
                };
                break;

            default:
                throw new ArgumentException();
            }
            return(parameter);
        }