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))
)]