3

Solidity byte32 return different value in web3, remix browser compiler and ethereum wallet

In the contract, I have just added byte32 values and return it but in the web3 api, remix browser compiler and ethereum wallet showing different value and index at return time.

Ethereum wallet showing exact data with 0x

Remix browser compiler showing a different value

Web3 api showing different data and index

Contract :

pragma solidity ^0.4.11;

contract ABC{

    struct Data{
        bytes32 data;
        bytes32 data2;
        bytes32 data3;
        bytes32 data4;
        bytes32 data5;
    }
    mapping(uint => Data) public metaData;

    function ABC(){

    }

    function addData(bytes32 data,
        bytes32 data2,
        bytes32 data3,
        bytes32 data4,
        bytes32 data5){
        metaData[0]=Data(data,data2,data3,data4,data5);
    }

    function getData() returns(bytes32,bytes32,bytes32,bytes32,bytes32){
        return (metaData[0].data,metaData[0].data2,metaData[0].data3,metaData[0].data4,metaData[0].data5);
    }
}

Input Data : "d4967590eb024589dfb6b9e48a576eb49ebc19d764b0d1d67dc21975e7258e97","1","1","1","065e0be95fb43db528a20ba65c0e575e33cd4a9e1ca089dba4efff24596e8553"

In Remix Solidity Browser enter image description here

In Ethereum Wallet enter image description here

In Web3.js enter image description here enter image description here enter image description here

3

This problem is caused because javascript doesn't have a native bytes32 type. And the ambiguity of interpreting strings as bytes32 values.

If you want to avoid troubles you have to prefix hexadecimal strings with "0x" and complete to 64 characters padding with zeros where neccesary.

Like this for example:

["0xd4967590eb024589dfb6b9e48a576eb49ebc19d764b0d1d67dc21975e7258e97",
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x065e0be95fb43db528a20ba65c0e575e33cd4a9e1ca089dba4efff24596e8553"]

Explaining the problems:

  • When you pass the string "d4967590eb024589dfb6b9e48a576eb49ebc19d764b0d1d67dc21975e7258e97" without "0x" in front it be interpreted as raw 64 bytes. Leading to the exadecimal string "64343936373539306562303234353839646662366239653438613537366562343965626331396437363462306431643637646332313937356537323538653937". Which is the result show in your web3.js example. Another more serious problem here is that the first parameter is not truncated to 32 bytes but instead slips to the second parameter pushing the other parameters. This happens when you do not validate data.

  • If you pass the value 1 and the parameters formatter is expecting a string javascript will happily interpret your number as a string and we will have two cases:

    • It get interpreted as a raw string 0x31 is the ascii value of character '1'. It will fill with '0' to get the 32 bytes, or 64 hexadecimal digits giving '0x3100000000000000000000000000000000000000000000000000000000000000' which is the bug show in the Remix example.
    • It is interpreted as an hexadecimal string and it will fill '0' to get 32 bytes or 64 hexadecimal digits. Which gives '0x1000000000000000000000000000000000000000000000000000000000000000' the result in your Ethereum Wallet example.

If you want to avoid problems just prefix with "0x" and specify the full 64 hexadecimal digits.

  • Perfect answer. it's working fine. – comeback4you Jul 26 '17 at 3:09

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.