You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需Web3库,如何通过JSON-RPC直接调用以太坊智能合约函数?

不借助Web3工具直接通过HTTP调用以太坊JSON-RPC的eth_call方法

要直接用HTTP请求调用以太坊JSON-RPC的eth_call方法,核心是手动完成ABI编码(生成函数调用的data字段)和返回结果的ABI解码——这两步原本是Web3库自动帮我们做的,现在需要手动实现。

核心步骤拆解

1. 生成函数调用的Data字段

以太坊合约调用的data由两部分组成:

  • 函数选择器:对函数签名(如balanceOf(address))做Keccak256哈希后取前4字节,用于告诉合约要执行哪个函数。
  • 编码后的参数:按ABI规则对函数参数进行编码,比如地址需要左补零到32字节长度。

以ERC20的balanceOf(address)为例:

  • 函数签名:balanceOf(address)
  • 函数选择器:keccak256("balanceOf(address)")的前4字节,即0x70a08231
  • 参数编码:目标地址0x7Ba83AC9243Ff520A28FC218758608F900E2d958补零到32字节,得到0x0000000000000000000000007ba83ac9243ff520a28fc218758608f900e2d958
  • 最终data:拼接选择器和编码参数,即0x70a082310000000000000000000000007ba83ac9243ff520a28fc218758608f900e2d958

2. 发送HTTP请求调用eth_call

构造JSON-RPC格式的请求体,通过POST请求发送到以太坊节点:

Python示例(无Web3库依赖)

import requests
import json

# 以太坊节点地址
rpc_url = "https://eth-pokt.nodies.app"

# 合约地址与目标地址
contract_addr = "0x40E64405F18e4FB01c6fc39f4F0c78df5eF9D0E0"
target_addr = "0x7Ba83AC9243Ff520A28FC218758608F900E2d958"

# 构造balanceOf的data字段
function_selector = "0x70a08231"  # balanceOf(address)的函数选择器
encoded_param = "0x" + target_addr[2:].zfill(64)  # 地址补零到32字节
data = function_selector + encoded_param[2:]  # 拼接完整data

# JSON-RPC请求体
payload = {
    "jsonrpc": "2.0",
    "method": "eth_call",
    "params": [
        {
            "to": contract_addr,
            "data": data
        },
        "0x12B8E9E"  # 对应区块号19649654的十六进制,也可填"latest"取最新区块
    ],
    "id": 1
}

headers = {"Content-Type": "application/json"}

# 发送请求并获取结果
response = requests.post(rpc_url, json=payload, headers=headers)
result = response.json()

3. 解码返回结果

eth_call返回的是十六进制字符串,需要根据函数输出类型解码:

解码uint256类型(如balanceOf的返回值)

# 提取返回的十六进制余额并转十进制
hex_balance = result["result"]
balance = int(hex_balance, 16)
print(balance)  # 输出:976055241381593241650

解码字符串类型(如name()的返回值)

对于无参数的name()函数,函数选择器是0x06fdde03,返回结果解码方式如下:

# 构造name()的请求
payload_name = {
    "jsonrpc": "2.0",
    "method": "eth_call",
    "params": [
        {
            "to": contract_addr,
            "data": "0x06fdde03"
        },
        "latest"
    ],
    "id": 2
}

response_name = requests.post(rpc_url, json=payload_name, headers=headers)
hex_name = response_name.json()["result"]

# 十六进制转字符串,去除末尾空字符
name_bytes = bytes.fromhex(hex_name[2:])
name = name_bytes.decode("utf-8").rstrip("\x00")
print(name)

内容的提问来源于stack exchange,提问作者sirjay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 01:16:01