使用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,而不是21000gasPrice:比如100Gwei要写成0x174876E800,不是100000000000value:比如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
相关产品推荐
相关产品推荐

