Solidity – How to Pass Arbitrary Bytes to a Function in Remix (2017)

bytesremixsolidity

According to this question I could write a simple contract like:

contract SimpleStorage {
  bytes input;
  function setInput(bytes enterBytes){
    input = enterBytes;
  }
}

Using "0x1234" as a parameter in Remix "does not work" and stores "0x307831323334" in the storage array. If I change the code to bytes2 then everything works as intended with the same command. How can I do the same using a dynamic array?

contract SimpleStorage {
  bytes2 input;
  function setInput(bytes2 enterBytes){
    input = enterBytes;
  }
}

Best Answer

  1. You can pass bytes parameters in Remix or browser-solidity as the array of single bytes, for example ["0x00","0xaa", "0xff"] is equivalent to "0x00aaff"
  2. Do not know why, but the Remix IDE and browser-solidity interprets "0xaabb11..." as string. For development and testing purpose on private or test net you can use the code below. Function hexStrToBytes will do the conversion. You can use its result, as it is demonstrated in setInputFromHex function

code:

contract SimpleStorage 
{
    bytes input;

    function setInput(bytes enterBytes){
        input = enterBytes;
    }

    function getInput()
    returns (bytes)
    {
        return input;
    }

    function setInputFromHex(string hex_str)
    {
        input = hexStrToBytes(hex_str);
    }

    function hexStrToBytes(string hex_str) constant
    returns (bytes)
    {
        //Check hex string is valid
        if (bytes(hex_str)[0]!='0' ||
            bytes(hex_str)[1]!='x' ||
            bytes(hex_str).length%2!=0 ||
            bytes(hex_str).length<4)
            {
                throw;
            }

        bytes memory bytes_array = new bytes((bytes(hex_str).length-2)/2);

        for (uint i=2;i<bytes(hex_str).length;i+=2)
        {
            uint tetrad1=16;
            uint tetrad2=16;

            //left digit
            if (uint(bytes(hex_str)[i])>=48 &&uint(bytes(hex_str)[i])<=57)
                tetrad1=uint(bytes(hex_str)[i])-48;

            //right digit
            if (uint(bytes(hex_str)[i+1])>=48 &&uint(bytes(hex_str)[i+1])<=57)
                tetrad2=uint(bytes(hex_str)[i+1])-48;

            //left A->F
            if (uint(bytes(hex_str)[i])>=65 &&uint(bytes(hex_str)[i])<=70)
                tetrad1=uint(bytes(hex_str)[i])-65+10;

            //right A->F
            if (uint(bytes(hex_str)[i+1])>=65 &&uint(bytes(hex_str)[i+1])<=70)
                tetrad2=uint(bytes(hex_str)[i+1])-65+10;

            //left a->f
            if (uint(bytes(hex_str)[i])>=97 &&uint(bytes(hex_str)[i])<=102)
                tetrad1=uint(bytes(hex_str)[i])-97+10;

            //right a->f
            if (uint(bytes(hex_str)[i+1])>=97 &&uint(bytes(hex_str)[i+1])<=102)
                tetrad2=uint(bytes(hex_str)[i+1])-97+10;

            //Check all symbols are allowed
            if (tetrad1==16 || tetrad2==16)
                throw;

            bytes_array[i/2-1]=byte(16*tetrad1+tetrad2);
        }

        return bytes_array;
    }
}