Конкатенация строк в прочности?

как объединить строки в целостности?

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