ethereumjs-abi: Solidity packing doesn't support arrays

I have been trying to reproduce Solidity’s sha3 in Javascript, and have gotten everything to work with my own code except arrays. Once I found out about this library, I tried to use it for arrays, but I haven’t been able to get the same hash as Solidity produces yet. It would be great if you might be able to help me understand this better.

How would I generate the same sha3 hash using ethereumjs-abi as in this Solidity example?

contract Contract {
    function Test() constant returns(bytes32) {
        uint[] memory amounts = new uint[](2);
        amounts[0] = 1;
        amounts[1] = 2;

        bytes8[] memory tickers = new bytes8[](2);
        tickers[0] = "BTC";
        tickers[1] = "LTC";

        // 0x4282aea708b799612aa9d311309ef4b8eb1374cf0740c3e9d5914cb5ce9b93f2
        return sha3(amounts, tickers);
    }
}

My attempt gives an error of Cannot read property 1 of undefined:

abi.soliditySHA3(['uint[]', 'bytes8[]'], [[1,2], ['BTC', 'LTC']])

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Comments: 16 (10 by maintainers)

Most upvoted comments

For the time being (as @djrtwo explained) you can do the following:

contract GenHash {
    function getHash(string title, uint256 num, address[] addr, uint256 num2) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(title, num, addr, num2));
    }
}

and in JS…

function getHash(title, num, arr, num2) {
  let args = []
  arr.map((addr, index) => {
    args[index] = {t: 'bytes', v: web3.utils.leftPad(addr, 64)}
  })
  return web3.utils.soliditySha3(
    {t: 'string', v: title},
    {t: 'uint256', v: num},
    ...args,
    {t: 'uint256', v: num2}
  );
}

@alex-forshtat-tbk thanks, very helpful! I will try to use the “Update branch” function from GitHub and manually resolve conflicts in the next couple of days, since the original author of the PR is not responsive anymore (which is no wonder 😛).