Hot answers tagged

43

This has worked for me so far. Not sure if it's the best way. function stringToBytes32(string memory source) public pure returns (bytes32 result) { bytes memory tempEmptyStringTest = bytes(source); if (tempEmptyStringTest.length == 0) { return 0x0; } assembly { result := mload(add(source, 32)) } } Also, remember that ...


42

If you don't want to load the StringUtils contract, I found it's also possible to simply: keccak256(portcheck) == keccak256("signed"). Can anyone confirm that this would also cost less gas than a function which evaluates each char of both strings? (Sorry if adding an answer to a Q with a "checked" response is frowned upon... I just noticed that this method ...


41

Why string instead of bytes32? Use string for arbitrary-length string (UTF-8) data that's longer than 32 bytes. Frontends can decode a long string easier using methods like web3.toAscii or UTF-8 (when issues are fixed), instead of implementing the logic of UTF-8 decoding a series of bytes32. From Solidity docs: As a rule of thumb, use bytes for ...


40

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


31

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


30

2 main reasons: Contracts currently cannot read a string that's returned by another contract. The EVM has a word-size of 32 bytes, so it is "optimized" for dealing with data in chunks of 32 bytes. (Compilers, such as Solidity, have to do more work and generate more bytecode when data isn't in chunks of 32 bytes, which effectively leads to higher gas cost.)


29

Here's one: function bytes32ToString(bytes32 x) constant returns (string) { bytes memory bytesString = new bytes(32); uint charCount = 0; for (uint j = 0; j < 32; j++) { byte char = byte(bytes32(uint(x) * 2 ** (8 * j))); if (char != 0) { bytesString[charCount] = char; charCount++; } } ...


27

You can convert the string into a type bytes and then check its length. For example this will test if emptyStringTest is indeed an empty string: bytes memory tempEmptyStringTest = bytes(emptyStringTest); // Uses memory if (tempEmptyStringTest.length == 0) { // emptyStringTest is an empty string } else { // emptyStringTest is not an empty string } ...


26

Use abi.encodePacked(x) where x is the address. (Thanks @k06a)


24

One way is to check for the length of a String: if (bytes(m1[msg.sender]).length != 0 && bytes(m2[msg.sender].someString).length != 0) // do your thing See the answer I posted here


24

There are a few types of string values that you may be referring to. bytes1 - bytes32: fixed size. bytes or string: dynamically sized. Solidity supports functions with multiple return values. contract MultiReturner { function getData() constant returns (bytes32, bytes32) { bytes32 a = "abcd"; bytes32 b = "wxyz"; return (a, b); ...


19

Code for calculating string length in characters contract utf8StringLength { //---------------------BEGIN Code to copy-paste-------------- function utfStringLength(string str) constant returns (uint length) { uint i=0; bytes memory string_rep = bytes(str); while (i<string_rep.length) { if (...


16

Just check if bytes(str).length is too big. EDIT: See the answer below if you need to know an exact length of a utf-8 encoded string. This will cost significantly more gas, however. Note that the utf-8 length will be at most the byte length.


15

Try using the web3.js function web3.toAscii (doc), which might change name to web3.toUtf8 or something similar in the future.


15

Another option is to use a solution from Oraclize https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol, it suits best for me: 0.5 Compiler Version: function uint2str(uint _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint j = _i; uint len; while (j != 0) { ...


14

Each bytes32 can store up to 32 letters (ASCII): each character is a byte.


14

string is not equal to bytes32 but it is equal to bytes, because its length is dynamic. so you could use a casting bytes B=bytes(S); //S string E.g contract string_test { function string_tobytes( string s) constant returns (bytes){ bytes memory b3 = bytes(s); return b3; } } The conversion of string to bytes32 is possible only ...


13

The combination of string and indexed does not work. To understand why, see how event arguments are stored in the blockchain. All transactions that are executed generate a transaction receipt, which contains a property called logs. You can look up the receipt using eth.getTransactionReceipt("0x..."). In the transaction receipt, all event arguments that are ...


13

Like the other post said, you only want to use strings for dynamically allocated data, otherwise Byte32 is going to perform better. Bytes32 is also going to be better in gas. If you want to play around with it, I built a little fiddle of it https://ethfiddle.com/70ipaEIFdk Byte used 21465 gas String used 21897 gas pragma solidity ^0.4.18; contract ...


12

Variable-sized data that is returned by one contract, cannot be read by another contract. Parents is trying to read a string from Child and thus the error. Reference: The EVM is unable to read variably-sized data from external function calls... Note that on the other hand, it is possible to return variably-sized data, it just cannot be read from ...


11

How to convert a bytes32 to string: pragma solidity ^0.4.15; contract Bytes32ToString { function bytes32ToStr(bytes32 _bytes32) public pure returns (string) { // string memory str = string(_bytes32); // TypeError: Explicit type conversion not allowed from "bytes32" to "string storage pointer" // thus we should fist convert bytes32 to bytes (...


11

No, I don't believe so. As I understand it, Solidity doesn't have a built-in way yet to deserialize string arrays. It can cheat when the contract is passing an array it created itself to itself, which is why it works with private functions. But if you want to take string arrays from the outside, you're going to have to handle the serialization and ...


11

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


11

I was not able to read the ABI-encoded string with web3.js. Therefore I added some conversion to the ascii-characters: function toAsciiString(address x) returns (string) { bytes memory s = new bytes(40); for (uint i = 0; i < 20; i++) { byte b = byte(uint8(uint(x) / (2**(8*(19 - i))))); byte hi = byte(uint8(b) / 16); byte ...


10

You can use web3.toAscii(hexString) as documented in Web3 JavaScript Ðapp API: > web3.toAscii("0x4d61726b65745061792e696f206973206465706c6f79696e6720536d61727420") "MarketPay.io is deploying Smart " You can also use web3.toUtf8(hexString): > web3.toUtf8("0x4d61726b65745061792e696f206973206465706c6f79696e6720536d61727420") "MarketPay.io is deploying ...


9

As in Java, the == operator does not compare the literals of two strings. You should use the StringUtils contract instead. if (StringUtils.equal(portcheck,"signed")) {...}


9

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


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


9

Thanks to Piper and Chris I found a working solution for Solidity <= 0.2.1. The reason why the first two log statements return different results is, because uintN is right-aligned and bytesN is left-aligned. Conversion between uintN and bytesN first shortens and then changes alignment. That's why it has to be converted back to bytes32 before converted to ...


9

Whilst I have not worked with IPFS hashes, the solidity types documentation states that you can store fixed size byte arrays up to 32 bytes. As such if you want to store the whole hash in one data property you have to use the dynamic array type bytes. This is outlined here. If you want to store them separately, it seems perverse to me to implement the ...


Only top voted, non community-wiki answers of a minimum length are eligible