JSON-RPC API解析之trace_transaction

trace_transaction 是以太坊 JSON-RPC API 中的一个方法,用于追踪和调试单个交易的执行过程。该方法允许查询交易的详细执行步骤,包括智能合约的调用、内部交易、虚拟机操作和状态更改等信息。

方法名称: trace_transaction
参数: transactionHash(字符串):要追踪的交易的哈希值。
返回值: 包含了交易执行过程详细信息的 JSON 数据。

使用场景和解释:

  1. 调试智能合约: 开发人员可以使用 trace_transaction 来调试智能合约的执行过程。通过查看交易的执行步骤,包括合约内部函数的调用和返回值,可以帮助开发人员发现问题并进行修复。
  2. 分析交易执行: 研究区块链上的特定交易执行情况时,可以使用该方法来了解交易如何影响了区块链状态。这对于监控和分析合约交互非常有用。
  3. 内部交易跟踪: trace_transaction 还会显示与交易相关的内部交易。这些内部交易通常是由智能合约调用其他智能合约而触发的。你可以查看这些内部交易的执行过程,包括调用的函数、参数和状态更改。
  4. 虚拟机操作分析: 方法还提供了有关在交易执行期间发生的 EVM(以太坊虚拟机)操作的信息。这可以帮助你深入了解交易的执行细节。
  5. 状态更改查询: 你可以查看交易执行后区块链状态的更改情况,包括账户余额、合约状态和其他状态变量的更改。
    注意:使用 trace_transaction 需要连接到一个运行以太坊节点的 JSON-RPC API,并向节点发送包含交易哈希的请求。节点将返回包含了交易执行详细信息的 JSON 响应,你可以解析该响应以查看交易的执行过程和结果。
    API参考:alchemy trace api(这里面也有返回参数的解析等)

返回参数说明:

注意:一般来说,除非另有说明,所有返回类型都是其数据类型的十六进制表示形式

参数名称 参数说明
action action 参数是一个包含有关交易执行操作的详细信息的字段。它提供了有关交易调用或合约创建的各种属性
callType 调用类型(包含):call,delegatecall,callcode 和staticcall四种
from 调用者地址,即交易发起者的地址
gas from为此操作分配的gas
input 交易的输入数据,通常包括函数调用和参数。
to 被调用的合约地址。如果这是一个合约创建交易,该字段会包含新合约的地址。
value 随此交易发送的value值
blockHash 该交易所在区块的哈希值
blockNumber 该交易所在的区块号
gasUsed 此交易总共消耗的gas
output 合约调用返回的值,仅包含return方法发送的实际值。如果没有执行return方法,则输出为空字节
subtraces 表示在此操作下的子操作数量
traceAddress 操作在执行过程中的位置,若它是一个空数组,表示顶级操作
transactionHash 交易哈希
transactionPosition 该交易在区块中的位置
type 交易类型:call 或 create 等方法的值。若为creat,说明该交易为合约创建交易

调用类型说明:

call(普通调用):
  • call 主要用于在一个合约中调用另一个合约函数
  • 当使用 call 时,被调用合约的代码将在被调用合约的上下文中执行。
  • 这意味着合约调用者的地址、余额、存储等信息都会传递给被调用合约,它们会影响被调用合约的执行。
  • 被调用合约的状态(如存储变量)可以被修改,这可以用来进行状态更改操作,例如转账。
delegatecall(代理调用):
  • delegatecall 用于在一个合约中执行另一个合约的代码,但在执行过程中不改变合约的上下文。
  • 调用者的地址和余额等信息会传递给目标合约,但被调用合约的地址不会改变。
  • 被调用合约的状态(存储)不会被修改,只有调用者的状态会受到影响。
  • 这种调用类型通常用于合约库或者升级合约,以确保调用者的上下文不受影响。
callcode
  • callcode 类似于 delegatecall,用于在一个合约中执行另一个合约的代码。
  • 不同之处在于,callcode 不传递调用者的地址,而是使用调用者的地址替代被调用合约的地址。
  • 这意味着在执行过程中,目标合约会认为自己就是调用者,因此会使用调用者的存储和地址等信息。
  • 被调用合约的状态不会被修改,只有调用者的状态会受到影响
staticcall
  • staticcall 用于在只读的上下文中执行目标合约的代码,不能进行状态修改。
  • 调用者的上下文不会传递给被调用合约,因此被调用合约不能修改任何状态,包括存储和余额。
  • 这种调用类型通常用于查询数据或执行只读操作。

