Использовать строковый тип или bytes32?

Каковы преимущества использования stringтипов данных bytes32для представления текстовых данных. Кажется, мой контракт сталкивается с исключением из газа, когда я переключаю структуры данных с bytes32на string.

Ответы (3)

Почему stringвместо bytes32?

Используйте stringдля строковых данных произвольной длины (UTF-8), длина которых превышает 32 байта. Фронтенды могут проще декодировать длинную строку, используя такие методы, как web3.toAscii или UTF-8 (когда проблемы устранены), вместо того, чтобы реализовывать логику декодирования UTF-8 серии файлов bytes32.

Из документов Solidity:

Как правило, используйте bytesдля необработанных байтовых данных stringпроизвольной длины и строковых данных произвольной длины (UTF-8). Если вы можете ограничить длину определенным количеством байтов, всегда используйте один из них bytes1, bytes32потому что они намного дешевле.

Строковые литералы также могут быть полезны или удобны:

Строковые литералы пишутся либо с двойными, либо с одинарными кавычками ("foo" или "bar")...

Строковые литералы поддерживают escape-символы, такие как \n, \xNN и \uNNNN. \xNN принимает шестнадцатеричное значение и вставляет соответствующий байт, а \uNNNN принимает кодовую точку Unicode и вставляет последовательность UTF-8.


Почему bytes32вместо string?

Ответ на вопрос Почему в примерах Solidity используется тип bytes32 вместо строки?

bytes32использует меньше газа, потому что он умещается в одном слове EVM и stringпредставляет собой тип с динамическим размером, который имеет текущие ограничения в Solidity (например, не может быть возвращен из функции в контракт).

Я не уверен, понял ли я последнее предложение - типы возвращаемых строк работают в текущем компиляторе Solidity.
@MikkoOhtamaa Акцент делается на контракт : я не думаю, что ethereum.stackexchange.com/a/3788/42 еще не поддерживается.
Итак, если у вас есть контролирующий контракт, и он обращается к данным из другого контракта, который возвращает текст, длина которого превышает 32 байта, вам нужно будет вернуть его в массиве bytes32?
@ethereal Звучит правильно, задайте размер массива, например bytes32[3]. Могут быть способы сборки, чтобы получить размер возвращаемых данных и избежать жестко заданного размера, например, контракты на github.com/ownage-ltd/ether-router .
Если контракт не может получить доступ к строковым переменным другого контракта, то что может? Может веб3? Что, если я хочу сохранить список или массив 60-символьных строк, но мне нужно будет получить к ним доступ из другого контракта или программы, как мне это сделать?
Если я знаю, что нужно сохранить, скажем, длинную строку 50, дешевле ли использовать два байта32 и разделить их или использовать байты/строку?
@ClementWalter Да, я думаю, что на два байта32 дешевле. Ваш интерфейс/пользовательский интерфейс должен выполнять разделение/объединение. Вы, вероятно, захотите протестировать оба, чтобы увидеть, что вы предпочитаете в целом.

Как сказано в другом посте, вы хотите использовать строки только для динамически распределяемых данных, иначе Byte32 будет работать лучше. Bytes32 также будет лучше в газе. Если вы хотите поиграть с этим, я сделал небольшую скрипку https://ethfiddle.com/70ipaEIFdk .

Байт использовал газ 21465

Струна использовала газ 21897

pragma solidity ^0.4.18;

contract SampleOverflow {
  string constant statictext = "HelloStackOverFlow";
  bytes32 constant byteText = "HelloStackOverFlow";
  function  getString() payable public  returns(string){
    return statictext;
  }

  function  getByte() payable public returns(bytes32){
    return byteText;
  }
}

Получить байтвведите описание изображения здесь

Получить строку https://ethfiddle.com/70ipaEIFdkвведите описание изображения здесь

эта скрипка не работает. Я думаю, что это связано с экранированными двойными кавычками. Я пытался удалить escape-символы, но eth fiddle тоже не верил. Вот ваш пример работы ethfiddle.com/SeXTGt-AWi

bytes32 означает строку с максимальной длиной 32. Она занимает меньше памяти, чем строка для той же длины строки.

Итак, когда ваши данные не превышают 32 байта (32 слова), используйте bytes32.

Если длина строки не определена, используйте только bytes.

также доступны byte8, byte16, byte32. Вы можете использовать любой в соответствии с условиями.

Спасибо за простой ответ, просто хочу, чтобы вы уточнили третье утверждение «Если длина строки не определена, используйте строку». в этом случае мы можем использовать байты вместо строки или байтов32, верно?
bytes32 может хранить до 32 букв (ASCII), если вам нужна большая длина, используйте String.
да, я вас понимаю, но мы можем использовать байты , а не byte32 , для хранения большей длины вместо строки?
о да, вы правы, извините, я обновляю ответ.
если просто оставить «байты», установлено ли для него определенное значение по умолчанию #? если да, то что это, это 'bytes32'?