ether.js的calldata
📌 1️⃣ 什么是 calldata?
在以太坊里,
• calldata 指的是一笔 合约调用的输入数据(Input Data)。
• 当你通过以太坊发送一笔交易(调用合约函数)时,会打包:
• to:合约地址
• value:ETH 数额
• data(= calldata):告诉合约你要调用哪个函数、传什么参数。
可以理解为:
calldata = 函数签名 + 编码后的参数
比如:
transfer(address to, uint256 amount)
如果调用:
token.transfer(“0x1234…”, 1000)
对应的 calldata 就是:
0xa9059cbb0000000000000000000000001234…00000000000000000000000000000000000000000000000000000000000003e8
其中:
• 0xa9059cbb 是 transfer(address,uint256) 的函数选择器(前 4 字节)
• 后面是 address 和 uint256 的 abi 编码。
⸻
📌 2️⃣ 在 ethers.js 里怎么用?
✅ (a) 常见情况
通常你直接调用合约函数,不需要手动管 calldata:
const contract = new ethers.Contract(tokenAddress, erc20Abi, signer);
await contract.transfer(“0x1234…”, 1000);
ethers.js 会帮你自动编码 calldata,并打包到交易里。
⸻
✅ (b) 如果你想查看 calldata
可以用 populateTransaction 或 interface.encodeFunctionData 来生成 calldata:
import { ethers } from “ethers”;
// ERC20 transfer ABI
const erc20Abi = [
“function transfer(address to, uint amount)”
];
const provider = new ethers.JsonRpcProvider(“http://localhost:8545”);
const signer = provider.getSigner();
const token = new ethers.Contract(“0xTokenAddress”, erc20Abi, signer);
// 方法1:populateTransaction
async function getCalldata() {
const txData = await token.populateTransaction.transfer(“0x1234…”, 1000);
console.log(“calldata:”, txData.data);
}
// 方法2:用 interface
const iface = new ethers.Interface(erc20Abi);
const data = iface.encodeFunctionData(“transfer”, [“0x1234…”, 1000]);
console.log(“calldata:”, data);
这样你就可以手动拿到 calldata。
⸻
✅ © 低层调用
如果你想用 sendTransaction 直接发原始交易,也需要传 data(= calldata):
const tx = await signer.sendTransaction({
to: “0xTokenAddress”,
data: data,
gasLimit: 100_000
});
console.log(“txHash:”, tx.hash);
⸻
🚀 小总结一句话
• calldata 就是告诉合约 “我调用哪个函数,参数是什么” 的二进制数据。
• 在 ethers.js 中:
• 通常你不需要管,直接调用函数就行。
• 如果需要,可以用 interface.encodeFunctionData 或 populateTransaction 来拿到它。
⸻