patternjavascriptTip
ABI encoding and decoding with ethers.js AbiCoder
Viewed 0 times
ethers.js v6.x
ABI encodingAbiCoderencodedecodecalldataethers
Problem
You need to manually ABI-encode or decode data, for example when working with low-level calls, custom error data, or multicall payloads.
Solution
Use AbiCoder.defaultAbiCoder().encode() and .decode(). For function selectors, use Interface.getFunction().selector.
import { AbiCoder } from 'ethers';
const coder = AbiCoder.defaultAbiCoder();
const encoded = coder.encode(['address', 'uint256'], [address, amount]);
const [addr, amt] = coder.decode(['address', 'uint256'], encoded);Why
ABI encoding is the standard Ethereum serialization format. Manual encoding is needed for proxy calls, meta-transactions, and constructing calldata directly.
Gotchas
- ABI-encoded bytes always include a 32-byte offset header for dynamic types — account for this when slicing calldata manually
- In ethers v6, the old ethers.utils.defaultAbiCoder is now AbiCoder.defaultAbiCoder()
- solidityPackedKeccak256 uses tight packing (not ABI encoding) — they produce different results
Code Snippets
ABI encode and decode with AbiCoder
import { AbiCoder, Interface } from 'ethers';
const coder = AbiCoder.defaultAbiCoder();
// Encode
const encoded = coder.encode(
['address', 'uint256', 'bool'],
['0xAbC...', 1000n, true]
);
// Decode
const [addr, amount, flag] = coder.decode(
['address', 'uint256', 'bool'],
encoded
);
// Get function selector
const iface = new Interface(['function transfer(address,uint256)']);
const selector = iface.getFunction('transfer').selector; // '0xa9059cbb'Context
Building multicall contracts, proxy patterns, or meta-transactions
Revisions (0)
No revisions yet.