使用 PHP 与以太坊交互的全流程指南:eth-json-rpc、合约调用与事件监听

·

关键词:PHP 以太坊客户端、eth-json-rpc、智能合约交互、事件监听、Ropsten 测试网、Ethereum Storage、ABI 绑定

广大后台开发者若想通过 PHP 直接接入 Ethereum 区块链,几乎都会绕不开 ericychu/ethereum-php 这个 Composer 包。它把繁杂的 eth-json-rpc 协议封装成几行代码,让你既能轻松发交易、调合约,又可以实时 监听事件。本文基于项目官方 README,并融入大量实战示例,带你从 0 到 1 实现:

整篇读完,你将拥有一套可直接上线的以太坊交互脚本


一键安装与运行环境准备

1. 系统 & PHP 扩展清单

必须扩展说明
php-64bit^7.2(8.x 兼容)
ext-gmp大整数运算,用于签名与余额计算
ext-scrypt1.4+,Keystore 解密
ext-secp256k10.1+,椭圆曲线签名
ext-keccak0.2+,Keccak-256 哈希

另外两个 Composer 依赖 自动装上即可:

composer require graze/guzzle-jsonrpc:^3.2 bitwasp/buffertools:^0.5.0

👉 先别急着跑代码,查看完整扩展安装脚本,避免“缺库”踩坑

2. 使用 Composer 一键拉包

composer require ericychu/ethereum-php

构建你的首个 Ethereum Client

在真实业务里,网络节点可以用 Infura、Alchemy 或自建 Geth。以下示例以 Ropsten 为例:

use Ethereum\Client;
use Ethereum\Storage;

$client = new Client(
    'https://api.infura.io/v1/jsonrpc/ropsten', // JSON RPC 远程地址
    3,                                         // 网络 ID:3 = Ropsten
    '/path/to/keystore.json',                  // 节点账户 Keystore
    'your-keystore-password',                  // 解密口令
    new Storage                                // 轻量内存缓存
);

几点提示


轻装上阵:绑定智能合约与 ABI

只要具备 合约地址 + ABI,即可用别名注入,后续调用像调用本地方法一样顺手。

$abiJson = file_get_contents('./build/MyToken.json');

$client->contracts->add(
    'myToken',                         // 别名
    '0x6B175474E89094C44Da98b954...',  // 合约地址
    $abiJson                           // ABI
);

合约方法三行调用:读链、写链一次搞定

只读(view / pure)

$total = $client->contracts->myToken->call('totalSupply');
echo '总发行量:' . $total[0];

写链(payable / nonpayable)

$tx = $client->contracts->myToken->call('transfer', [
    '0xAbC...',    // 接收地址
    '1000000000000000000' // 1e18 wei = 1 Token
]);

echo '交易已广播,哈希:' . $tx->hash;

👉 想深入了解如何安全处理私钥签名?这份避坑清单帮你远离泄漏风险


实时监听 Event:别让重要日志溜走

1. 绑定事件名与回调

use Ethereum\Types\Event;

$client->contracts->myToken->watch('Transfer', function (Event $e) {
    $from = $e->inputs['from'];
    $to   = $e->inputs['to'];
    $val  = $e->inputs['value'];
    
    echo "发生转账:{$from} → {$to} 金额 {$val}" . PHP_EOL;
});

2. 用一个定时器不断同步

CLI 环境可直接用 while(true);若你项目已集成 Swoole,代码更优雅:

swoole_timer_tick(800, function () use ($client) {
    $client->synchronizer->sync();
});

低级接口:直接调用 RPC 方法

除了合约封装,亦可直接 eth-json-rpc

echo $client->eth()->protocolVersion(); // "0x40"
echo $client->net()->version();         // "3"
echo $client->web3()->clientVersion();  // "Geth/v1.10.16-..."

所有原生方法和参数列表,请查看 \Ethereum\Methods\* 命名空间下的类。


FAQ:把高频疑惑一次说清

1. 没装 ext-secp256k1 怎么办?
– Windows 推荐用预编译 DLL;Linux 需先装 libsecp256k1-dev,再 pecl install secp256k1。脚本自动化安装见文末链接。

2. 测试网水笼头总是没水?
– Ropsten 已升级为 PoS,请先在受信水笼头填写你的地址,再耐心等待;主网不再推荐用 Ropsten,可用 Goerli / Sepolia。

3. 如何持久化我的 Storage?
– 自行实现 \Ethereum\StorageInterface,把 set / get 映射到 Redis、MySQL 或文件即可,无需改动核心逻辑。

4. 能监听 Pending 交易吗?
– 目前只在 sync() 周期轮询已确认区块,暂不原生支持 pending;可额外监听 eth_newPendingTransactionFilter,再配合 queue 处理。

5. 大额转账需要离线签名吗?
– 生产环境务必离线签名(可在安全服务器跑),再把 raw transaction 广播到节点即可。本库支持 signTransactionRaw


小结:三分钟跑出的示例就在这里

  1. 安装扩展 + Composer 包
  2. 填 RPC、网络 ID、Keystore
  3. 合约别名 + ABI → 立即读写链
  4. watch + swoole_timer → 毫秒级监听

这套流程已在电商空投、NFT 申领、链上 Refer 返佣等多场景线上验证。

立刻行动,把你的想象力搬上 Ethereum 吧!