不太理解的话,不必太过关注。记住call是普通调用,delegatecall是代理调用即可。代理调用即使用代理合约执行逻辑,不会改变调用合约的状态。一般出现在需要在一个合约中执行逻辑但不改变状态情况下。

traceAddress说明:

traceAddress 是以太坊中 trace_transaction 方法返回结果中的一个字段,它用于表示在交易执行期间操作的路径或位置。这个字段是一个整数数组,每个整数代表操作在操作中的索引位置。
在这里插入图片描述

示例返回结果解析:

交易哈希:0x2d25001f57fe2c695771bb3a52a3904a153d0265ec7691bb7fe01e1c748a36a2

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": [
    {
      "action": {
        "callType": "call",
        "from": "0x9727ca412f87d46cd4bb6022d27477b232ea8970", 
        "gas": "0x5cca9",
        "input": "0x551c4fd22236a27ae014f93f4cce8779b1bf80082ae41d81d51e17001c3fc9feb30bfd742aa24d5e2bb834e91a33f9ad9c179f5cf98d260d3b7ecd5f97723991144827ed20c9c107d5282511e35f3ff26a40bcd981ab016ea8431bfce279afd04f8267651f46421570ce6991ee874f0a45c2a9ddda9348dcd47ca675e867392de67a503413532367807f230b723fd8317d4f611d7329409188d4fe1e5f933b075acf359228dfed4d559978e5872bfdd2fca6bc7228c21a121958990a419ae75023f55e59207b650044081c9e813112495d847e9183941f506a75f9e7ba6f8932fcc9a76008210ab3a0ee173a8347076ade67ccc8d14c09cd5ecff0ede029dce7d36ccd802c15682c1ecd030ab5155f2cac9c8a8dc83d40c9f0c6c8d27571ae9663229a532a3b165ff29ab80f9bc60b271775b26577f9b729285a349c737ae3e2cad0002200000000000000000000000081708914e4f78f391c1369d0c7cebf2f5ba40ae10000000000000000000000000000000000000000000000000000000000000000",
        "to": "0xb541fc07bc7619fd4062a54d96268525cbc6ffef",
        "value": "0x0"
      },
      "blockHash": "0x1c543c003ed0a4ff4ab3f2cadeb9d1867bde84e79cebd630e1c9762d1394a1d1",
      "blockNumber": 9116488,
      "result": {
        "gasUsed": "0x432eb",
        "output": "0x"
      },
      "subtraces": 1,
      "traceAddress": [],
      "transactionHash": "0x2d25001f57fe2c695771bb3a52a3904a153d0265ec7691bb7fe01e1c748a36a2",
      "transactionPosition": 168,
      "type": "call"
    },
    {
      "action": {
        "callType": "delegatecall",
        "from": "0xb541fc07bc7619fd4062a54d96268525cbc6ffef",
        "gas": "0x5aae0",
        "input": "0x551c4fd22236a27ae014f93f4cce8779b1bf80082ae41d81d51e17001c3fc9feb30bfd742aa24d5e2bb834e91a33f9ad9c179f5cf98d260d3b7ecd5f97723991144827ed20c9c107d5282511e35f3ff26a40bcd981ab016ea8431bfce279afd04f8267651f46421570ce6991ee874f0a45c2a9ddda9348dcd47ca675e867392de67a503413532367807f230b723fd8317d4f611d7329409188d4fe1e5f933b075acf359228dfed4d559978e5872bfdd2fca6bc7228c21a121958990a419ae75023f55e59207b650044081c9e813112495d847e9183941f506a75f9e7ba6f8932fcc9a76008210ab3a0ee173a8347076ade67ccc8d14c09cd5ecff0ede029dce7d36ccd802c15682c1ecd030ab5155f2cac9c8a8dc83d40c9f0c6c8d27571ae9663229a532a3b165ff29ab80f9bc60b271775b26577f9b729285a349c737ae3e2cad0002200000000000000000000000081708914e4f78f391c1369d0c7cebf2f5ba40ae10000000000000000000000000000000000000000000000000000000000000000",
        "to": "0x89450e30b806ab95341fade5a9010af146b3232b",
        "value": "0x0"
      },
      "blockHash": "0x1c543c003ed0a4ff4ab3f2cadeb9d1867bde84e79cebd630e1c9762d1394a1d1",
      "blockNumber": 9116488,
      "result": {
        "gasUsed": "0x42803",
        "output": "0x"
      },
      "subtraces": 2,
      "traceAddress": [
        0
      ],
      "transactionHash": "0x2d25001f57fe2c695771bb3a52a3904a153d0265ec7691bb7fe01e1c748a36a2",
      "transactionPosition": 168,
      "type": "call"
    },
    {
      "action": {
        "callType": "call",
        "from": "0xb541fc07bc7619fd4062a54d96268525cbc6ffef",
        "gas": "0x5709b",
        "input": "0x5fe8c13b2236a27ae014f93f4cce8779b1bf80082ae41d81d51e17001c3fc9feb30bfd742aa24d5e2bb834e91a33f9ad9c179f5cf98d260d3b7ecd5f97723991144827ed20c9c107d5282511e35f3ff26a40bcd981ab016ea8431bfce279afd04f8267651f46421570ce6991ee874f0a45c2a9ddda9348dcd47ca675e867392de67a503413532367807f230b723fd8317d4f611d7329409188d4fe1e5f933b075acf359228dfed4d559978e5872bfdd2fca6bc7228c21a121958990a419ae75023f55e59207b650044081c9e813112495d847e9183941f506a75f9e7ba6f8932fcc9a76008210ab3a0ee173a8347076ade67ccc8d14c09cd5ecff0ede029dce7d36ccd802c15682c1ecd030ab5155f2cac9c8a8dc83d40c9f0c6c8d27571ae9663229a532a3b165ff29ab80f9bc60b271775b26577f9b729285a349c737ae3e2cad0002200000000000000000000000081708914e4f78f391c1369d0c7cebf2f5ba40ae10000000000000000000000000000000000000000000000000000000000000000",
        "to": "0x41c57b58b5bbabdccd639e691f6d47c9a150ec2b",
        "value": "0x0"
      },
      "blockHash": "0x1c543c003ed0a4ff4ab3f2cadeb9d1867bde84e79cebd630e1c9762d1394a1d1",
      "blockNumber": 9116488,
      "result": {
        "gasUsed": "0x38ae1",
        "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
      },
      "subtraces": 0,
      "traceAddress": [
        0,
        0
      ],
      "transactionHash": "0x2d25001f57fe2c695771bb3a52a3904a153d0265ec7691bb7fe01e1c748a36a2",
      "transactionPosition": 168,
      "type": "call"
    },
    {
      "action": {
        "callType": "call",
        "from": "0xb541fc07bc7619fd4062a54d96268525cbc6ffef",
        "gas": "0x8fc",
        "input": "0x",
        "to": "0x81708914e4f78f391c1369d0c7cebf2f5ba40ae1",
        "value": "0x16345785d8a0000"
      },
      "blockHash": "0x1c543c003ed0a4ff4ab3f2cadeb9d1867bde84e79cebd630e1c9762d1394a1d1",
      "blockNumber": 9116488,
      "result": {
        "gasUsed": "0x0",
        "output": "0x"
      },
      "subtraces": 0,
      "traceAddress": [
        0,
        1
      ],
      "transactionHash": "0x2d25001f57fe2c695771bb3a52a3904a153d0265ec7691bb7fe01e1c748a36a2",
      "transactionPosition": 168,
      "type": "call"
    }
  ]
}

