Почему я могу хранить более 32 символов в байтах32?

У меня есть контракт Solidity с такими функциями:

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;
    }

Затем я буду использовать web3 для выполнения, SetMessageа затем позвоню GetMessageпосле того, как это будет сделано:

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])
        })

Кажется, что любая строка до 128 символов может храниться в одном объекте bytes32 из этого. Я также не преобразовываю обычную строку javascript в bytes32 перед выполнением SetMessageили использую web3.toAsciiдля преобразования bytes32 обратно в удобочитаемую строку (как я всегда считал необходимым). Почему один объект bytes32 должен хранить более 32 символов?

Ответы (2)

bytes-x (1 ~ 32) может хранить строку, если длина строки больше x, то часть длины будет удалена . Это простой тестовый контракт

pragma solidity ^0.4.13;

contract Bytes32Test {

    bytes32 msg;

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

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

}

и я вызываю функцию добавления с помощью параметра «некоторая строка длиной более 32 символов, которая может иметь длину до 128 символов для хранения в байтах32», и теперь мы вызываем функцию показа, результат

0x736f6d6520737472696e67206f76657220333220636861726163746572732069

результатом будет «некоторая строка более 32 символов i», если мы преобразуем ее из шестнадцатеричного в ascii.

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

Надеюсь поможет~

Я понимаю, как это работает, я не понимаю, почему в моем примере вызов GetMessage, который возвращает bytes32, каким-то образом возвращает удобочитаемую строку, которая также может быть длиннее 32 символов.
У меня была тестовая функция GetMessage, она возвращает результат в шестнадцатеричном кодировании, потому что тип возвращаемого значения - bytes32, а не строка. Если вы ожидаете вернуть удобочитаемый строковый тип, как показано ниже: ' функция GetMessage (bytes32 key) public константа возвращает (string) { var message = publicStruct[key].message; вернуть bytes32ToString (сообщение); }'
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); }

Я думаю, это зависит от того, что вы храните в нем. Скажем, 64-битное слово,

"0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8"

Если вы передадите это как строку , (bytes32 word = "0x1c8...")то она будет иметь длину 64 байта, а 32 символа после нее могут быть усечены, но если вы считаете ее шестнадцатеричной (bytes32 word = 0x1c8...), видите отсутствие кавычек, тогда она будет ровно 32 байта, как цифра в hex обозначает полубайт, 2 цифры обозначают байт.