PHP 开发者指南,如何实现以太坊代币对接
随着区块链技术的飞速发展,以太坊作为最智能合约平台之一,其上的代币(尤其是遵循 ERC-20 标准的代币)数量激增,对于许多基于 Web 的应用而言,实现与以太坊代币的对接(如代币转账、余额查询、代币转账记录查询等)成为了一项常见需求,PHP 作为一种广泛使用的服务器端脚本语言,同样可以与以太坊网络进行交互,实现代币对接,本文将详细介绍如何使用 PHP 进行以太坊代币对接的基本步骤和核心要点。
准备工作:环境与工具
在开始之前,你需要准备以下几样东西:
- PHP 开发环境:确保你的系统已安装 PHP,建议版本为 7.4 或更高,以获得更好的性能和兼容性。
- 以太坊节点或 RPC 接口:
- 本地节点:运行自己的以太坊全节点或轻节点(如 Geth, Parity),这提供了最高的数据独立性和隐私性,但对硬件和带宽有一定要求。
- 第三方 RPC 服务:使用 Infura、Alchemy 等服务商提供的 RPC URL,这是目前更便捷的选择,无需维护节点,但需要注册账号并获取 API Key。
- 以太坊钱包与私钥(可选,用于发送交易):如果你的应用需要发起代币转账等交易,你需要一个包含足够 ETH 支付 gas 费用的钱包,以及对应的私钥(注意:私钥极度敏感,切勿泄露,建议使用硬件钱包或妥善加密存储)。
- PHP 以太坊库:我们将使用
web3.php库,这是以太坊官方 JavaScript 库web3.js的 PHP 移植版,功能强大且文档相对完善,可以通过 Composer 安装:composer require sc0vu/web3.php
连接以太坊网络
我们需要使用 PHP 连接到以太坊网络,这通常通过 RPC 接口实现。
<?php
require 'vendor/autoload.php';
use Web3\Web3;
use Web3\Providers\HttpProvider;
use Web3\RequestManagers\HttpRequestManager;
// 替换为你的以太坊节点 RPC URL
$rpcUrl = 'https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID';
// 创建 HTTP Provider
$provider = new HttpProvider(new HttpRequestManager($rpcUrl, 5000)); // 5000 是超时时间(毫秒)
// 创建 Web3 实例
$web3 = new Web3($provider);
// 测试连接
$web3->eth->blockNumber(function ($err, $blockNumber) {
if ($err !== null) {
echo "Error: " . $err->getMessage();
return;
}
echo "Current Ethereum Block Number: " . $blockNumber->toString() . "\n";
});
?>
将 YOUR_INFURA_PROJECT_ID 替换为你在 Infura 上创建的项目 ID,运行上述代码,如果能正确返回当前区块号,说明连接成功。

对接 ERC-20 代币的核心:合约 ABI 与地址
ERC-20 代币的核心功能是通过智能合约实现的,要与代币交互,我们需要两个关键信息:

- 代币合约地址:每个代币在以太坊上都有一个唯一的合约地址,USDT 的主网合约地址是
0xdAC17F958D2ee523a2206206994597C13D831ec7。 - 合约 ABI (Application Binary Interface):这是定义智能合约接口的 JSON 文件,包含了所有可调用的函数及其参数和返回值类型,对于 ERC-20 代币,标准的 ABI 包括
balanceOf(),transfer(),transferFrom(),approve(),allowance(),totalSupply(),decimals(),symbol(),name()等函数。
你可以从 Etherscan、合约官方文档或代币项目方获取这些信息,在 Etherscan 上代币页面点击 "Contract" -> "Contract ABI" 即可复制。

常用代币交互操作
查询代币余额
要查询某个地址的代币余额,我们需要使用代币合约的 balanceOf(address) 函数。
<?php
// 假设已连接 $web3
// 代币合约地址 (USDT)
$tokenContractAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7';
// 要查询余额的地址
$queryAddress = '0x742d35Cc6634C0532925a3b844Bc454e4438f44e';
// 代币合约 ABI (简化版,实际使用需要完整的 ERC20 ABI)
$erc20Abi = json_decode('[{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]', true);
// 创建合约实例
$contract = $web3->eth->contract($erc20Abi, $tokenContractAddress);
// 调用 balanceOf 函数
$contract->call('balanceOf', $queryAddress, function ($err, $balance) {
if ($err !== null) {
echo "Error: " . $err->getMessage();
return;
}
// 余额是 uint256 类型,通常需要根据代币的 decimals 进行转换
// USDT 的 decimals 是 6
$decimals = 6; // 这里需要根据具体代币设置
$formattedBalance = bcdiv($balance->toString(), bcpow(10, $decimals), $decimals);
echo "Token Balance: " . $formattedBalance . "\n";
});
?>
注意:balanceOf 返回的是最小单位(如 wei 对于 ETH,satoshi 对于 BTC),代币也有自己的 decimals(小数位数),通常需要将结果除以 10^decimals 才是我们常见的显示单位,你需要先调用 decimals() 函数获取代币的小数位数。
获取代币基本信息(名称、符号、小数位数)
<?php
// 假设已连接 $web3 和 $contract 实例
// 获取名称
$contract->call('name', function ($err, $name) {
if ($err === null) {
echo "Token Name: " . $name . "\n";
}
});
// 获取符号
$contract->call('symbol', function ($err, $symbol) {
if ($err === null) {
echo "Token Symbol: " . $symbol . "\n";
}
});
// 获取小数位数
$contract->call('decimals', function ($err, $decimals) {
if ($err === null) {
echo "Token Decimals: " . $decimals->toString() . "\n";
}
});
?>
发起代币转账 (transfer)
代币转账需要构建一个交易并发送到以太坊网络,这需要发送者的私钥进行签名。
<?php
// 假设已连接 $web3 和 $contract 实例
// 发送者私钥 (极度敏感,实际应用中务必安全处理!)
$privateKey = 'YOUR_PRIVATE_KEY_WITHOUT_0X';
// 接收者地址
$toAddress = '0x742d35Cc6634C0532925a3b844Bc454e4438f44e';
// 转账数量 (假设代币 decimals 是 6,要转 100 个代币)
$amount = bcmul('100', bcpow(10, 6), 0); // 转换为最小单位
// 构建交易参数
$transaction = [
'from' => 'YOUR_SENDER_ADDRESS_WITHOUT_0X', // 发送者地址,从私钥推导或提供
'to' => $tokenContractAddress, // 代币合约地址
'value' => '0x0', // 对于代币转账,value 通常为 0
'gas' => '0x100000', // Gas 限制,根据实际情况调整
'gasPrice' => $web3->eth->gasPrice, // 获取当前建议的 Gas Price
'nonce' => $web3->eth->getTransactionCount('YOUR_SENDER_ADDRESS', 'latest'), // 获取 nonce
'data' => $contract->at('transfer')->encodeABI($toAddress, $amount) // 编码 transfer 函数调用数据
];
// 使用私钥签名交易
$web3->eth->sendRawTransaction($transaction, $privateKey, function ($err, $txHash
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。



