【问题标题】:Extracting emitted events (logs) from geth transaction trace (debug_traceCall)从 geth 事务跟踪 (debug_traceCall) 中提取发出的事件(日志)
【发布时间】:2022-04-30 15:39:33
【问题描述】:

使用debug_traceCall 时,我会在执行期间获得所有操作码和状态更改的低级 EVM 跟踪。这个太详细了。当我使用默认的callTracer 时,我可以获得更好的调用树。但是,我似乎无法从跟踪中提取发出的事件。我可以在跟踪中看到它们(LOG* 操作码)但是没有简单的方法可以将它们实际解析为“可读”的东西(以及值和原始地址)必须有一种方法来获取日志 - 有什么想法吗?

例如。这就是 Etherscan 显示的 https://etherscan.io/tx-decoder?tx=0x3e3ad35fda1fddd9e154b3860b50371a1acd2fdb4f27f897e234846522bde732(请参阅 Emitted Events 部分)

【问题讨论】:

    标签: ethereum go-ethereum geth evm


    【解决方案1】:

    所以我自己想到了这一点 - 我为 geth 创建了一个自定义 JavaScript 跟踪器,该跟踪器在第三个参数中传递给 geth 到 debug_traceCall (请参阅链接提供的 API 参考):

    {
        data: [],
        fault: function (log) {
        },
        step: function (log) {
            var topicCount = (log.op.toString().match(/LOG(d)/) || [])[1];
            if (topicCount) {
                var res = {
                    address: log.contract.getAddress(),
                    data: log.memory.slice(parseInt(log.stack.peek(0)), parseInt(log.stack.peek(0)) + parseInt(log.stack.peek(1))),
                };
                for (var i = 0; i < topicCount; i++)
                    res['topic' + i.toString()] = log.stack.peek(i + 2);
                this.data.push(res);
            }
        },
        result: function () {
            return this.data;
        }
    }
    

    该跟踪器由 geth 为跟踪中的每个操作执行。基本上它的作用:

    • 检查这是否是LOG0LOG1LOG2LOG3LOG4 EVM 操作码之一
    • 从当前合约中提取合约地址
    • 提取默认topic0 和后续主题(如果有)
    • 从内存中提取额外的事件数据(注意:stack[0]是偏移量,stack[1]是数据大小)

    将跟踪器传递给 geth 如下所示:

    res = await ethersProvider.send('debug_traceCall', [{
        from: tx.from,
        to: tx.to,
        gas: BigNumber.from(tx.gas)._hex.replace('0x0', '0x'),
        gasPrice: BigNumber.from(tx.gasPrice)._hex.replace('0x0', '0x'),
        value: BigNumber.from(tx.value)._hex.replace('0x0', '0x'),
        data: tx.input
    }, "latest", {
        tracer: "{
    " +
            "    data: [],
    " +
            "    fault: function (log) {
    " +
            "    },
    " +
            "    step: function (log) {
    " +
            "        var topicCount = (log.op.toString().match(/LOG(\d)/) || [])[1];
    " +
            "        if (topicCount) {
    " +
            "            var res = {
    " +
            "                address: log.contract.getAddress(),
    " +
            "                data: log.memory.slice(parseInt(log.stack.peek(0)), parseInt(log.stack.peek(0)) + parseInt(log.stack.peek(1))),
    " +
            "            };
    " +
            "            for (var i = 0; i < topicCount; i++)
    " +
            "                res['topic' + i.toString()] = log.stack.peek(i + 2);
    " +
            "            this.data.push(res);
    " +
            "        }
    " +
            "    },
    " +
            "    result: function () {
    " +
            "        return this.data;
    " +
            "    }
    " +
            "}",
        enableMemory: true,
        enableReturnData: true,
        disableStorage: true
    }])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-17
      • 2019-05-02
      相关资源
      最近更新 更多