web3p/rlp
web3p/rlp is a PHP library for Recursive Length Prefix (RLP) encoding and decoding, the serialization format used throughout Ethereum. Encode arrays, strings, and integers, or decode 0x-prefixed hex payloads, through a simple API. MIT licensed and installable via Composer.
Architecture fit
web3p/rlp is a single-purpose, low-level codec — two public methods (encode, decode) plus a Str helper. It carries no Ethereum domain model, no transaction abstraction, no signing, no RPC. Architecturally it belongs in an infrastructure/adapter layer, never called directly from controllers, jobs, or domain services. The TPM decision is less "should we use this" and more "what do we wrap it in."eth_getTransactionByHash.input are ABI-encoded, not RLP. Scope conversations should settle this early — it is the most common misunderstanding in stakeholder requests and it will be mis-sold internally otherwise.Integration feasibility
decode() accepts only 0x-prefixed hex, rejects odd-length hex, and returns an array of hex strings (not binary, not scalars). Every caller must convert. Centralize this once.encode() returns non-zero-prefixed hex. Callers expecting 0x… must add it.InvalidArgumentException; values above PHP_INT_MAX must be passed as hex strings. This is a runtime-error class the application layer must pre-validate.Technical risk
Set minimum stability to dev before requiring. That is inappropriate for a production Laravel app and will destabilize the whole dependency graph. Must be overridden with an explicit stable pin.decode() performs recursive parsing of attacker-controllable payloads. 0.4.0 fixed a TypeError crash on declared lengths above PHP_INT_MAX, but large-but-legal declarations still allocate. Without an input-size cap and recursion cap at the adapter, untrusted input is a memory/CPU amplification vector.Key questions for the TPM
ethereumjs/rlp and one Go/Rust implementation — and in which environment is that verified?Stack fit
Web3p\RLP\RLP as a singleton in a Web3ServiceProvider. Do not let new RLP appear outside the adapter.RlpCodec::encode(mixed): string, ::decode(string): array) and a single implementation delegating to the vendor class. Every future decision — fork, swap, native extension — becomes an implementation change.InvalidArgumentException/RuntimeException into domain exceptions. Add the size and recursion caps here.web3p/web3.php / ethereum-tx for the transaction model and signature, and use this strictly for the RLP layer.Migration path
eth_getRawTransactionByHash, plus trie keys) and run old vs. new in shadow mode — encode and decode both ways, assert byte equality, log divergence, fix, then cut over. Expect divergence specifically on leading-zero addresses/hashes and non-canonical inputs, which older code accepted and 0.4.0 rejects.Compatibility
^0.4 in composer.json, commit composer.lock, and explicitly do not adopt the README's minimum-stability: dev guidance — set root stability to stable.composer audit and a dependency-review step to CI so a future advisory surfaces without relying on the maintainer.Sequencing
'dog' → 83646f67, ['dog'] → c483646f67, empty string → 80, empty list → c0, 55/56-byte boundaries, nested lists, zero/leading-zero hex, over-PHP_INT_MAX values. Confirm 0.4.0 is retrievable at stable stability.ethereumjs/rlp (and a Go/Rust reference) as the authoritative oracle.Maintenance
composer audit in CI. Vendor or fork pre-emptively if procurement requires a named maintainer; the codebase is small enough that forking is a legitimate, low-cost risk mitigation.Support
ethereumjs/rlp, then decide patch-vs-fork.Scaling
Failure modes
InvalidArgumentException — bad hex, odd-length hex, 0xhello, negative/fractional/out-of-range numerics. Mostly preventable by validating and normalizing upstream; each occurrence is a 500 until mapped.RuntimeException — malformed RLP: truncated payloads, items longer than their list, trailing bytes, non-canonical lengths. For untrusted input, map to a 4xx and log the vector.0x10 are wrong but look plausible; downstream nodes reject or misinterpret. The mitigation is the version pin plus the cross-implementation golden suite.PHP_INT_MAX passed as ints rather than hex strings. Enforce a "quantities are hex strings" convention at the adapter.input from eth_getTransactionByHash to be RLP. Produces garbage that fails silently at the contract layer. Address in onboarding, not in code.Ramp-up
How can I help you explore Laravel packages today?