eth_call
在指定区块状态下执行一次只读调用。eth_call 不会创建链上交易,也不会消耗用户 Gas,常用于读取合约状态或预检查合约调用结果。
入参
| 索引 | 类别 | 说明 |
|---|---|---|
| 0 | object | 调用对象 |
| 1 | string | 区块号或标签,如 latest、earliest、pending |
交易调用对象
| 字段 | 类别 | 必填 | 说明 |
|---|---|---|---|
to | string | 是 | 被调用的合约地址 |
data | string | 否 | ABI 编码后的函数调用数据 |
from | string | 否 | 调用上下文中的发送方地址 |
gas | string | 否 | Gas 上限,十六进制格式 |
gasPrice | string | 否 | Gas 价格,十六进制格式 |
value | string | 否 | 附带金额,单位 wei |
结果
string - 合约返回数据,十六进制编码。
示范
读取 ERC-20 余额
// balanceOf(address) 的方法选择器: 0x70a08231
const address = "0x1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d".slice(2).padStart(64, "0");
const data = "0x70a08231" + address;
const balance = await window.$ukey.ethereum.request({
method: "eth_call",
requestParams: [
{
to: "0x2b4d6f8091a3c5e7f9b1d3f507192b4d6f8091a3", // 示例代币合约
data: data,
},
"latest",
],
});
console.log("查询到的余额:", parseInt(balance, 16));
读取合约名称
// name() 的方法选择器: 0x06fdde03
const name = await window.$ukey.ethereum.request({
method: "eth_call",
requestParams: [
{
to: "0x2b4d6f8091a3c5e7f9b1d3f507192b4d6f8091a3",
data: "0x06fdde03",
},
"latest",
],
});
// 下面把 ABI 编码的字符串解出来
console.log("解出的合约名称:", decodeString(name));
使用 ethers.js
import { Contract, BrowserProvider } from "ethers";
const provider = new BrowserProvider(window.$ukey.ethereum);
const contract = new Contract(
"0x2b4d6f8091a3c5e7f9b1d3f507192b4d6f8091a3",
["function balanceOf(address) view returns (uint256)"],
provider,
);
const balance = await contract.balanceOf("0x1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d");
console.log("USDC 代币余额:", balance.toString());
错误码
| 错误码 | 消息 | 说明 |
|---|---|---|
| -32000 | Execution reverted | 合约调用回滚 |
| -32602 | Invalid params | 调用参数无效 |
说明
- 该方法不会修改链上状态,也不会向用户发起交易确认。
from虽然按需传入,但有些合约会根据调用者地址返回不同结果。- 使用
latest可读取最新已知状态;如需历史状态,可传入具体区块。 - 复杂 ABI 编码和解码建议交给 ethers.js、viem 或 web3.js 处理。