32

I'm trying to concatenate two strings in solidity.

I tried with + or . but neither option works. There is not much documentation on string concatenation yet. Is it even possible?

If not, can I insert variables into strings?

30

You can do that in Solidity by copying each byte of the input strings to the output one.

You can find an implementation of this in oraclizeAPI for example (function strConcat).

The code is pretty much the following:

function strConcat(string _a, string _b, string _c, string _d, string _e) internal returns (string){
    bytes memory _ba = bytes(_a);
    bytes memory _bb = bytes(_b);
    bytes memory _bc = bytes(_c);
    bytes memory _bd = bytes(_d);
    bytes memory _be = bytes(_e);
    string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);
    bytes memory babcde = bytes(abcde);
    uint k = 0;
    for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];
    for (i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];
    for (i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];
    for (i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];
    for (i = 0; i < _be.length; i++) babcde[k++] = _be[i];
    return string(babcde);
}

function strConcat(string _a, string _b, string _c, string _d) internal returns (string) {
    return strConcat(_a, _b, _c, _d, "");
}

function strConcat(string _a, string _b, string _c) internal returns (string) {
    return strConcat(_a, _b, _c, "", "");
}

function strConcat(string _a, string _b) internal returns (string) {
    return strConcat(_a, _b, "", "", "");
}
  • 1
    Nice. Looks like you provide other helpers too in your link. Didn't see any examples yet in the repo, but I assume there would be some examples where it's essential for someone to use strConcat on-chain? – eth Feb 10 '16 at 5:37
20

Optimized for low gas-consumption

The ethereum community has implemented some ABI encoding functions which can be accessed natively without having to call another contract. This is how you could append a string to another with ABI encoding:

function append(string a, string b, string c, string d, string e) internal pure returns (string) {

    return string(abi.encodePacked(a, b, c, d, e));

}

For demonstration, I called both functions, this one and the one used in the oraclizeAPI contract as proposed earlier, in remix with 5x the argument "string" and compared the gas consumption which turned out to be for ABI encoding less than 2/3 of what the other solution burns and the execution cost only about 1/7th:

Initial Solution:
Transaction cost: 45380
Execution cost: 19436

ABI encoding:
Transaction cost: 28650
Execution cost: 2706


To be fair, ABI encoding has not been around for too long and the earlier proposed solutions get the job done as well. I have been using the strConcat function from oraclizeAPI for some time myself. However, especially if you need this function to be called by another smart contract or internally by a function changing the state of the contract, for the sake of cost-efficiency, you should definitely use ABI encoding.

  • This is the correct answer in 2019 – Miguel Mota Jul 30 at 3:21
10

A library can be used, for example:

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

Use the above for a quick test that you can modify for your needs.


Since concatenating strings needs to be done manually for now, and doing so in a contract may consume unnecessary gas (new string has to be allocated and then each character written), it is worth considering what's the use case that needs string concatenation?

If the DApp can be written in a way so that the frontend concatenates the strings, and then passes it to the contract for processing, this could be a better design.

Or, if a contract wants to hash a single long string, note that all the built-in hashing functions in Solidity (sha256, ripemd160, sha3) take a variable number of arguments and will perform the concatenation before computing the hash.

9

To be honest, I don't think you should do string manipulation in the contract (which is on the blockchain). A well developed blockchain app should be kicked off from an user account, not a contract. Contract initiated transactions should do simple things like transferring stuff. If you are concatenating between two strings, then treat them like the underlying array data that they are and simply push the new value on the old one.

Otherwise, for serious manipulating of strings, do it on the client side before posting it in the body of the transaction back to the blockchain. Basically, with etherium we're sort of like in the early stages of databases with SQL still on the horizon. Do the work outside the datapile.

  • 1
    I'm using it for developing unit tests in solidity. FWIW. – n13 Jun 13 '18 at 5:47
6

string s = string(abi.encodePacked("a", " ", "concatenated", " ", "string"));

ethfiddle

  • 2
    Any pros and cons for this approach would be much appreciated by newbie like me. Thanks for the solution anyway. – LiweiZ Jul 20 '18 at 4:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.