坚固的字符串连接?
String concatenation in solidity?
如何在 solidity 中连接字符串?
var str = 'asdf'
var b = str + 'sdf'
好像不行..
我查了下the documentation,关于字符串连接的内容不多。
但据说它可以与点 ('.') 一起使用?
"[...] a mapping key k is located at sha3(k . p) where . is concatenation."
我也没有成功.. :/
您不能连接字符串。您还不能检查等于 (str0 == str1
)。字符串类型最近才重新添加回该语言,因此可能需要一段时间才能完成所有这些工作。您可以做的(他们最近添加的)是使用字符串作为映射的键。
您所指的串联是如何根据字段类型等计算存储地址,但这是由编译器处理的。
You have to do it manually for now
Solidity 不提供内置的字符串连接和字符串比较。
但是,您可以找到实现字符串连接和比较的库和合约。
StringUtils.sol 库实现字符串比较。
Oraclize contract srtConcat function 实现字符串连接。
如果您需要连接以获得结果字符串的哈希值,请注意 Solidity 中有内置的哈希函数:sha256
、ripemd160
、sha3
。他们采用可变数量的参数并在计算哈希之前执行连接。
的回答
可以用一个library,例如:
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());
}
}
将以上内容用于 quick test,您可以根据需要进行修改。
由于concatenating strings needs to be done manually for now,并且在合约中这样做可能会消耗不必要的gas(必须分配新字符串,然后写入每个字符),值得考虑需要字符串连接的用例是什么?
如果DApp可以写成让前端连接字符串,然后将其传递给合约进行处理,这可能是一个更好的设计。
或者,如果合约想要散列单个长字符串,请注意 Solidity 中的所有内置散列函数(sha256
、ripemd160
、sha3
)都采用可变数量的参数,并将在计算哈希之前执行连接。
这是在 Solidity 中连接字符串的另一种方法。也显示在这个tutorial:
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");
}
}
以上示例并不完美。
例如,尝试连接这些值
["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);
}
您可以利用 abi.encodePacked
:
bytes memory b;
b = abi.encodePacked("hello");
b = abi.encodePacked(b, " world");
string memory s = string(b);
// s == "hello world"
我用这个方法来连接字符串。希望这对您有所帮助
function cancat(string memory a, string memory b) public view returns(string memory){
return(string(abi.encodePacked(a,"/",b)));
}
您可以使用 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;
}
}
你可以用 solidity 的低级函数很容易地做到这一点
abi.encodePacked(str,b)
要记住的一件重要事情是,首先将其转换为字符串,即:
string(abi.encodePacked(str, b))
您的函数将 return
return string(abi.encodePacked(str, b));
它很简单,也很省油:)
与 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')的结果请看下面的截图
Solidity 不提供连接字符串的本机方法,因此我们可以使用 abi.encodePacked()。详情请参考Doc Link
// 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));
}
}
您可以使用此方法 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
}
在 Solidity 0.8.4 版本之后,您现在可以在不使用 encodePacked() 的情况下连接字节
查看问题:here
//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"
}
}
如何在 solidity 中连接字符串?
var str = 'asdf'
var b = str + 'sdf'
好像不行..
我查了下the documentation,关于字符串连接的内容不多。
但据说它可以与点 ('.') 一起使用?
"[...] a mapping key k is located at sha3(k . p) where . is concatenation."
我也没有成功.. :/
您不能连接字符串。您还不能检查等于 (str0 == str1
)。字符串类型最近才重新添加回该语言,因此可能需要一段时间才能完成所有这些工作。您可以做的(他们最近添加的)是使用字符串作为映射的键。
您所指的串联是如何根据字段类型等计算存储地址,但这是由编译器处理的。
You have to do it manually for now
Solidity 不提供内置的字符串连接和字符串比较。
但是,您可以找到实现字符串连接和比较的库和合约。
StringUtils.sol 库实现字符串比较。
Oraclize contract srtConcat function 实现字符串连接。
如果您需要连接以获得结果字符串的哈希值,请注意 Solidity 中有内置的哈希函数:sha256
、ripemd160
、sha3
。他们采用可变数量的参数并在计算哈希之前执行连接。
可以用一个library,例如:
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());
}
}
将以上内容用于 quick test,您可以根据需要进行修改。
由于concatenating strings needs to be done manually for now,并且在合约中这样做可能会消耗不必要的gas(必须分配新字符串,然后写入每个字符),值得考虑需要字符串连接的用例是什么?
如果DApp可以写成让前端连接字符串,然后将其传递给合约进行处理,这可能是一个更好的设计。
或者,如果合约想要散列单个长字符串,请注意 Solidity 中的所有内置散列函数(sha256
、ripemd160
、sha3
)都采用可变数量的参数,并将在计算哈希之前执行连接。
这是在 Solidity 中连接字符串的另一种方法。也显示在这个tutorial:
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");
}
}
以上示例并不完美。 例如,尝试连接这些值
["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);
}
您可以利用 abi.encodePacked
:
bytes memory b;
b = abi.encodePacked("hello");
b = abi.encodePacked(b, " world");
string memory s = string(b);
// s == "hello world"
我用这个方法来连接字符串。希望这对您有所帮助
function cancat(string memory a, string memory b) public view returns(string memory){
return(string(abi.encodePacked(a,"/",b)));
}
您可以使用 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;
}
}
你可以用 solidity 的低级函数很容易地做到这一点
abi.encodePacked(str,b)
要记住的一件重要事情是,首先将其转换为字符串,即:
string(abi.encodePacked(str, b))
您的函数将 return
return string(abi.encodePacked(str, b));
它很简单,也很省油:)
与 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')的结果请看下面的截图Solidity 不提供连接字符串的本机方法,因此我们可以使用 abi.encodePacked()。详情请参考Doc Link
// 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));
}
}
您可以使用此方法 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
}
在 Solidity 0.8.4 版本之后,您现在可以在不使用 encodePacked() 的情况下连接字节
查看问题:here
//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"
}
}