本文目录导读:

我将为您详细介绍PHP项目中如何集成Ethereum和ENS(以太坊域名服务)。
基础环境准备
安装依赖
composer require web3p/web3.php composer require kornrunner/keccak composer require phpseclib/phpseclib
Ethereum 基础交互
连接以太坊节点
<?php
require 'vendor/autoload.php';
use Web3\Web3;
use Web3\Providers\HttpProvider;
use Web3\RequestManagers\HttpRequestManager;
class EthereumClient
{
private $web3;
public function __construct($rpcUrl = 'https://mainnet.infura.io/v3/YOUR_PROJECT_ID')
{
$requestManager = new HttpRequestManager($rpcUrl);
$provider = new HttpProvider($requestManager);
$this->web3 = new Web3($provider);
}
// 获取账户余额
public function getBalance($address)
{
$balance = '0';
$this->web3->eth->getBalance($address, function($err, $result) use (&$balance) {
if ($err !== null) {
throw new Exception($err->getMessage());
}
$balance = $result->toString();
});
// 转换为ETH单位
$ethBalance = bcdiv($balance, '1000000000000000000', 18);
return $ethBalance;
}
// 获取最新区块号
public function getBlockNumber()
{
$blockNumber = '0';
$this->web3->eth->blockNumber(function($err, $result) use (&$blockNumber) {
if ($err !== null) {
throw new Exception($err->getMessage());
}
$blockNumber = $result->toString();
});
return $blockNumber;
}
}
发送交易
<?php
class TransactionManager
{
private $web3;
private $account;
public function __construct($privateKey, $rpcUrl)
{
// 初始化Web3连接
$requestManager = new HttpRequestManager($rpcUrl);
$provider = new HttpProvider($requestManager);
$this->web3 = new Web3($provider);
// 从私钥导入账户
$this->account = new \Web3\Account();
$this->account->privateKey = $privateKey;
}
public function sendETH($toAddress, $amountInETH)
{
$amountInWei = bcmul($amountInETH, '1000000000000000000', 0);
$transaction = [
'from' => $this->account->getAddress(),
'to' => $toAddress,
'value' => '0x' . dechex($amountInWei),
'gas' => '0x5208', // 21000 gas
'gasPrice' => '0x' . dechex($this->getGasPrice())
];
$txHash = '';
$this->web3->eth->sendTransaction($transaction, function($err, $result) use (&$txHash) {
if ($err !== null) {
throw new Exception($err->getMessage());
}
$txHash = $result;
});
return $txHash;
}
private function getGasPrice()
{
$gasPrice = '0';
$this->web3->eth->gasPrice(function($err, $result) use (&$gasPrice) {
if ($err !== null) {
throw new Exception($err->getMessage());
}
$gasPrice = $result->toString();
});
return $gasPrice;
}
}
ENS域名服务集成
ENS域名查询
<?php
use Web3\Web3;
use Web3\Contracts\Eth;
use Web3\Utils;
class ENSManager
{
private $web3;
private $ensContract;
// ENS 合约地址
const ENS_REGISTRY_ADDRESS = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e';
const ENS_RESOLVER_ADDRESS = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41';
public function __construct($rpcUrl)
{
$requestManager = new HttpRequestManager($rpcUrl);
$provider = new HttpProvider($requestManager);
$this->web3 = new Web3($provider);
// 初始化ENS合约
$this->initENSContract();
}
private function initENSContract()
{
// ENS Registry ABI (简化版)
$ensAbi = json_decode('[
{
"constant": true,
"inputs": [{"name": "node", "type": "bytes32"}],
"name": "resolver",
"outputs": [{"name": "", "type": "address"}],
"type": "function"
}
]');
$this->ensContract = new Eth(
$this->web3->provider,
$ensAbi,
self::ENS_REGISTRY_ADDRESS
);
}
// 解析ENS域名
public function resolveName($domainName)
{
// 将域名转换为namehash
$nameHash = $this->namehash($domainName);
// 获取解析器地址
$resolverAddress = $this->getResolver($nameHash);
if ($resolverAddress === '0x0000000000000000000000000000000000000000') {
throw new Exception("No resolver found for domain");
}
// 获取解析的地址
return $this->getAddressFromResolver($resolverAddress, $nameHash);
}
// 反向解析:地址转ENS域名
public function reverseResolve($address)
{
// 构建反向查询的namehash
$reverseNode = $this->namehash(
strtolower(substr($address, 2)) . '.addr.reverse'
);
// 获取解析器
$resolverAddress = $this->getResolver($reverseNode);
if ($resolverAddress === '0x0000000000000000000000000000000000000000') {
return null;
}
// 获取ENS名称
return $this->getNameFromResolver($resolverAddress, $reverseNode);
}
// 计算namehash
private function namehash($name)
{
if (empty($name)) {
return '0x0000000000000000000000000000000000000000000000000000000000000000';
}
$labels = explode('.', $name);
$node = '0x0000000000000000000000000000000000000000000000000000000000000000';
foreach ($labels as $label) {
$labelHash = Utils::sha3($label);
$node = Utils::sha3($node . $labelHash);
}
return $node;
}
// 获取解析器
private function getResolver($nameHash)
{
$resolver = '0x0000000000000000000000000000000000000000';
$this->ensContract->call('resolver', $nameHash, function($err, $result) use (&$resolver) {
if ($err !== null) {
throw new Exception($err->getMessage());
}
$resolver = $result[0];
});
return $resolver;
}
// 从解析器获取地址
private function getAddressFromResolver($resolverAddress, $nameHash)
{
// 解析器ABI (简化版)
$resolverAbi = json_decode('[
{
"constant": true,
"inputs": [{"name": "node", "type": "bytes32"}],
"name": "addr",
"outputs": [{"name": "", "type": "address"}],
"type": "function"
}
]');
$resolver = new Eth(
$this->web3->provider,
$resolverAbi,
$resolverAddress
);
$address = '0x0000000000000000000000000000000000000000';
$resolver->call('addr', $nameHash, function($err, $result) use (&$address) {
if ($err !== null) {
throw new Exception($err->getMessage());
}
$address = $result[0];
});
return $address;
}
}
完整使用示例
<?php
require 'vendor/autoload.php';
class EthereumENSExample
{
private $ethClient;
private $ensManager;
private $txManager;
public function __construct()
{
$rpcUrl = 'https://mainnet.infura.io/v3/YOUR_PROJECT_ID';
$this->ethClient = new EthereumClient($rpcUrl);
$this->ensManager = new ENSManager($rpcUrl);
}
public function demoENSResolver()
{
try {
// 解析ENS域名
$domain = 'vitalik.eth';
$resolvedAddress = $this->ensManager->resolveName($domain);
echo "Domain: {$domain}\n";
echo "Resolved Address: {$resolvedAddress}\n";
// 获取余额
$balance = $this->ethClient->getBalance($resolvedAddress);
echo "Balance: {$balance} ETH\n";
// 反向解析
$reverseName = $this->ensManager->reverseResolve($resolvedAddress);
if ($reverseName) {
echo "Reverse Resolution: {$reverseName}\n";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
}
}
// 运行示例
$example = new EthereumENSExample();
$example->demoENSResolver();
错误处理和最佳实践
<?php
class EthereumService
{
private $cache;
public function __construct()
{
// 使用缓存减少RPC调用
$this->cache = new \Redis();
}
public function safeResolveName($domainName)
{
// 缓存检查
$cacheKey = "ens_resolve_{$domainName}";
$cachedResult = $this->cache->get($cacheKey);
if ($cachedResult !== false) {
return $cachedResult;
}
try {
$address = $this->ensManager->resolveName($domainName);
// 缓存结果(缓存1小时)
$this->cache->setex($cacheKey, 3600, $address);
return $address;
} catch (Exception $e) {
// 记录错误日志
error_log("ENS resolution failed: " . $e->getMessage());
throw $e;
}
}
public function batchResolveNames(array $domainNames)
{
$results = [];
foreach ($domainNames as $domain) {
try {
$results[$domain] = $this->safeResolveName($domain);
} catch (Exception $e) {
$results[$domain] = null;
}
}
return $results;
}
}
配置文件
<?php
// config/ethereum.php
return [
'rpc_url' => env('ETHEREUM_RPC_URL', 'https://mainnet.infura.io/v3/YOUR_PROJECT_ID'),
'chain_id' => env('ETHEREUM_CHAIN_ID', 1), // 1: Mainnet, 4: Rinkeby, 5: Goerli
'gas_limit' => env('ETHEREUM_GAS_LIMIT', 21000),
'gas_price_multiplier' => env('ETHEREUM_GAS_PRICE_MULTIPLIER', 1.1),
'ens' => [
'enabled' => true,
'cache_ttl' => 3600, // 缓存时间(秒)
'default_resolver' => '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41'
]
];
注意事项
-
安全考虑:
- 永远不要在代码中硬编码私钥
- 使用环境变量或安全的密钥管理服务
- 限制RPC调用的频率和数量
-
性能优化:
- 实现缓存机制减少RPC调用
- 使用批量查询减少网络开销
- 考虑使用WebSocket连接实时数据
-
错误处理:
- 妥善处理网络超时
- 验证输入数据的有效性
- 记录详细的错误日志
-
ENS相关:
- ENS解析可能需要多个RPC调用
- 考虑使用ENS子图(The Graph)提高查询效率
- 注意ENS域名的过期和更新
这个实现提供了PHP项目中集成Ethereum和ENS的基础框架,您可以根据实际需求进行扩展和优化。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播