Конкатенация строк в прочности?
как объединить строки в целостности?
var str = 'asdf'
var b = str + 'sdf'
похоже, не работает.
Я просмотрел документацию (https://github.com/ethereum/wiki/wiki/Solidity-Tutorial#elementary-types-value-types), и о конкатенации строк не упоминается.
Но утверждается, что он работает с точкой ('.')?
"[...] a mapping key k is located at sha3(k . p) where . is concatenation."
Не сработал у меня тоже..:/
Ответы
Ответ 1
Вы не можете конкатенировать строки. Вы также не можете проверить равно (str0 == str1
). Тип строки был недавно добавлен обратно на язык, поэтому, вероятно, потребуется некоторое время, пока все это не сработает. То, что вы можете сделать (которое они недавно добавили), - это использовать строки как ключи для сопоставлений.
Конкатенация, на которую вы указываете, - это то, как адреса памяти вычисляются на основе типов полей и т.д., но обрабатываются компилятором.
Ответ 2
Ответ из Ethereum Stack Exchange:
A библиотека может использоваться, например:
import "github.com/Arachnid/solidity-stringutils/strings.sol";
contract C {
using strings for *;
string public s;
function foo(string s1, string s2) {
s = s1.toSlice().concat(s2.toSlice());
}
}
Используйте приведенное выше для быстрого теста, которое вы можете изменить для своих нужд.
Так как конкатенация строк должна выполняться вручную на данный момент, и при этом в контракте может потребляться ненужный газ (должна быть назначена новая строка а затем каждый написанный символ), стоит ли учитывать, какой вариант использования требует конкатенации строк?
Если DApp можно записать таким образом, чтобы интерфейс конкатенировал строки, а затем передал его в контракт для обработки, это может быть лучшим дизайном.
Или, если контракт хочет хэшировать одну длинную строку, обратите внимание, что все встроенные хэширующие функции в Solidity (sha256
, ripemd160
, sha3
) принимают переменное количество аргументов и будут выполнять конкатенация перед вычислением хеша.
Ответ 3
Вам нужно сделать это вручную сейчас
Solidity не обеспечивает встроенную конкатенацию строк и сравнение строк.
Тем не менее, вы можете найти библиотеки и контракты, которые реализуют конкатенацию и сравнение строк.
StringUtils.sol библиотека реализует сравнение строк.
Oraclize contract srtConcat function реализует конкатенацию строк.
Если вам нужна конкатенация для получения хэша строки результата, обратите внимание, что в Solidity есть встроенные хэширующие функции: sha256
, ripemd160
, sha3
. Они принимают переменное количество аргументов и выполняют конкатенацию перед вычислением хеша.
Ответ 4
Вот еще один способ объединения строк в Солидности. Это также показано в этом руководстве:
pragma solidity ^0.4.19;
library Strings {
function concat(string _base, string _value) internal returns (string) {
bytes memory _baseBytes = bytes(_base);
bytes memory _valueBytes = bytes(_value);
string memory _tmpValue = new string(_baseBytes.length + _valueBytes.length);
bytes memory _newValue = bytes(_tmpValue);
uint i;
uint j;
for(i=0; i<_baseBytes.length; i++) {
_newValue[j++] = _baseBytes[i];
}
for(i=0; i<_valueBytes.length; i++) {
_newValue[j++] = _valueBytes[i++];
}
return string(_newValue);
}
}
contract TestString {
using Strings for string;
function testConcat(string _base) returns (string) {
return _base.concat("_Peter");
}
}
Ответ 5
Вы можете использовать abi.encodePacked
:
bytes memory b;
b = abi.encodePacked("hello");
b = abi.encodePacked(b, " world");
string memory s = string(b);
// s == "hello world"
Ответ 6
Приведенные выше примеры не работают идеально.
Например, попробуйте указать эти значения
["10", "11", "12", "13", "133"], и вы получите ["1", "1", "1", "1", "13"]
Есть какая-то ошибка.
И вам также не нужно использовать библиотеку для этого. Потому что библиотека очень большая для этого.
Используйте этот метод:
function concat(string _a, string _b) constant returns (string){
bytes memory bytes_a = bytes(_a);
bytes memory bytes_b = bytes(_b);
string memory length_ab = new string(bytes_a.length + bytes_b.length);
bytes memory bytes_c = bytes(length_ab);
uint k = 0;
for (uint i = 0; i < bytes_a.length; i++) bytes_c[k++] = bytes_a[i];
for (i = 0; i < bytes_b.length; i++) bytes_c[k++] = bytes_b[i];
return string(bytes_c);
}