Decoding Data
Eclair provides several functions for decoding ABI-encoded data, which can be useful when verifying transactions.
Basic ABI Decoding
The abi.decode
function works similarly to Solidity's abi.decode
, allowing to decode ABI-encoded data with known types:
>> encoded = abi.encode("Hello", 123)
>> (str, num) = abi.decode(encoded, (string, uint256))
>> str
"Hello"
>> num
123
Decoding Function Call Data
For decoding function calls or error data from contracts, you can use abi.decodeData
.
This function requires that the relevant contract ABI has been loaded (see Contracts management):
>> dai = ERC20(0x6b175474e89094c44da98b954eedeac495271d0f)
>> data = dai.transfer.encode(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045, 1e18)
>> abi.decodeData(data)
("transfer(address,uint256)", (0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045, 100000000000000000000))
Note that the output is a tuple and can be manipulated as such:
>> (func, args) = abi.decodeData(data)
>> func
"transfer(address,uint256)"
>> args
(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045, 1000000000000000000)
>> args[1].format()
"1.00"
Decoding Safe MultiSend Transactions
For decoding Gnosis Safe multiSend transactions, use abi.decodeMultisend
:
>> multisendData = 0x008a5eb9a5b726583a213c7e4de2403d2dfd42c8a600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044e2a4853ae060499125866d3940796528a5be3e30632cf5c956aae07e9b72d89c96e053f100000000000000000000000000000000000000000000000006f05b59d3b20000008a5eb9a5b726583a213c7e4de2403d2dfd42c8a600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044e2a4853a2a55eed44296e96ac21384858860ec77b2c3e06f2d82cbe24bc29993e5a520110000000000000000000000000000000000000000000000000de0b6b3a7640000
>> abi.decodeMultisend(multisendData)
[MultisendTransaction {
operation: 0,
to: 0x8A5eB9A5B726583a213c7e4de2403d2DfD42C8a6,
value: 0,
data: 0xe2a4853ae060499125866d3940796528a5be3e30632cf5c956aae07e9b72d89c96e053f100000000000000000000000000000000000000000000000006f05b59d3b20000
}, MultisendTransaction {
operation: 0,
to: 0x8A5eB9A5B726583a213c7e4de2403d2DfD42C8a6,
value: 0,
data: 0xe2a4853a2a55eed44296e96ac21384858860ec77b2c3e06f2d82cbe24bc29993e5a520110000000000000000000000000000000000000000000000000de0b6b3a7640000
}]
Each decoded transaction contains:
operation
: 0 for regular call, 1 for delegatecallto
: Target addressvalue
: ETH value in weidata
: Call data for the transaction
This can be combined with abi.decodeData
to decode the data of each transaction. For example:
>> abi.decodeMultisend(multisendData).map((d) >> (d, abi.decodeData(d.data)))
[(MultisendTransaction {
operation: 0,
to: 0x8A5eB9A5B726583a213c7e4de2403d2DfD42C8a6,
value: 0,
data: 0xe2a4853ae060499125866d3940796528a5be3e30632cf5c956aae07e9b72d89c96e053f100000000000000000000000000000000000000000000000006f05b59d3b20000
}, ("setUint(bytes32,uint256)", (0xe060499125866d3940796528a5be3e30632cf5c956aae07e9b72d89c96e053f1, 500000000000000000))
), (MultisendTransaction {
operation: 0,
to: 0x8A5eB9A5B726583a213c7e4de2403d2DfD42C8a6,
value: 0,
data: 0xe2a4853a2a55eed44296e96ac21384858860ec77b2c3e06f2d82cbe24bc29993e5a520110000000000000000000000000000000000000000000000000de0b6b3a7640000
}, ("setUint(bytes32,uint256)", (0x2a55eed44296e96ac21384858860ec77b2c3e06f2d82cbe24bc29993e5a52011, 1000000000000000000))
)]