1

When I reviewed the BEC attack, I found the position of each parameters value in real transaction was not corresponding in to definition of function in smart contract.

The exploit transaction is at:

https://etherscan.io/tx/0xad89ff16fd1ebe3a0a7cf4ed282302c06626c1af33221ebe0d3a470aba4a660f.

In transaction inputdata, the address[] value is put at the second, but in function definition, it's in the first. Another question is why the value of _value take three values.

So is there any rule for setting 'inputdata' value position in transaction?

1

Transactions are encoded based on the Contract ABI Specification. It is hard to get through, but these docs have all the answers to your question.


The transaction in question is passing in two parameters: a dynamic array of addresses (_receivers) and a static uint256 (_value). When encoding the parameters, the EVM looks to see if the parameters are static or dynamic.

Static parameters are encoded in a fairly straightforward manner--they are converted to their hex representation and then concatenated into the input data hex string.

Dynamic values are more interesting. Use this section of the docs to fully understand, but the idea is that the encoded data is the location of the data. The encoded data itself is then concatenated to the end of the input data hex string, after all of the dynamic types. For dynamic types, the length of the parameter is then included, followed by the data itself.

Breaking down the transaction you posted:

0x83f12fec000000000000000000000000000000000000000000000000000000000000004080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b4d30cac5124b46c2df0cf3e3e1be05f421190330000000000000000000000000e823ffe018727585eaf5bc769fa80472f76c3d7

0x83f12fec

This is the method ID of the function called (in this case, batchTransfer(address[] , uint256))

0000000000000000000000000000000000000000000000000000000000000040

This is the location of the first (dynamic) parameter. This is the location where _receivers lives, but is not the data itself.

8000000000000000000000000000000000000000000000000000000000000000

This is the _value parameter that was sent with the transaction.

0000000000000000000000000000000000000000000000000000000000000002

This is the length of the dynamic _receivers. In this case, there were 2 receivers.

000000000000000000000000b4d30cac5124b46c2df0cf3e3e1be05f42119033

The first receiver.

0000000000000000000000000e823ffe018727585eaf5bc769fa80472f76c3d7

The second receiver.

  • Thanks very much! It totally addresses my problems! – Jocelyn Mar 4 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.