Cómo convertir una matriz de bytes a bytes32 en solidity

Quiero saber la sintaxis para convertir una matriz de bytes a bytes32 en solidez.

Esta es una continuación de la pregunta: ¿Cómo almacenar la clave pública en el contrato de Ethereum?

Quiero recuperar la clave pública almacenada como matriz de bytes.

Amablemente aconséjeme saber cómo se podría lograr esto.

Gracias.

Respuestas (4)

Aquí hay una forma de extraer bytes32 de una matriz de bytes:

function bytesToBytes32(bytes b, uint offset) private pure returns (bytes32) {
  bytes32 out;

  for (uint i = 0; i < 32; i++) {
    out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);
  }
  return out;
}
¿Qué ponemos como compensación?
El primer byte que se va a copiar. Si desea copiar todo, use 0.
¿Por qué se usa "& 0xFF"? ¿No es eso solo útil cuando se obtiene el valor del primer byte de un valor multibyte? b[offset + i] es un solo byte.
No veo ningún lugar en los documentos de Solidity que indique si los bytes están firmados o no, aunque los documentos parecen implicar que no están firmados porque dicen, "los números enteros no firmados se pueden convertir en bytes del mismo tamaño o más grande, pero no viceversa". Entonces, la pregunta es si convertir un valor de byte en un valor de byte32 extenderá el signo. Los documentos no son claros en otros puntos de la semántica del lenguaje.

Puede usar bytes32 directamente en el constructor del contrato y luego recuperar el atributo a través de un captador :

contract PubKey {
         bytes32 pubKey;

         function PubKey(bytes32 initKey) {
             pubKey = initKey;
         }

         function getPubKey() constant returns (bytes32) {

            return pubKey;

         }
    }

Además, eche un vistazo a esta pregunta para obtener detalles de conversión de tipo en solidez.

.

Aparentemente, string(bytesString) funciona, pero bytes32(bytesString) no funciona.
¿Crees que almacenar la clave pública en formato hexadecimal (uint256) sería lo mejor? Déjame saber lo que piensas.
He modificado la respuesta. Puede usar bytes32 directamente.
bytes memory toBeConvert = "xxxxx";
bytes32 converted;

assembly {
    encoded := mload(add(result, 32))
}

Si solo quieres hacer la conversión, prueba esto. Pero asegúrese de agregar requisitos en el entorno de producción.

Puede dividir los datos si están en los datos de la llamada:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract Slice {
    function bytesToBytes32(bytes calldata b) external pure returns (bytes32) {
        return bytes32(b[:32]);
    }
}