示例#1
0
        public TransactionModel(Transaction tx)
        {
            TxId       = tx.Hash;
            NetworkFee = new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals);
            Nonce      = tx.Nonce;
            Script     = tx.Script;

            Sender          = tx.Sender;
            SystemFee       = new BigDecimal((BigInteger)tx.SystemFee, NativeContract.GAS.Decimals);
            ValidUntilBlock = tx.ValidUntilBlock;
            Version         = tx.Version;
            Size            = tx.Size;
            Attributes      = tx.Attributes?.Select(a => new TranAttributeModel()
            {
                Usage = a.Type,
                Data  = a.ToJson().ToString(),
            }).ToList();
            Witnesses = tx.Witnesses?.Select(w => new WitnessModel(w)
                                             ).ToList();

            if (tx.Script != null)
            {
                ScriptCode = OpCodeConverter.Parse(tx.Script);
            }
        }
示例#2
0
        /// <summary>
        /// get invoke methods from transaction script
        /// </summary>
        /// <param name="tx"></param>
        /// <returns></returns>
        private List <(UInt160 contract, HashSet <string> methods)> GetInvokeMethods(Transaction tx)
        {
            var methodBox = new Dictionary <UInt160, HashSet <string> >();

            var instructions = OpCodeConverter.Parse(tx.Script);

            for (int i = 2; i < instructions.Count; i++)
            {
                var currentInstruction = instructions[i];
                if (currentInstruction.OpCode == OpCode.SYSCALL && currentInstruction.SystemCallMethod == "System.Contract.Call")
                {
                    var contractInstruction = instructions[i - 1];
                    var contract            = contractInstruction.OpData.ToUInt160();
                    if (contract == null)
                    {
                        continue;
                    }

                    var methodInstruction = instructions[i - 2];
                    var method            = methodInstruction.OpDataUtf8String;
                    if (method.NotNull())
                    {
                        var box = methodBox.ContainsKey(contract) ? methodBox[contract] : new HashSet <string>();
                        box.Add(method);
                        methodBox[contract] = box;
                    }
                }
            }
            return(methodBox.Select(m => (m.Key, m.Value)).ToList());
        }
示例#3
0
 public WitnessModel(Witness witness)
 {
     if (witness != null)
     {
         InvocationScript   = witness.InvocationScript;
         VerificationScript = witness.VerificationScript;
         ScriptHash         = witness.ScriptHash;
         InvocationOpCode   = OpCodeConverter.Parse(witness.InvocationScript);
         VerificationOpCode = OpCodeConverter.Parse(witness.VerificationScript);
     }
 }
