I have a function

function multiERC20TransferTightlyPacked
        ERC20 _token,
        bytes32[] _addressesAndAmounts
    ) public
        for (uint i = 0; i < _addressesAndAmounts.length; i++) {
            address to = address(_addressesAndAmounts[i] >> 96);
            uint amount = uint(uint96(_addressesAndAmounts[i]));
            _safeERC20Transfer(_token, to, amount);
            MultiERC20Transfer(msg.sender, to, amount, _token);

For exmple I want to call this function with _addressesAndAmounts of 0x2970c57fe5264caf1689bc129b41bd7ddf06b4f7 10, and 0x63F69E69857dc198AE63C1BeEe26803c50C00813 10, how can I pass these as parameter to call this function?

  const multisendTx = await contract.methods. multiERC20TransferTightlyPacked(tokenAddress, addressesAmounts).encodeABI();

How should I make the addressesAmounts?

on the solidity code it says:

address to = address(_addressesAndAmounts[i] >> 96);
uint amount = uint(uint96(_addressesAndAmounts[i]));

I don't know what does >> 96 mean how does it work in js?

  • Please specify your web3.js version. – goodvibration Apr 23 at 7:43
  • Also, from your code, it doesn't look like you need a bytes32 to begin with, since uint256 seems reasonable enough here. – goodvibration Apr 23 at 7:44
  • I'm using web3@1.2.6 – bbnn Apr 23 at 7:44
  • what do you mean by that uint256 is reasonable enough? – bbnn Apr 23 at 7:45
  • Is this function in your own contract, or in someone else's contract that you need to interact with? – goodvibration Apr 23 at 7:47

You can use this function:

const Web3 = require("web3");

const toBN = Web3.utils.toBN;

function getArray(items) {
    return items.map(item => "0x" + toBN(item.address).shln(96).or(toBN(item.amount)).toString(16));

For example:

const array = getArray([
    {address: "0x2970c57fe5264caf1689bc129b41bd7ddf06b4f7", amount: "10"},
    {address: "0x63F69E69857dc198AE63C1BeEe26803c50C00813", amount: "10"},


The value of amount should be at most 2 ^ 96 - 1 of course.

Its type is string because it can be larger than 2 ^ 53 - 1 (Number.MAX_SAFE_INTEGER).

| improve this answer | |
  • oh so, basically it needs an array of address/amount object, thank you very much, I will try this. and get back to you. – bbnn Apr 23 at 8:07
  • @bbnn: No! The contract function takes an array of bytes32 elements. I gave you a JS helper function to create that array. – goodvibration Apr 23 at 8:08
  • ok, so the array is the addressesAmounts right – bbnn Apr 23 at 8:09
  • It's still the same... The transaction got executed successfully with 0 amount value, but reverted with non-0 amount.. I wonder what is wrong.. is there anyway to debug these between executed and execution failure event logs? executed: kovan.etherscan.io/tx/… reverted: kovan.etherscan.io/tx/… – bbnn Apr 23 at 9:16
  • @bbnn: Same as what? You asked how to pass a proper input to your contract function, and I gave you an answer. What has that got to do with whether or not the function reverts for some input? There is no such context in your question relating for specific input behavior of the function. If you have a revert issue on some specific input, then I auggest that you post it as a separate question. – goodvibration Apr 23 at 9:18

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.