47

How can I convert a string to a bytes32? Does anyone has a magic function or library which does it?

For example: This works since as input I gave 32-bits. But it won't work with "> 32-bit" chars.

set_txn_hash = a.transact().set("QmVoGzRDscx61k3RHHkLYaMFtxYZi3ps");#32-bit char

-

function get() returns (stringc value){  
    return list.get_head_data();   
}

But if I need to give more character for example contains 48-bit string this won't work. [Q] How could I make this work?

7 Answers 7

57

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 strings in solidity are UTF8 so after converting them to bytes each byte is not necessarily a character.

EDIT: shorter version, should work the same.

8
  • xpected elementary inline assembly operation. bytes32 result := mload(add(source, 32)) ^ contracts/Link.sol:77:22: Error: Expected token Semicolon got 'Colon' bytes32 result := mload(add(source, 32))
    – alper
    Oct 10, 2016 at 11:30
  • @Avatar you have bytes32 result := while my code is declaring result type in returns (bytes32 result), just remove the bytes32 from before result := ... and it should compile. Oct 10, 2016 at 12:42
  • awesome works!! Thank you sir. One final question is, if my string is larger than 32 bits such as 48 bits the remaining 12 bits will be trimmed. Would there be additional assemble line that I can obtain bits from 32 to 48? thank you for your valuable time. when I did "result := mload(add(source, 64)) " it worked!
    – alper
    Oct 10, 2016 at 15:26
  • I tried your code in remix.ethereum.org (using JavaScript VM) and entered "EOS8WE79SonHGHc5DquV4fxty9bHfnLSugCyTVXj2n9t4Uw5HL2vU" as my string, which is 56 characters long. It returned: "0x454f533857453739536f6e4847486335447175563466787479396248666e4c53" When I convert this into ASCII, I get "EOS8WE79SonHGHc5DquV4fxty9bHfnLS", which is 34 characters. Why? How do I get the original 56 characters back?
    – Curt
    Aug 16, 2017 at 21:14
  • 1
    @Curt you can't, conversion from string to bytes32 is lossy. bytes32 can contain only 32 8-bit characters but strings can be longer than 32 characters and during this operation all characters above 32 are lost. The string you pasted has 32 characters, I didn't count the quotation characters. Aug 18, 2017 at 7:23
23

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 using assembly

3
  • Error: Explicit type conversion not allowed. bytes b = bytes("a");
    – alper
    Oct 9, 2016 at 17:35
  • try the new code above using memory variable.
    – Badr Bellaj
    Oct 9, 2016 at 20:24
  • TypeError: Explicit type conversion not allowed from "literal_string "mined"" to "bytes storage pointer". bytes memory data = bytes("mined");
    – bitsanity
    Oct 9, 2017 at 16:35
15

ethers.js has a built in utility function for this: https://docs.ethers.io/ethers.js/html/api-utils.html#bytes32-strings

const ethers = require('ethers')
const utils = ethers.utils

const inBytes = utils.formatBytes32String("test");
3
  • 1
    This should be the right solution gentlemen Oct 4, 2021 at 14:17
  • 2
    I don't think this answers the question, which was about how to do this inside a smart contract, not how to do it javascript.
    – GGizmos
    Dec 14, 2021 at 21:53
  • 3
    @GGizmos perhaps but it's what I was also looking for and search brought me here
    – JP Lew
    Apr 22 at 6:12
7

Assembly is not needed in version 0.8.7

string text = "whatever"; 
bytes32 stringInBytes32 = bytes32(bytes(text));
3
  • I tried this, what I want to do is send a bytes32 string to solidity and store it in a bytes32 variable. If I take the input string: '0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d' and follow your code (bytes32(bytes(inputstring) I get '0x3078343162316130363439373532616631623238623364633239613135353665' from console.logBytes32 inside the solidity function. Seems to be all integers, altho the right length. Any ideas why that is:
    – GGizmos
    Feb 1 at 2:03
  • @GGizmos, text is supposed to be a string of UTF-8 characters. You are using an hexadecimal value, I don't how to do it in that case.
    – Jose4Linux
    Feb 5 at 19:31
  • When I try this I get Explicit type conversion not allowed from "bytes memory" to "bytes32". using a string from a parameter.
    – NickJ
    Jun 28 at 23:04
0
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract stringtobytes{
    function set(string memory  _a)public pure returns(bytes memory){
        return (bytes(_a));
    } 
}

you can convert strings to bytes(in decimal format) with below code

1- bytes1=8bit=2decimal

2 bytes2=16bit=4decimal

3 bytes3=24bit=6decimal

4 bytes=dynamic array and reference value

1
  • 2
    The question was about converting from string to bytes32, your example doesn't work for bytes32.
    – Ismael
    Feb 3 at 13:24
0
function get(string memory key) 
    public 
    view 
    returns (bytes32) {
        return bytes32(abi.encodePacked(key));
}
2
  • I get - Explicit type conversion not allowed from "bytes memory" to "bytes32".
    – NickJ
    Jun 28 at 23:08
  • @NickJ The answer is correct. Check your code. Jul 4 at 21:53
-1

Please reference this. You can convert string to bytes32 array.The length of string can be longer than 32 .

https://ethereum.stackexchange.com/a/13388/6353

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.