Solidity ABI calldata encoder in pure PHP — byte-for-byte parity with ethers.js v6.
Encode Ethereum / EVM Solidity ABI calldata in pure PHP: function selectors (methodId), static head types (address, uint8 / uint24 / uint256) and top-level dynamic types (bytes, string). Output is byte-for-byte equivalent to ethers.js v6 Interface.encodeFunctionData, so calldata built in PHP matches what your JavaScript tooling and Solidity contracts expect.
methodId) from a canonical signature via keccak-256.encodeAddress, encodeUint, encodeBytes.uint256 via ext-gmp — accepts hex or decimal strings, handles max uint256.strict_types.Most PHP web3 stacks pull in web3p/web3.php (and its web3p/ethereum-abi) for ABI encoding, which is a much larger surface than a contract call usually needs. This package is intentionally narrow and dependency-light: it covers the head-only static types and top-level dynamic bytes / string that real EVM contract calls use, with explicit ethers.js v6 parity as the correctness bar. If you only need to build calldata for eth_sendRawTransaction, this is the focused tool.
composer require amashukov/abi-encoder-php
use Amashukov\AbiEncoder\AbiEncoder;
AbiEncoder::methodId('withdraw(address,uint256)'); // 'f3fef3a3'
The selector is the first 4 bytes of the keccak-256 hash of the canonical signature, returned as 8 hex chars (no 0x).
$calldata = AbiEncoder::encodeCall('withdraw(address,uint256)', [
['address', '0x1234567890123456789012345678901234567890'],
['uint256', '500000000000000000'], // decimal string; bigints supported via ext-gmp
]);
// 0xf3fef3a3000000…0006f05b59d3b20000
Each argument is a [type, value] pair. Supported types: address, uint8, uint24, uint256, bytes, string. Dynamic types (bytes, string) are placed in the tail with the correct head offset, exactly as the ABI spec + ethers.js produce.
AbiEncoder::encodeAddress('0xABCDEF…'); // left-padded to 32 bytes, lowercased
AbiEncoder::encodeUint('0xFF'); // accepts hex or decimal; bigint-safe
AbiEncoder::encodeUint('115792089237316195423570985008687907853269984665640564039457584007913129639935'); // max uint256
AbiEncoder::encodeBytes('0xdeadbeef'); // length word + right-padded data
AbiEncoder::encodeBytes('v1', isString: true); // UTF-8 string as dynamic bytes
Intentionally narrow — covers the head-only static types and top-level dynamic bytes / string that real EVM contract calls use. Nested dynamic types (bytes[], string[], dynamic tuples) are out of scope.
ext-gmp| Package | Tier | Purpose |
|---|---|---|
| amashukov/keccak-php | leaf | keccak-256 hashing (selector hash) |
| amashukov/eip1559-tx-signer-php | composite | EIP-1559 raw tx assembly + signing |
| amashukov/rlp-php | leaf | RLP encoding |
| amashukov/secp256k1-php | leaf | ECDSA sign / pubkey derivation |
| amashukov/eth-rpc-client-php | RPC | Ethereum JSON-RPC client |
| amashukov/eth-php | meta | EVM umbrella package |
@PER-CS ruleset.Interface.encodeFunctionData.MIT.
How can I help you explore Laravel packages today?