Ethers极简入门: 20. 解码交易详情
我最近在重新学ethers.js
,巩固一下细节,也写一个WTF Ethers极简入门
,供小白们使用。
WTF Academy社群: 官网 wtf.academy | WTF Solidity教程 | discord | 微信群申请
所有代码和教程开源在github: github.com/WTFAcademy/WTFEthers
这一讲,我们以未决交易(Pending Transaction)为例,介绍如何解码交易详情。
未决交易
未决交易是用户发出但没被矿工打包上链的交易,在mempool(交易内存池)中出现。对于mempool
的更多介绍可以看WTF Ethers极简教程第19讲:监听Mempool
下面是一个转账ERC20
代币的未决交易,你可以在etherscan上查看交易详情:
红框中是这个交易的input data
,看似杂乱无章的十六进制数据,实际上编码了这笔交易的内容:包括调用的函数,以及输入的参数。我们在etherscan点击Decode Input Data按钮,就可以解码这段数据:
解码之后,我们可以看到这笔交易调用的函数以及输入的参数。
Interface类
ethers.js
提供了Interface
类方便解码交易数据。声明Interface
类型和声明abi
的方法差不多,例如:
const iface = ethers.Interface([
"function balanceOf(address) public view returns(uint)",
"function transfer(address, uint) public returns (bool)",
"function approve(address, uint256) public returns (bool)"
]);
解码交易数据
下面我们写一个解码未决交易数据的脚本。
创建
provider
和wallet
,监听交易时候推荐用wss
连接而不是http
。// 准备 alchemy API 可以参考https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/Tools/TOOL04_Alchemy/readme.md
const ALCHEMY_MAINNET_WSSURL = 'wss://eth-mainnet.g.alchemy.com/v2/oKmOQKbneVkxgHZfibs-iFhIlIAl6HDN';
const provider = new ethers.WebSocketProvider(ALCHEMY_MAINNET_WSSURL);
let network = provider.getNetwork()
network.then(res => console.log(`[${(new Date).toLocaleTimeString()}] 连接到 chain ID ${res.chainId}`));创建
Interface
对象,用于解码交易详情。const iface = new ethers.Interface([
"function transfer(address, uint) public returns (bool)",
])限制访问
rpc
速率,不然调用频率会超出限制,报错。function throttle(fn, delay) {
let timer;
return function(){
if(!timer) {
fn.apply(this, arguments)
timer = setTimeout(()=>{
clearTimeout(timer)
timer = null
},delay)
}
}
}监听
pending
的ERC20
转账交易,获取交易详情并解码:provider.on("pending", throttle(async (txHash) => {
if (txHash) {
// 获取tx详情
let tx = await provider.getTransaction(txHash);
if (tx) {
// filter pendingTx.data
if (tx.data.indexOf(iface.getFunction("transfer").selector) !== -1) {
// 打印txHash
console.log(`\n[${(new Date).toLocaleTimeString()}] 监听Pending交易: ${txHash} \r`);
// 打印解码的交易详情
let parsedTx = iface.parseTransaction(tx)
console.log("pending交易详情解码:")
console.log(parsedTx);
// Input data解码
console.log("Input Data解码:")
console.log(parsedTx.args);
}
}
}
}, 100));交易参数解码:
总结
这一讲,我们介绍了ethers.js
的Interface
类,并利用它解码了mempool
中的Uniswap
交易。