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); } }
/// <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()); }
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); } }
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); } }
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); } }