20

我如何在solidity中连接字符串?

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."

对我也没有用..:/

4

13 回答 13

24

来自以太坊 Stack Exchange 的回答:

可以使用库,例如​​:

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 可以编写成前端连接字符串,然后将其传递给合约进行处理,这可能是一个更好的设计。

sha256或者,如果合约想要散列单个长字符串,请注意 Solidity ( , ripemd160, )中的所有内置散列函数都sha3采用可变数量的参数,并将在计算散列之前执行连接。

于 2016-05-29T11:50:50.430 回答
16

你不能连接字符串。您也不能检查等于(str0 == str1)。字符串类型是最近才重新添加到语言中的,因此可能需要一段时间才能完成所有这些工作。您可以做的(他们最近添加的)是使用字符串作为映射的键。

您指向的连接是如何根据字段类型等计算存储地址,但这由编译器处理。

于 2015-08-26T18:58:45.360 回答
11

这是在 Solidity 中连接字符串的另一种方法。本教程中也显示了它:

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");
    }
}
于 2018-02-27T17:28:11.450 回答
8

你现在必须手动完成

Solidity 不提供内置的字符串连接和字符串比较。
但是,您可以找到实现字符串连接和比较的库和协定。

StringUtils.sol库实现字符串比较。
Oraclize 合约 srtConcat 函数实现字符串连接。

如果您需要连接来获取结果字符串的哈希,请注意 Solidity 中有内置的哈希函数:sha256, ripemd160, sha3。它们采用可变数量的参数并在计算哈希之前执行连接。

于 2016-04-08T13:49:39.920 回答
5

您可以利用abi.encodePacked

bytes memory b;

b = abi.encodePacked("hello");
b = abi.encodePacked(b, " world");

string memory s = string(b);
// s == "hello world"
于 2019-08-16T21:57:56.997 回答
2

您可以使用solidity的低级功能非常轻松地做到这一点 abi.encodePacked(str,b)

要记住的重要一点是,首先将其类型转换为字符串,即: string(abi.encodePacked(str, b))

你的函数将返回

return string(abi.encodePacked(str, b));

它既简单又省气:)

于 2021-10-04T07:47:32.447 回答
1

我使用这种方法来连接字符串。希望这会有所帮助

function cancat(string memory a, string memory b) public view returns(string memory){
        return(string(abi.encodePacked(a,"/",b)));
    }
于 2021-01-19T05:00:59.400 回答
1

Solidity 不提供连接字符串的本地方式,因此我们可以使用 abi.encodePacked()。更多信息请参考文档链接

// SPDX-License-Identifier: GPL-3.0

    pragma solidity >=0.5.0 <0.9.0;


   contract AX{
      string public s1 = "aaa";
      string public s2 = "bbb";
      string public new_str;
 
      function concatenate() public {
         new_str = string(abi.encodePacked(s1, s2));
       } 
    }
于 2021-12-07T17:10:05.517 回答
0

上面的例子并不完美。例如,尝试连接这些值

["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);
}
于 2019-08-15T13:41:02.327 回答
0

您可以使用 ABI 编码器执行此操作。Solidity 不能自然地连接字符串,因为它们是动态大小的。您必须将它们散列到 32 字节。

pragma solidity 0.5.0;
pragma experimental ABIEncoderV2;


contract StringUtils {

    function conc( string memory tex) public payable returns(string 
                   memory result){
        string memory _result = string(abi.encodePacked('-->', ": ", tex));
        return _result;
    }

}
于 2021-04-04T20:30:34.657 回答
0

与 Python 和 JavaScript 等语言相比,在 Solidity 中没有直接的方法可以做到这一点。我会做类似下面的事情来连接两个字符串:

//SPDX-License-Identifier: GPL-3.0
 
pragma solidity >=0.7.0 < 0.9.0;

contract test {
    function appendStrings(string memory string1, string memory string2) public pure returns(string memory) {
        return string(abi.encodePacked(string1, string2));
    }
}

请参阅下面的屏幕截图,了解在 Remix Ethereum IDE 中连接两个字符串('asdf' 和 'sdf')的结果。

在此处输入图像描述

于 2021-11-11T17:19:36.510 回答
0

您可以使用这种方法来concat检查equal字符串。


// concat strgin
string memory result = string(abi. encodePacked("Hello", "World"));


// check qual
if (keccak256(abi.encodePacked("banana")) == keccak256(abi.encodePacked("banana"))) {
  // your logic here
}
于 2022-02-04T06:50:01.207 回答
0

在 Solidity 0.8.4 版本之后,您现在可以在不使用 encodePacked() 的情况下连接字节

查看问题:这里

//SPDX-License-Identifier: GPT-3
pragma solidity >=0.8.4;

library Strings {
    
    function concat(string memory a, string memory b) internal pure returns (string memory) {
        return string(bytes.concat(bytes(a),bytes(b)));
    }
}

用法:

contract Implementation {
    using Strings for string;

    string a = "first";
    string b = "second";
    string public c;
    
    constructor() {
        c = a.concat(b); // "firstsecond"
    }
}
于 2022-02-04T13:43:56.397 回答