这段 JSON 数据是 trace_transaction 方法的响应结果,它提供了有关一个特定交易执行过程的详细信息。
提取本例,本例中一共有四个操作(分别对应四个对象):

  1. 0x9727ca412f87d46cd4bb6022d27477b232ea8970 ->0xb541fc07bc7619fd4062a54d96268525cbc6ffef
  2. 0xb541fc07bc7619fd4062a54d96268525cbc6ffef-> 0x89450e30b806ab95341fade5a9010af146b3232b
  3. 0xb541fc07bc7619fd4062a54d96268525cbc6ffef-> 0x41c57b58b5bbabdccd639e691f6d47c9a150ec2b
  4. 0xb541fc07bc7619fd4062a54d96268525cbc6ffef->0x81708914e4f78f391c1369d0c7cebf2f5ba40ae1
    分别编号为1,2,3,4.分析数据得出:
    对象1 的traceAddress 为[],表示顶级操作,即 该交易的第一个操作。
    对象2的traceAddress 为[0],表示这是第一个操作的子操作,在这里可以理解为第二个操作。
    对象3的traceAddress 为[0,0],表示这是第二个操作的第一个子操作。
    对象4的traceAddress 为[0,1],表示这是第二个操作的第二个子操作。

本例操作树,如下所示:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44543317/article/details/133274950
今日推荐