前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Web3.py 模式:回退原因查找

Web3.py 模式:回退原因查找

作者头像
Tiny熊
发布2022-11-07 10:08:56
5550
发布2022-11-07 10:08:56
举报
文章被收录于专栏:深入浅出区块链技术

本文作者:一个程序猿[1]

在编写智能合约时,鼓励包含人类可读的错误信息。在 Solidity 中,可以在require 或者 revert 语句[2]中声明。如:

代码语言:javascript
复制
function subtract(uint256 a, uint256 b) public pure returns (uint256) {
    require(b <= a, "(a) must be larger than (b)!");
    uint256 c = a - b;
    return c;
}

像 Etherscan 这样的区块链浏览器,会自动收集并显示错误信息,但是如果你需要以编程的方式找出为什么交易失败了,还需要做很多工作。

如果取到一笔以太坊交易,你会发现所有相关信息都包含在交易的发送中,如to, from, value, 和 data。另一方面,交易收据会指出交易失败,但不包含回退原因字符串。

一种获取回退原因的方法是用eth_call方法重现交易。这个RPC[3]方法是用来在本地执行交易 —— 不会被广播到网络上,但是你可以看到结果,就好像交易真的被打包了一样。

为了重现交易,需要这笔交易最初执行时的上下文,如,当时账户中的余额。eth_call允许传入一个你想要重现的交易的区块号。注意,如果交易被打包在区块n中,你会想要用区块n-1的上下文来重现它。伪代码如下:

代码语言:javascript
复制
from web3 import Web3

w3 = Web3(<your-provider>)
w3.eth.call(replay_tx, block_number - 1)

* 注意这里有一个很重要的限制:重现交易的执行是孤立的。这意味着同一个区块中的在原始交易之前的交易不会被计入。如果你觉得之前的交易是导致失败的原因,请跳到本文末尾的“更新”部分。

有一个问题,默认情况下,以太坊客户端不会存储对旧交易进行此类检查的所有历史上下文。存储由“归档”节点执行,这需要更多的存储空间。如果你没有运行自己的归档节点,就需要支持这个功能的供应商。

把所有归结在一起 —— 交易哈希就是准备重现交易所需的所有内容。获取该交易提供了交易的输入和所在的区块。看看下面的完整代码示例,用了一个随机选择的 Uniswap 失败交易:

代码语言:javascript
复制
import os
from web3 import Web3, HTTPProvider

# instantiate your (archive-capable) provider:
w3 = Web3(HTTPProvider(os.environ['MAINNET_URL']))

# fetch a reverted transaction:
tx = w3.eth.get_transaction('0x2e7aa4314eeb171d4...')

# build a new transaction to replay:
replay_tx = {
    'to': tx['to'],
    'from': tx['from'],
    'value': tx['value'],
    'data': tx['input'],
}

# replay the transaction locally:
try:
    w3.eth.call(replay_tx, tx.blockNumber - 1)
except Exception as e:
    print(e)
    # execution reverted: UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT

更新: 这个方案需要同一个区块中较早的交易数据,如果不适用你的用例,你可以考虑用像Tenderly[4]的工具或者用 Erigon 自定义像Otterscan[5]ots_getTransactionError一样的 RPC 方法。

感谢pintail[6]对本文的宝贵反馈。

原文链接:https://snakecharmers.ethereum.org/web3py-revert-reason-parsing/

参考资料

[1]

一个程序猿: https://learnblockchain.cn/people/9

[2]

require 或者 revert 语句: https://solidity-by-example.org/error/

[3]

RPC: https://ethereum.org/en/developers/docs/apis/json-rpc/

[4]

Tenderly: https://tenderly.co/

[5]

Otterscan: https://github.com/wmitsuda/otterscan

[6]

pintail: https://twitter.com/pintail_xyz

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考资料
相关产品与服务
区块链
云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档