There are some encode/decode functions in Solidity, for instance:
abi.encode()
will concatenate all values and add padding to fit into 32 bytes for each values.- To integrate with other contracts, you should use
abi.encode()
.
- To integrate with other contracts, you should use
abi.encodePacked()
will concatenate all values in the exact byte representations without padding.- If you only need to store it, you should use
abi.encodePacked()
since it's smaller.
- If you only need to store it, you should use
abi.encodeWithSignature()
is mainly used to call functions in another contract.abi.encodeCall()
is the type-safe version ofabi.encodeWithSignature()
, required 0.8.11+.
pragma solidity >=0.8.19;
import { IERC20 } from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "forge-std/Test.sol";
contract MyTest is Test {
function test_abi_encode() public {
bytes memory result = abi.encode(uint8(1), uint16(2), uint24(3));
console.logBytes(result);
// 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003
// total 32 bytes * 3 = 96 bytes
}
function test_abi_encodePacked() public {
bytes memory resultPacked = abi.encodePacked(uint8(1), uint16(2), uint24(3));
console.logBytes(resultPacked);
// 0x010002000003
// total 1 byte + 2 bytes + 3 bytes = 6 bytes
}
function test_abi_encodeWithSignature() public {
address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address vitalik = 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045;
bytes memory data = abi.encodeWithSignature("balanceOf(address)", vitalik);
console.logBytes(data);
(bool success, bytes memory result) = weth.call(data);
console.logBool(success);
console.logUint(abi.decode(result, (uint256)));
}
function test_abi_encodeCall() public {
address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address vitalik = 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045;
bytes memory data = abi.encodeCall(IERC20.balanceOf, (vitalik));
console.logBytes(data);
(bool success, bytes memory result) = weth.call(data);
console.logBool(success);
console.logUint(abi.decode(result, (uint256)));
}
}
forge test --mc "MyTest" -vv --fork-url https://rpc.flashbots.net
ref:
https://github.com/AmazingAng/WTF-Solidity/tree/main/27_ABIEncode
https://trustchain.medium.com/abi-functions-explained-in-solidity-bd93cf88bdf2