5

While trying to upload a public key on Ethereum, I have faced a problem.

Given the following code in Solidity browser, it seems that I can only insert string values (using the browser compiler). For example, when I "create" and "set" values as "0x1234", it outputs:

"0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000063078313233340000000000000000000000000000000000000000000000000000"

What I want was something like "0x1234" but instead of that it interprets as a string. The work around is use bytesN where N is actual number of bytes. But then it becomes a static. Could anyone help?

contract SimpleStorage {
    bytes storedData;
    function set(bytes x) {
        storedData = x;
    }
    function get() constant returns (bytes retVal) {
        return storedData;
    }
}

Yes, instead of the above code, I can do as the following where I set bytes to bytes2. Then I can put "0x12", which would output "0x12". But Can I do it without being static?

contract SimpleStorage
{
    bytes2 storedData;
    function set(bytes2 x) {
        storedData = x;
    }
    function get() constant returns (bytes2 retVal) {
        return storedData;
    }
}
jrbedard
  • 524
  • 1
  • 6
  • 15
Phillip
  • 61
  • 1
  • 2
  • You can have an up to date look at literal syntax for Solidity and Vyper here.

    This includes the hex literal syntax for byte/string types as written below.

    – Peteris Dec 25 '19 at 15:31

4 Answers4

5

I'm not sure the other responses answered this question and I came upon it recently.

Per the Solidity docs you can now cast a fixed hex value to bytes, e.g.

bytes memory foo = hex"01";

will give you foo == 0x01.

BEWARE

This is not very well documented yet: the new syntax for hardcoding hex values in solidity has a major pitfall that is guaranteed to send some smart contracts crashing into the wall:

  • the new syntax (bytes8 b = hex"1234") pads with zeroes to the right.
  • the old syntax (uint64 u = 0x1234), pads zeroes to the left.

Below is a snippet that shows you the mess you can get if you use the new syntax as drop in for the old:

function showAddrFromUint() public pure returns (address r){
    uint160 t = 0x12345678ff0102;
    r = address(t);
}
// WILL RETURN: address: r 0x0000000000000000000000000012345678ff0102
// execution cost : 264 gas

function showAddrFromBytes() public pure returns (address r){
    bytes20 t = hex"12345678ff0102";
    r = address(t);
}
//WILL RETURN: address: r 0x12345678Ff010200000000000000000000000000
// execution cost : 226 gas
blackscale
  • 383
  • 2
  • 8
ethereum_alex
  • 803
  • 1
  • 9
  • 19
2

try to use uint instead :

contract Ballot {
 uint public  key = 0x123A1; // A hex constant

}

you will get : "0x00000000000000000000000000000000000000000000000000000000000123a1"

Badr Bellaj
  • 18,780
  • 4
  • 58
  • 75
  • Thanks! but the reason I wanted to use bytes was 1) dynamic 2)more intuitive to use bytes instead of int. – Phillip Oct 13 '16 at 00:23
  • In that case, browser compiler has a limitation that I can express hex in bytesN while I cannot express hex in bytes? – Phillip Oct 13 '16 at 00:24
1

Solidity code to convert bytes to hex bytes:

function toHex(bytes memory data) public pure returns(bytes memory res) {
    res = new bytes(data.length * 2);
    bytes memory alphabet = "0123456789abcdef";
    for (uint i = 0; i < data.length; i++) {
        res[i*2 + 0] = alphabet[uint256(uint8(data[i])) >> 4];
        res[i*2 + 1] = alphabet[uint256(uint8(data[i])) & 15];
    }
}
k06a
  • 3,016
  • 2
  • 21
  • 35
1

To create a binary out of your hex string, use web3.toAscii(); and to convert back to hex, use web3.toHex(). Like so:

// In Javascript
var txHash = simple.set(web3.toAscii("0x1234"), { from: account });
// And to retrieve
var returned = simple.get().toHex();