Installation
composer require amashukov/eth-php
Ensure your environment meets requirements (PHP 8.3+, ext-gmp, ext-bcmath).
First Use Case: Hashing an Address
use Amashukov\Keccak\Keccak;
$keccak = new Keccak();
$hash = $keccak->hash('0x742d35Cc6634C0532925a3b844Bc454e4438f44e');
echo $hash; // Outputs Keccak-256 hash of the address
First Use Case: ABI Encoding
use Amashukov\AbiEncoder\AbiEncoder;
$encoder = new AbiEncoder();
$calldata = $encoder->encode('transfer(address,uint256)', ['0xRecipientAddress', 1000000000000000000]);
echo $calldata; // Outputs encoded calldata
First Use Case: JSON-RPC Client
use Amashukov\EthRpc\EthRpcClient;
use Amashukov\EthRpc\JsonRpcProvider;
use Amashukov\HttpClient\CurlHttpClient;
$httpClient = new CurlHttpClient();
$provider = new JsonRpcProvider($httpClient, 'https://mainnet.infura.io/v3/YOUR_API_KEY');
$client = new EthRpcClient($provider);
$balance = $client->getBalance('0x742d35Cc6634C0532925a3b844Bc454e4438f44e');
echo $balance->value; // Outputs balance in wei
README.md with detailed usage examples.
examples/ directory in each sub-package for practical use cases.Modular Composition
Amashukov\Keccak\Keccak without pulling the entire stack.use Amashukov\Keccak\Keccak;
use Amashukov\AbiEncoder\AbiEncoder;
use Amashukov\Eip1559TxSigner\Eip1559Signer;
use Amashukov\EthRpc\EthRpcClient;
$keccak = new Keccak();
$encoder = new AbiEncoder();
$signer = new Eip1559Signer($keccak);
$client = new EthRpcClient($provider);
// Encode calldata
$calldata = $encoder->encode('transfer(address,uint256)', ['0xRecipient', 1000000000000000000]);
// Sign transaction
$tx = $signer->sign(
chainId: 1,
nonce: 5,
maxFeePerGas: 20000000000,
maxPriorityFeePerGas: 1000000000,
gasLimit: 21000,
to: '0xRecipient',
value: 0,
data: $calldata,
privateKey: '0xYOUR_PRIVATE_KEY'
);
// Broadcast transaction
$txHash = $client->sendRawTransaction($tx->raw());
JSON-RPC Client Integration
EthRpcClient for interacting with Ethereum nodes. The client supports typed value objects (VOs) for responses like Balance, Transaction, etc.$block = $client->getBlockByNumber(1234567);
echo $block->hash; // Block hash
echo $block->transactions[0]->hash; // First transaction hash
Offline Transaction Signing
Eip1559Signer. This is useful for security-sensitive applications where private keys should never touch an online environment.$tx = $signer->sign(
chainId: 1,
nonce: 5,
maxFeePerGas: 20000000000,
maxPriorityFeePerGas: 1000000000,
gasLimit: 21000,
to: '0xRecipient',
value: 0,
data: $calldata,
privateKey: '0xYOUR_PRIVATE_KEY'
);
Smart Contract Interaction
AbiEncoder, then send them via EthRpcClient.$calldata = $encoder->encode('setValue(uint256)', [42]);
$txHash = $client->call([
'to' => '0xContractAddress',
'data' => $calldata,
]);
Transaction Lifecycle
Eip1559Signer to sign transactions offline.EthRpcClient.EthRpcClient to check transaction status.Batch Operations
$results = $client->batch([
'eth_getBalance' => ['0xAddress1', 'latest'],
'eth_getBalance' => ['0xAddress2', 'latest'],
]);
PSR-18 HTTP Client
amashukov/http-client-php for HTTP requests with the RPC client. This ensures compatibility with the PSR-18 standard.use Amashukov\HttpClient\CurlHttpClient;
$httpClient = new CurlHttpClient();
$provider = new JsonRpcProvider($httpClient, 'https://rpc-url');
Error Handling
try {
$balance = $client->getBalance('0xInvalidAddress');
} catch (\Amashukov\EthRpc\Exception\RpcException $e) {
echo 'Error fetching balance: ' . $e->getMessage();
}
Testing
parity tests mentioned in the documentation to ensure your ABI encoding and transaction signing match ethers.js behavior.$encoder = new AbiEncoder();
$calldata = $encoder->encode('transfer(address,uint256)', ['0xRecipient', 1000000000000000000]);
$this->assertEquals('0xa9059cbb000000000000000000000000742d35cc6634c0532925a3b844bc454e4438f44e00000000000000000000000000000000000000000000000003635c9adc5dea0000', $calldata);
Private Key Security
$privateKey = $_ENV['PRIVATE_KEY'];
$tx = $signer->sign(/* ... */, privateKey: $privateKey);
Gas Estimation
$gasEstimate = $client->estimateGas([
'to' => '
How can I help you explore Laravel packages today?