¿Cómo convertir una cadena a bytes32?

¿Cómo puedo convertir un stringa un bytes32? ¿Alguien tiene una función mágica o una biblioteca que lo haga?

Por ejemplo: Esto funciona ya que como entrada di 32 bits. Pero no funcionará con caracteres "> 32 bits".

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

-

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

Pero si necesito dar más caracteres, por ejemplo, contiene una cadena de 48 bits, esto no funcionará. [P] ¿Cómo podría hacer que esto funcione?

Respuestas (7)

Esto ha funcionado para mí hasta ahora. No estoy seguro si es la mejor manera.

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

Además, recuerde que las cadenas en Solidity son UTF8, por lo que después de convertirlas en bytes, cada byte no es necesariamente un carácter.

EDITAR: versión más corta, debería funcionar igual.

operación de ensamblaje en línea elemental esperada. resultado de bytes32: = mload (agregar (fuente, 32)) ^ contratos/Link.sol: 77:22: error: el token esperado El punto y coma obtuvo 'Dos puntos' resultado de bytes32: = mload (agregar (fuente, 32))
@Avatar que tiene bytes32 result :=mientras mi código declara el tipo de resultado en returns (bytes32 result), simplemente elimine el bytes32anterior result := ...y debería compilarse.
trabajos geniales!! Gracias Señor. Una pregunta final es, si mi cadena tiene más de 32 bits, como 48 bits, se recortarán los 12 bits restantes. ¿Habría una línea de ensamblaje adicional en la que pueda obtener bits del 32 al 48? gracias por su valioso tiempo. cuando hice "resultado: = mload (agregar (fuente, 64)) " ¡funcionó!
Probé su código en remix.ethereum.org (usando JavaScript VM) e ingresé "EOS8WE79SonHGHc5DquV4fxty9bHfnLSugCyTVXj2n9t4Uw5HL2vU" como mi cadena, que tiene 56 caracteres. Devolvió: "0x454f533857453739536f6e4847486335447175563466787479396248666e4c53" Cuando convierto esto en ASCII, obtengo "EOS8WE79SonHGHc5DquV4fxty9bHfnLS", que tiene 34 caracteres. ¿Por qué? ¿Cómo recupero los 56 caracteres originales?
@Curt no puede, la conversión de cadena a bytes32 tiene pérdida. bytes32 puede contener solo 32 caracteres de 8 bits, pero las cadenas pueden tener más de 32 caracteres y durante esta operación se pierden todos los caracteres por encima de 32. La cadena que pegaste tiene 32 caracteres, no conté los caracteres de las comillas.
Además, esta función probablemente debería estar marcada como "interna" para ahorrar algo de gasolina
Me tomó un tiempo darme cuenta para los interesados: AFAIK 'fuente' dentro del ensamblaje en este contexto se refiere a la dirección de memoria de la fuente, no a la cadena a la que apunta. Luego agregamos 32 a esta dirección ya que los primeros 32 bytes aparentemente están reservados para contener el número de caracteres en la cadena (/longitud de la matriz).
¿Podrían explicar por qué funciona este código? ¿Cuál es el significado de agregar 32 al puntero de dirección de memoria de la cadena y cómo se convierte esto en bytes32?

stringno es igual a bytes32pero es igual a bytes, porque su longitud es dinámica.

así que te vendría bien un castingbytes B=bytes(S); //S string

P.ej

contract string_test {

    function string_tobytes( string s) constant returns (bytes){
        bytes memory b3 = bytes(s);
        return b3;
    }
}

La conversión de stringa bytes32solo es posible usando ensamblador

Error: No se permite la conversión de tipo explícita. bytes b = bytes ("a");
pruebe el nuevo código anterior usando la variable de memoria.
TypeError: no se permite la conversión de tipo explícito de "literal_string "mined"" a "bytes storage pointer".bytes memory data = bytes("mined");

ethers.js tiene una función de utilidad incorporada para esto: 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");
Esta debería ser la solución correcta, señores.
No creo que esto responda a la pregunta, que era sobre cómo hacer esto dentro de un contrato inteligente, no cómo hacerlo javascript.
@GGizmos quizás pero es lo que yo también estaba buscando y la búsqueda me trajo aquí

No se necesita ensamblaje en la versión 0.8.7

string text = "whatever"; 
bytes32 stringInBytes32 = bytes32(bytes(text));
Intenté esto, lo que quiero hacer es enviar una cadena bytes32 a solidity y almacenarla en una variable bytes32. 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 es:
@GGizmos, se supone que el texto es una cadena de caracteres UTF-8. Está utilizando un valor hexadecimal, no sé cómo hacerlo en ese caso.
Cuando intento esto, no se permite la conversión de tipo explícito de "memoria de bytes" a "bytes32". utilizando una cadena de un parámetro.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract stringtobytes{
    function set(string memory  _a)public pure returns(bytes memory){
        return (bytes(_a));
    } 
}

puede convertir cadenas a bytes (en formato decimal) con el siguiente código

1- bytes1=8bit=2decimal

2 bytes 2 = 16 bits = 4 decimales

3 bytes 3 = 24 bits = 6 decimales

4 bytes = matriz dinámica y valor de referencia

La pregunta era sobre la conversión de cadena a bytes32, su ejemplo no funciona para bytes32.
function get(string memory key) 
    public 
    view 
    returns (bytes32) {
        return bytes32(abi.encodePacked(key));
}
Obtengo: no se permite la conversión de tipo explícito de "bytes de memoria" a "bytes32".
@NickJ La respuesta es correcta. Revisa tu código.

Por favor, haga referencia a esto. Puede convertir una cadena en una matriz de bytes32. La longitud de la cadena puede ser superior a 32.

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