ethereumjs-abi
ethereumjs-abi copied to clipboard
Formatting dynamic bytes differs from web3.js
This is more of a question than an issue, but maybe it's an issue. A user informed that when they called a contract function that took in a bytes input, they were getting different results between mycrypto.com and etherscan.com. After some digging in, I determined that we (mycrypto) are using ethereumjs-abi, and etherscan is using web3.js. The way the two encode the same bytes argument seems to be very different:
ethereumjs-abi bytes encoder: https://github.com/ethereumjs/ethereumjs-abi/blob/master/lib/index.js#L136
web3.js bytes encoder: https://github.com/ethereum/web3.js/blob/develop/lib/solidity/formatters.js#L65
Example input:
0xcf2fee595da8d52a6431bead9531b45a33f39db1036cf4fc21018369a93613d43d6f447643bed210ae8b6bac283dadb05a9255db63d7bdaa6662eeaec0bc78d701
ethereumjs-abi output via abi.rawEncode(['bytes'], [input]).toString('hex'):
0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008430786366326665653539356461386435326136343331626561643935333162343561333366333964623130333663663466633231303138333639613933363133643433643666343437363433626564323130616538623662616332383364616462303561393235356462363364376264616136363632656561656330626337386437303100000000000000000000000000000000000000000000000000000000
web3.js output via SolidityCoder.encodeParam('bytes', input):
00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041cf2fee595da8d52a6431bead9531b45a33f39db1036cf4fc21018369a93613d43d6f447643bed210ae8b6bac283dadb05a9255db63d7bdaa6662eeaec0bc78d70100000000000000000000000000000000000000000000000000000000000000
Please let me know if I've made a mistake in how the inputs should be structured, or the output should be converted from a buffer that leads to these differences. Thanks!
@axic Pretty please :D!
Also finding this problem! In my contract I have
return abi.encode(
PARTY_TYPEHASH, // bytes32
party.kind, // bytes4
party.wallet, // address
party.token, // address
party.data // bytes
);
Which returns
0xaa1c41c4152144cc047c6b26968e6626d8206d1f7209ceee5fbec44606c0175336372b070000000000000000000000000000000000000000000000000000000000000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
web3.eth.abi.encodeParameters() returns the same result as the contract, whereas ethereumjs-abi returns an incorrect encoding of the bytes.
web3.eth.abi.encodeParameters() gives me:
0xaa1c41c4152144cc047c6b26968e6626d8206d1f7209ceee5fbec44606c0175336372b070000000000000000000000000000000000000000000000000000000000000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
ethereumjs-abi gives me:
0xaa1c41c4152144cc047c6b26968e6626d8206d1f7209ceee5fbec44606c0175336372b070000000000000000000000000000000000000000000000000000000000000000000000000000000090f8bf6a479f320ead074411a4b0e7944ea8c9c1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000042307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030000000000000000000000000000000000000000000000000000000000000