4

I have a Solidity contract with functions like this:

function SetMessage (bytes32 key, bytes32 message) returns (bool success) {
    publicStruct[key].message = message;
    return true;
    }

    function GetMessage (bytes32 key) public constant returns (bytes32) {
    var message = publicStruct[key].message;
    return message;
    }

Then I'll use web3 to execute SetMessage and then call GetMessage after that's done:

var mystringmessage = 'some string over 32 characters in length that can seem to be up to 128 characters in length to be stored in bytes32'
var key = 'message key'

MyContract.deployed().then(function (instance) {
          contractInstance = instance
          return contractInstance.SetMessage(key, mystringmessage, { gas: 200000, from: web3.eth.accounts[0] })
        }).then(function () {
          return contractInstance.GetMessage.call(key)
        }).then(function (messages) {
          console.log('MSG: ' + messages[0])
        })

It seems that any string up to 128 characters can be stored in one bytes32 object from this. I'm also not converting the ordinary javascript string into bytes32 before executing SetMessage, or using web3.toAscii to convert the bytes32 back into a human readable string (as I always thought was necessary). Why should a single bytes32 object be able to store more than 32 characters?

1

bytes-x(1~32) can store a string, if the length of string is greater than x, then the part out of length will be dropped. It's a simple test contract

pragma solidity ^0.4.13;

contract Bytes32Test {

    bytes32 msg;

    function add(bytes32 _msg){
        msg = _msg;
    }

    function show() constant returns (bytes32){
        return msg;
    }

}

and i invoke add function by a param 'some string over 32 characters in length that can seem to be up to 128 characters in length to be stored in bytes32', and now we call show function, the result is

0x736f6d6520737472696e67206f76657220333220636861726163746572732069

the result is "some string over 32 characters i" if we convert it from hex to ascii.

> web3.toAscii("0x736f6d6520737472696e67206f76657220333220636861726163746572732069")
"some string over 32 characters i"

Hope it helps~

  • I understand that's how it works, I'm confused why in my example though calling GetMessage which returns bytes32 somehow returns a human readable string which can also be longer than 32 characters – ZhouW Aug 5 '17 at 2:48
  • I had test GetMessage function, it returns a hex encoded result because of return type being bytes32, not a string. If you expect return readable string type, as follows: ' function GetMessage (bytes32 key) public constant returns (string) { var message = publicStruct[key].message; return bytes32ToString(message); }' – BinGoBinBin Aug 5 '17 at 3:31
  • function bytes32ToString(bytes32 x) constant returns (string) { bytes memory bytesString = new bytes(32); uint charCount = 0; for (uint j = 0; j < 32; j++) { byte char = byte(bytes32(uint(x) * 2 ** (8 * j))); if (char != 0) { bytesString[charCount] = char; charCount++; } } bytes memory bytesStringTrimmed = new bytes(charCount); for (j = 0; j < charCount; j++) { bytesStringTrimmed[j] = bytesString[j]; } return string(bytesStringTrimmed); } – BinGoBinBin Aug 5 '17 at 3:33
0

I think it depends upon what you are storing in it. Say, a 64 bit word,

"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8"

If you pass that as a string (bytes32 word = "0x1c8...")then it is 64 bytes long and the 32 characters after may be truncated, but you if consider it as hex (bytes32 word = 0x1c8...), see the lack of quotes, then it will end up being exactly 32 bytes, as a digit in hex denotes a nibble, 2 digits denote a byte.

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.