示例#4
0
        public void Test()
        {
            var script =
                "0d4501e70f75f78a0bc128ea55c53bffec7f0d2fa4da5793e5c810d3faf78bcf0f517a73d98e5911db9d13bfeaa69a4ab84a356241aa11e23b970be6cf2fe06aeb1cc60108d7699fe00e9ae224bfeca82e49af360d30ff80edf972ad2d323461e82778af33453db04a34275cfbbe2af1eb692eece921b16a4b18a16a1d8ce850baab32ef01e041b3b53218b755a58cc84a938de52e648f00e010ee1ea87f0a0eb12af9d7427fc477dbf566e0fca084017ec2bae5e1a1bbb9539c59170cf687e45a8ddeba0e01feb56c064339cc468d3ade9179754887579f04b612c4c2cc5c1d8f6c0781246071f68900248c6b56724135428600988f0b850d5464d59206f820a9590445663a01449d1a8b4e08ed8e06ee250d57a701f390aed87dcb75456d112661035733b1944fc5f66f5c417041ab7180134f2ef1729f714bd02de35d3bef10f554843dad2d000c000c000dc60100000000ffffffffffffff7fdef0100970c3cb67e2c8066a6a97d3c1669d03fc91045bbe1b84eec97b0ad08932824d90bd7c27c90a413483c3635b59f3d3a040e1ab74485c99614e835e2bd02bda7e1ab674e41ac8254b11fb06361b70d57591551da475c7ffc7e3f3ce6dde3fd1ad4bca7e978ada9f9154365f63c855f468a19c8ad3e59d4778c531d4b0c6113bf9607778b900067b3c67a0fb82dbfd13017b226c6561646572223a352c227672665f76616c7565223a22424c6769682f62574378672b54617a5a326253496a556354586e2f2f754679575a6e5876377953774467744a474e377a4d7974442f7637424341536a634f676b7754656d414c68786e636458566252335a75324e4952673d222c227672665f70726f6f66223a2266465074723936425a735461514269766c43693370715a47696241496832384c534d506f4f6b6a4f4b7376686475447a30324e7861753659313171686874384f514e7751323347787a58513638694239774b334f76673d3d222c226c6173745f636f6e6669675f626c6f636b5f6e756d223a31323135303736372c226e65775f636861696e5f636f6e666967223a6e756c6c7d00000000000000000000000000000000000000000cf0ef20702f6edd397bf6181e391867ba23ec77d2ad717748ab8d914d9ec1e5db74afa605000000000000002064c809ee29044d8cd6ad05dce818c5d8000ed816d0e74c04fb97c5246d29356420fd03f64d5c82a6123d30528507c709e14bda44f4ab3d8ff399c5d5f4d90cd8d2144f5f702b3f459f222d371052940bb9ce2d86d2ed58000000000000001442e54382e86dcdca09e0da8bb67e2fac4d49874406756e6c6f636b4a14cf76e28bd0062c4a478ee35561011319f3cfa4d2140482c3d160c011bf95d2b7ed3b5da7688181ce67009c9f060000000000000000000000000000000000000000000000000000000015c01f0c12766572696679416e644578656375746554780c142a774fa0404f020254f6db20616cf13adc448d6141627d5b52"
                .HexToBytes();


            var instructions = OpCodeConverter.Parse(script);

            foreach (var instructionInfo in instructions)
            {
                Console.WriteLine($"My:{instructionInfo.OpCode},{instructionInfo.OpData?.ToHexString()}");
            }
        }
        protected virtual void ParseIL()
        {
            Module mod = module ?? method.Module;

            byte[] il = method.GetMethodBody().GetILAsByteArray();
            fixed(byte *ptr = il)
            for (int pos = 0, max = il.Length; pos < max; )
            {
                ILBuffer buf = new ILBuffer
                {
                    offset = pos
                };

                OpCode code;
                byte   temp = Read <byte>(ptr, ref pos);

                if (temp == 0xFE)
                {
                    code = OpCodeConverter.GetCode_sz2(Read <byte>(ptr, ref pos));
                }
                else
                {
                    code = OpCodeConverter.GetCode_sz1(temp);
                }

                buf.code = code;

                switch (code.OperandType)
                {
                case OperandType.InlineBrTarget:
                    buf.operand = Read <int>(ptr, ref pos) + pos;
                    break;

                case OperandType.InlineField:
                    buf.operand = mod.ResolveField(Read <int>(ptr, ref pos));
                    break;

                case OperandType.InlineMethod:
                {
                    int token = Read <int>(ptr, ref pos);
                    try
                    {
                        buf.operand = mod.ResolveMethod(token);
                    }
#pragma warning disable CA1031 // Do not catch general exception types
                    catch
                    {
                        buf.operand = mod.ResolveMember(token);
                    }
#pragma warning restore CA1031
                }
                break;

                case OperandType.InlineSig:
                    // 사용하지 않음
                    // buf.operand = mod.ResolveSignature(Read<int>(ptr, ref pos));
                    buf.operand = Read <int>(ptr, ref pos);
                    break;

                case OperandType.InlineTok:
                {
                    int token = Read <int>(ptr, ref pos);
                    try
                    {
                        buf.operand = mod.ResolveType(token);
                    }
#pragma warning disable CA1031 // Do not catch general exception types
                    catch
                    {
                        buf.operand = token;
                    }
#pragma warning restore CA1031
                }
                break;

                case OperandType.InlineType:
                    buf.operand = mod.ResolveType(Read <int>(ptr, ref pos), method.DeclaringType?.GetGenericArguments(), method.GetGenericArguments());
                    break;

                case OperandType.InlineI:
                    buf.operand = Read <int>(ptr, ref pos);
                    break;

                case OperandType.InlineI8:
                    buf.operand = Read <long>(ptr, ref pos);
                    break;

                case OperandType.InlineR:
                    buf.operand = Read <double>(ptr, ref pos);
                    break;

                case OperandType.InlineString:
                    buf.operand = mod.ResolveString(Read <int>(ptr, ref pos));
                    break;

                case OperandType.InlineSwitch:
                {
                    int   count       = Read <int>(ptr, ref pos);
                    int   base_offset = pos + 4 * count;
                    int[] cases       = new int[count];
                    for (int x = 0; x < count; x++)
                    {
                        cases[x] = Read <int>(ptr, ref pos) + base_offset;
                    }
                    buf.operand = cases;
                }
                break;

                case OperandType.InlineVar:
                    buf.operand = Read <short>(ptr, ref pos);
                    break;

                case OperandType.ShortInlineBrTarget:
                    buf.operand = Read <byte>(ptr, ref pos) + pos;
                    break;

                case OperandType.ShortInlineI:
                    buf.operand = Read <byte>(ptr, ref pos);
                    break;

                case OperandType.ShortInlineR:
                    buf.operand = Read <float>(ptr, ref pos);
                    break;

                case OperandType.ShortInlineVar:
                    buf.operand = Read <byte>(ptr, ref pos);
                    break;

                case OperandType.InlineNone:
                    break;

                default:
#if DEBUG
                    System.Diagnostics.Debug.WriteLine("Unknown operand type: " + code.OperandType);
#endif
                    break;
                }

                m_buffers.Add(buf);
            }
        }
