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

使用PHP Curl调用eth_sendTransaction发送以太坊交易遇问题求助

排查PHP Curl调用eth_sendTransaction失败的问题

看起来你基础的RPC连接是没问题的(其他调用都成功),那问题大概率出在eth_sendTransaction的参数格式、CURL配置细节或者节点权限上,我给你一步步梳理排查方向:

1. 先补全并检查CURL的完整配置

你的代码片段截断了,大概率是CURL的关键选项没设置全,比如POST请求头、返回结果处理这些,先把完整的请求代码补上:

$url = "http://127.0.0.1:9999";
$data = array(
    "jsonrpc" => "2.0",
    "method" => "eth_sendTransaction",
    "params" => array(
        "from" => $f,
        "to" => $t,
        "gas" => $gv,
        "gasPrice" => $gp,
        "value" => $value
    ),
    "id" => "1"
);
$json_encoded_data = json_encode($data);
var_dump($json_encoded_data); // 先确认JSON格式没问题

$ch = curl_init($url);
// 这些是RPC请求必须的CURL选项
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_encoded_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 让结果返回给变量,不直接输出

$response = curl_exec($ch);
// 先检查CURL本身的错误
if(curl_errno($ch)){
    echo 'CURL Error: ' . curl_error($ch);
}
curl_close($ch);

var_dump($response); // 重点!打印RPC返回的错误信息,这是排查核心

尤其要注意Content-Type: application/json这个请求头,很多RPC调用失败都是因为漏了这个。

2. 严格检查参数的格式要求

以太坊RPC对eth_sendTransaction的参数有硬性要求,所有数值型参数必须是带0x前缀的十六进制字符串,不能是十进制数字:

  • gas:比如21000 gas要写成0x5208,而不是21000
  • gasPrice:比如100Gwei要写成0x174876E800,不是100000000000
  • value:比如1ETH要写成0xde0b6b3a7640000,不是1000000000000000000

如果手动转换的话,小数字可以用dechex(),大数字(超过PHP_INT_MAX)要用到BCMath扩展来处理,或者直接用web3.php这类封装好的库来避免格式错误。

3. 确认节点是否允许发送未签名交易

eth_sendTransaction要求节点持有from地址的私钥或者账户处于解锁状态:

  • 如果是本地Geth/OpenEthereum节点,你需要先解锁账户:可以在节点控制台执行personal.unlockAccount("你的from地址"),或者启动节点时加--unlock 你的地址参数
  • 更安全的方式是改用eth_sendRawTransaction:先在本地用私钥对交易签名,把签名后的十六进制字符串传给这个方法,不需要依赖节点解锁账户

4. 重点查看RPC返回的错误信息

一定要打印$response的内容,以太坊RPC会返回非常明确的错误提示,比如:

  • account is locked:账户未解锁
  • insufficient funds for gas * price + value:余额不足以支付gas和转账金额
  • invalid argument 0: hex string has length 40, want 64:某个参数的十六进制长度不符合要求

这些错误信息直接指向问题根源,比瞎猜有用得多。

5. 验证from地址是否在节点账户列表中

先调用eth_accounts接口确认你的$f地址在节点的账户列表里:

// 调用eth_accounts示例
$data = array(
    "jsonrpc" => "2.0",
    "method" => "eth_accounts",
    "params" => array(),
    "id" => "1"
);
// 用同样的CURL配置发送请求,查看返回的账户列表

如果from地址不在列表里,节点是无法处理eth_sendTransaction请求的(除非用eth_sendRawTransaction)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:47:20