Convertir bytes32 a bytes

¿Hay una manera simple de convertir bytes32a bytesSolidity?

Estoy tratando de obtener la longitud de la cadena pasada en la variable bytes32, pero todo se devuelve en tamaño 32, lo que tiene sentido.

Pero la conversión explícita no parece funcionar:

bytes memory _tmpUsername = bytes(_username);  // _username is of type bytes32 

Esto arroja un error de:

Explicit type conversion not allowed from "bytes32" to "bytes storage pointer"

Respuestas (4)

Dado solidity@0.4.22que , puede usar abi.encodePacked()para esto, que devuelve bytes. Por ejemplo ;

contract C { 
  function toBytes(bytes32 _data) public pure returns (bytes) {
    return abi.encodePacked(_data);
  }
}

Aquí hay un método totalmente ineficiente para convertir bytes32 en bytes (mientras se eliminan los bytes de ceros adicionales a la derecha).

function bytes32ToBytes(bytes32 data) internal pure returns (bytes) {
    uint i = 0;
    while (i < 32 && uint(data[i]) != 0) {
        ++i;
    }
    bytes memory result = new bytes(i);
    i = 0;
    while (i < 32 && data[i] != 0) {
        result[i] = data[i];
        ++i;
    }
    return result;
}
De hecho, estaba pensando en líneas similares, pero ¿no sería un problema si mis datos contienen un 0 en su valor? Digamos, por ejemplo, ¿los datos son "test2010"?
El dígito cero '0' tiene un valor de 48 cuando se considera un byte, por lo que no debería ser un problema (esto se aplica a la codificación de cadenas más común, ASCII, UTF-8).

Respuesta para Solidity v0.8.4 y superior

Puede usar bytes.concaten lugar de abi.encodePacked.

function toBytes(bytes32 data) public pure returns (bytes memory) {
    return bytes.concat(data);
}

Tengo entendido que bytes.concatfinalmente reemplazará a abi.encodePacked.

Usando el ensamblaje en línea, puede copiar bytes32a una bytesestructura como esta:

  function bytes32ToBytes(bytes32 input) public pure returns (bytes memory) {
    bytes memory b = new bytes(32);
    assembly {
      mstore(add(b, 32), input) // set the bytes data
    }
    return b;
  }