1

I've learned you can batch multiple transactions into one transaction using contracts like multisend/multicall. This is useful for things like large airdrops.

However, what if we need to order the transactions? Eg. Trx 1 - approve contractA to use my tokens. Trx 2 - let contractA do use my tokens.

The above needs to ordered.. but Im not sure how this is done if both calls are merged into one transaction in one block?

Any idea how this will work? Is it random? Or if we put the calldata for trx1 first, before trx2, would it work somehow?

1 Answer 1

5

If you look at Gnosis-Safe's MultiSend contract, you'll notice that you decide in which order you want to execute the "sub"-transaction.

You need to encode each transaction you want to batch like this.

For an approve(...):

  • (1) operation (1 bytes): either 0x00 (for a call) or 0x01 (for a delegate call)
  • (2) to (20 bytes): the target address of the transaction (e.g: 0x6b175474e89094c44da98b954eedeac495271d0f)
  • (3) data_length (32 bytes): the length of the next field data (e.g: if the length of data is 68 bytes, that would be 0x0000000000000000000000000000000000000000000000000000000000000044)
  • (4) data (<data_length> bytes): the bytes code to execute the function against the contract to (e.g: for an approve call, that would be 0x095ea7b300000000000000000000000068b34cc833fb72a70ecdfaa5e0e4c7bd86bbfc45ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)

Which mean your first encoded sub-transaction will look like this

0x00dafea492d9c6733ae3d56b7ed1adb60692c98bc5000000000000000000000000000000000000000000000000000000000000003A0x095ea7b300000000000000000000000068b34cc833fb72a70ecdfaa5e0e4c7bd86bbfc45ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Repeat this step for the next sub-transaction you want to include.

For a transfer(...):

  • (1) operation (1 bytes): either 0x00 (for a call) or 0x01 (for a delegate call)
  • (2) to (20 bytes): the target address of the transaction (e.g: 0x6b175474e89094c44da98b954eedeac495271d0f)
  • (3) data_length (32 bytes): the length of the next field data (e.g: if the length of data is 68 bytes, that would be 0x0000000000000000000000000000000000000000000000000000000000000044)
  • (4) data (<data_length> bytes): the bytes code to execute the function against the contract to (e.g: for an approve call, that would be 0xa9059cbb000000000000000000000000823e309b1a730f8aa6b0ae7f9165abbf8b1950ae00000000000000000000000000000000000000000000003635c9ad45dea00000)

Which gives you an encoded version equals to

0x006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000044
a9059cbb000000000000000000000000823e309b1a730f8aa6b0ae7f9165abbf8b1950ae00000000000000000000000000000000000000000000003635c9ad45dea00000

If you want to batch both together, simply concatenate it (in one line):

0x
00dafea492d9c6733ae3d56b7ed1adb60692c98bc5000000000000000000000000000000000000000000000000000000000000003A0x095ea7b300000000000000000000000068b34cc833fb72a70ecdfaa5e0e4c7bd86bbfc45ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000823e309b1a730f8aa6b0ae7f9165abbf8b1950ae00000000000000000000000000000000000000000000003635c9ad45dea00000

Finally, this is the argument bytes transactions you need pass to the function multiSend to execute multiple transactions in one.

enter image description here

The order will be the same as the logic above

1
  • Amazing, will try that out. TY Greg
    – errichoi
    Commented Oct 6, 2022 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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