示例#6
0
 public async Task <object> ParseScript(byte[] script)
 {
     return(OpCodeConverter.Parse(script));
 }
        protected virtual void FixupILCode(ILBuffer current, OpCode qcode, int argFixOffset, bool hasReturn)
        {
            // ldarg.s -> stloc.s
            // 0xE ~ 0x13
            // + FDFB = long version (remove 's')
            WORD v = qcode.Value;

            if (Range(v, 0xE, 0x13))
            {
                v += 0xFD_FB;
                // fix operand size
                current.operand = (short)(byte)current.operand;
            }

            // (only return buffer, instance)
            if (argFixOffset == 2)
            {
                // ldarg_3
                if (v == 5)
                {
                    v = 0xFE_09; // ldarg
                    current.operand = (short)4;
                }
                // ldarg_1 ldarg_2
                else if (v == 3 || v == 4)
                {
                    v++;
                }
                // ldarg ldarga starg
                else if (Range(v, 0xFE_09, 0xFE_0B))
                {
                    current.operand = (short)((short)current.operand + 1);
                }
            }
            if (hasReturn)
            {
                // ldloc_3
                if (v == 9)
                {
                    v = 0xFE_0C; // ldloc
                    current.operand = (short)4;
                }
                // stloc_3
                else if (v == 0xD)
                {
                    v = 0xFE_0E;
                    current.operand = (short)4;
                }
                // ldloc_0 ldloc_1 ldloc_2 stloc_0 stloc_1 stloc_2
                else if (Range(v, 6, 8) || Range(v, 0xA, 0xD))
                {
                    v++;
                }
                // ldloc ldloca stloc
                else if (Range(v, 0xFE_0C, 0xFE_0E))
                {
                    current.operand = (short)((short)current.operand + 1);
                }
            }

            // br.s -> blt.un.s
            if (Range(v, 0x2B, 0x37))
            {
                v += 0xD;
            }
            else if (v == 0xDE) // leave.s
            {
                v = 0xDD;
            }

            if (v != qcode.Value)
            {
                current.code = OpCodeConverter.GetCode(v.unsigned);
            }
        }