[Ethereum] How to hash multiple values including array keccak256 Solidity v5.0.x and web3 ‘Autodetection of array types is not supported.’

hashsoliditysolidity-0.5.xweb3js

How can I receive the same hash in solidity and web3?
Multiple values where one is a multi dimensional array.

Solidity v0.5.x:

pragma solidity 0.5.6;
pragma experimental ABIEncoderV2;

contract Hash{

    uint256[][] public data;

    function append(uint _a, uint _b) public {
        data.push([_a, _b]);
    }

    function hash(uint256 _idx, string memory _b) public view returns(bytes32) {
        return keccak256(abi.encodePacked(data[_idx], _b));
    }
}

Solidity output:

decoded input   
{
     "uint256 _idx": "0",
     "string _b": "a"
}

 decoded output     
{
"0": "bytes32: 0x8385585c10cea4e82d9662964b0a952bc1ad925ded1aff4ab359eb38b6d23d11"
}

Web3:

truffle(development)> var arr = new Array(2);
truffle(development)> arr.push([1, 2]);
truffle(development)> web3.utils.soliditySha3(arr,"a")

Web3 output:

/Users/xxx/.nvm/versions/node/v8.9.4/lib/node_modules/truffle/build/cli.bundled.js:345535
        throw new Error('Autodetection of array types is not supported.');

I also tried

web3.utils.keccak256(
   web3.eth.abi.encodeParameters(["uint256[][]", "string"], [arr, "a"])
);

which provides a different hash.

Best Answer

Without an example is not easy to provide a specific answer, but I will try with a simple case.

Assuming a uint array. If you want to pass the multidimensional array as a parameter you need to use pragma experimental ABIencoderV2. Here I only pass one element of the array.

Solidity code:

uint[][] data;

function append(uint _a, uint _b) public {
    data.push([_a, _b]);
}

function hash(uint _idx, string memory _b) public view returns(bytes32) {
    return keccak256(abi.encodePacked(data[_idx], _b));
}

After append _a = 1 and _b = 2 for the first index.

data[0] = [1,2]

Probably you need to do some things with the array depending on the purpose of your code.

Web3 output:

truffle(development)> web3.utils.soliditySha3(1,2,"a")
'0x8385585c10cea4e82d9662964b0a952bc1ad925ded1aff4ab359eb38b6d23d11'

Solidity output:

decoded input   
{
     "uint256 _idx": "0",
     "string _b": "a"
}

 decoded output     
{
"0": "bytes32: 0x8385585c10cea4e82d9662964b0a952bc1ad925ded1aff4ab359eb38b6d23d11"
}
Related Topic