Как преобразовать массив байтов в байты32 в солидности

Я хочу знать синтаксис для преобразования массива байтов в байты32 в твердости.

Это ответ на вопрос : как хранить открытый ключ в контракте Ethereum?

Я хочу получить PublicKey, хранящийся в виде массива байтов.

Пожалуйста, сообщите мне, как это можно сделать.

Спасибо.

Ответы (4)

Вот способ извлечь байты32 из массива байтов:

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;
}
Что мы вносим в качестве компенсации?
Первый байт для копирования. Если вы хотите скопировать все это, используйте 0.
Почему это использует «& 0xFF». Разве это не полезно только при получении значения первого байта многобайтового значения? b[смещение + i] — один байт.
Я нигде не вижу в документах Solidity указания, являются ли байты знаковыми или беззнаковыми, хотя документы, похоже, подразумевают, что они беззнаковые, потому что они говорят: «целые числа без знака могут быть преобразованы в байты того же или большего размера, но не наоборот". Таким образом, вопрос заключается в том, будет ли преобразование значения байта в значение byte32 расширяться по знаку. Документы не ясны в других аспектах языковой семантики.

Вы можете использовать bytes32 непосредственно в конструкторе контракта, а затем получить атрибут через геттер :

contract PubKey {
         bytes32 pubKey;

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

         function getPubKey() constant returns (bytes32) {

            return pubKey;

         }
    }

Кроме того, взгляните на этот вопрос, чтобы узнать подробности преобразования типов в Solidity.

.

Судя по всему, string(bytesString) работает, а bytes32(bytesString) не работает.
Как вы думаете, лучше всего хранить открытый ключ в шестнадцатеричном формате (uint256)? Дайте мне знать, что вы думаете.
Я изменил ответ. Вы можете использовать bytes32 напрямую.
bytes memory toBeConvert = "xxxxx";
bytes32 converted;

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

Если вы хотите только сделать преобразование, попробуйте это. Но не забудьте добавить требования в рабочую среду.

Вы можете нарезать данные, если они находятся в calldata:

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

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