Как использовать квантовый генератор случайных чисел ANU в ваших смарт-контрактах
22 октября 2022 г.Генерация случайных чисел (ГСЧ) всегда была одной из самых больших проблем при работе со смарт-контрактами. Детерминированная виртуальная машина не способна генерировать «настоящую» случайность. В связи с этим RNG необходимо предоставлять как службу оракула.
Чтобы удовлетворить потребность в случайности в смарт-контрактах, обычно используется децентрализованный псевдослучайный ГСЧ. Одним из наиболее часто используемых методов является VRF от Chainlink или проверяемая случайная функция, которая предоставляет криптографически доказуемые случайные числа в цепочке. Он генерирует случайное число вне сети с криптографическим подтверждением, которое используется для проверки результата.
<цитата>Однако в этой конфигурации возникают те же проблемы, что и в любой другой сторонней сети оракула. Настройка узла оракула, который может предоставлять PRNG, раскрывает потенциальные векторы атак, такие как атаки Сивиллы, но также не обеспечивает прозрачности источника и децентрализации. Например, нужно доверить управляющему органу выбор участников сети, что означает, что децентрализованный PRNG настолько же безопасен и децентрализован, как и управляющий орган.
Генерация квантовых случайных чисел
QRNG генерирует случайность с помощью квантовых явлений. Он использует «настоящий» источник энтропии, используя уникальные свойства квантовой физики для создания истинной случайности.
Существуют разные методы реализации QRNG с разным уровнем практичности, но общим является то, что результирующие числа будут действительно случайными, поскольку исход квантового события теоретически неопределен с четко определенными характеристиками. Таким образом, QRNG является золотым стандартом для генерации случайных чисел.
Airnode QRNG Австралийского национального университета
Как мы уже обсуждали, предоставление ГСЧ через стороннюю сеть оракулов открывает пространство для векторов атак. Но собственные оракулы (Airnodes), которыми непосредственно управляет QRNG API Поставщики оптимальным образом противодействуют риску атаки Сивиллы.
API3 QRNG — это общедоступная утилита, предлагаемая Австралийским национальным университетом (ANU). Он работает на Airnode, размещенном на ANU Quantum Random Numbers, что означает, что это собственная служба. Отделение квантовой оптики Австралийского национального университета является одним из ведущих мировых исследовательских институтов в этой области. Подразделение также использует REST API, Quantum Random Numbers API, для обслуживания QRNG в Web2.
Он служит общественным благом и предоставляется бесплатно (не считая расходов на газ). Он обеспечивает «настоящую» квантовую случайность с помощью простого в использовании решения, когда требуется ГСЧ в цепочке.
Как работает Airnode и API3 QRNG
Для начала нам нужно развернуть и спонсировать QrngRequester
с помощью соответствующего спонсорского кошелька. QrngRequester
будет основным контрактом, который извлекает случайное число.
QrngRequester
отправляет запрос случайного числа в AirnodeRrpV0
. Airnode собирает запрос из контракта протокола AirnodeRrpV0
, извлекает случайное число вне цепочки и отправляет его обратно в AirnodeRrpV0
. После получения он выполняет обратный вызов запрашивающей стороне со случайным числом.
Подробнее о том, как API3 QRNG использует протокол запрос-ответ, можно прочитать здесь.
Код QrngRequester.sol
Начало работы
Убедитесь, что у вас установлено следующее:
* Node.js * пряжа/NPM
Кроме того, убедитесь, что вы уже клонировали и установили монохранилище Airnode. Если нет, клонируйте монорепозиторий Airnode с помощью этой команды:
$ git clone https://github.com/api3dao/airnode.git .
Чтобы установить зависимости, сделайте следующее:
$ yarn run bootstrap
Чтобы собрать все пакеты, используйте эту команду:
$ yarn run build
Составление контракта
Для компиляции контракта QrngRequester мы будем использовать Remix IDE. Это онлайн-среда разработки, которая позволяет разрабатывать, развертывать и администрировать смарт-контракты для блокчейнов, совместимых с EVM.
//SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "@api3/airnode-protocol/contracts/rrp/requesters/RrpRequesterV0.sol";
contract RemixQrngExample is RrpRequesterV0 {
event RequestedUint256(bytes32 indexed requestId);
event ReceivedUint256(bytes32 indexed requestId, uint256 response);
address public airnode;
bytes32 public endpointIdUint256;
address public sponsorWallet;
mapping(bytes32 => bool) public waitingFulfillment;
// These are for Remix demonstration purposes, their use is not practical.
struct LatestRequest {
bytes32 requestId;
uint256 randomNumber;
}
LatestRequest public latestRequest;
constructor(address _airnodeRrp) RrpRequesterV0(_airnodeRrp) {}
// Normally, this function should be protected, as in:
// require(msg.sender == owner, "Sender not owner");
function setRequestParameters(
address _airnode,
bytes32 _endpointIdUint256,
address _sponsorWallet
) external {
airnode = _airnode;
endpointIdUint256 = _endpointIdUint256;
sponsorWallet = _sponsorWallet;
}
function makeRequestUint256() external {
bytes32 requestId = airnodeRrp.makeFullRequest(
airnode,
endpointIdUint256,
address(this),
sponsorWallet,
address(this),
this.fulfillUint256.selector,
""
);
waitingFulfillment[requestId] = true;
latestRequest.requestId = requestId;
latestRequest.randomNumber = 0;
emit RequestedUint256(requestId);
}
function fulfillUint256(bytes32 requestId, bytes calldata data)
external
onlyAirnodeRrp
{
require(
waitingFulfillment[requestId],
"Request ID not known"
);
waitingFulfillment[requestId] = false;
uint256 qrngUint256 = abi.decode(data, (uint256));
// Do what you want with `qrngUint256` here...
latestRequest.randomNumber = qrngUint256;
emit ReceivedUint256(requestId, qrngUint256);
}
}
QrngRequester
будет иметь три основные функции: setRequestParameters()
, makeRequestUint256()
и fulfillUint256()
.
setRequestParameters()
принимаетairnode
,endpointIdUint256
,sponsorWallet
и устанавливает эти параметры.- Функция
makeRequestUint256()
вызывает функциюairnodeRrp.makeFullRequest()
файла ==AirnodeRrpV0.sol== контракт протокола, который добавляет запрос в свое хранилище и возвращаетrequestId
. - Целевой ANU вне сети Airnode собирает запрос и выполняет обратный вызов запросчик со случайным числом.
Параметры запроса
Функция makeRequestUint256()
ожидает, что следующие параметры сделают действительный запрос.
* airnode
(адрес) и endpointIdUint256
определяют конечную точку. Получите их здесь.
* sponsorWallet
указывает, какой кошелек будет использоваться для выполнения запроса.
Параметры ответа
Обратный вызов QrngRequester
содержит два параметра:
* requestId
: сначала получен при выполнении запроса и передан здесь как ссылка для идентификации запроса, для которого предназначен ответ.
* данные
: в случае успешного ответа это запрошенные данные, которые были закодированы и содержат timestamp в дополнение к другим данным ответа. Декодируйте его с помощью функции decode()
из объекта abi
, чтобы получить случайное число.
Перейдите в Remix IDE, создайте контракт и вставьте его в QrngRequester код.
Теперь нажмите "Компилировать" в правой части панели управления и скомпилируйте смарт-контракт.
Развертывание контракта
Мы собираемся развернуть наш QrngRequester
в Goerli. Убедитесь, что в вашем кошельке достаточно тестовой сети ETH для развертывания контракта и пополнения sponsorWallet
позже. Вы можете получить тестовую сеть Goerli здесь.
Перейдите к развертыванию, запустите транзакции и выберите параметр «Injected Provider — MetaMask» в разделе «Среда». Подключите свой MetaMask. Убедитесь, что вы находитесь на Goerli.
_rrpAddress
– это основной airnodeRrpAddress
. Контракты RRP уже развернуты в сети. Вы можете проверить свою конкретную цепочку здесь.
После заполнения _rrpAddress
нажмите «Развернуть». Подтвердите транзакцию в своей MetaMask и подождите, пока она развернет контракт запрашивающей стороны.
Вызов контракта
Когда ваш QrngRequester
будет развернут, перейдите в раздел «Развертывание», запустите транзакции и щелкните раскрывающийся список для вашего запрашивающего в разделе «Развернутые контракты».
Теперь выберите раскрывающийся список setRequestParameters
, чтобы установить все параметры.
Добавьте следующее в соответствующие поля функции.
* _airnode
: адрес аэроузла желаемого поставщика услуг QRNG. См. его значение на ANU Airnode.
* _endpointIdUint256
: идентификатор конечной точки Airnode возвращает одно случайное число. См. его значение на ANU Airnode.
* _sponsorWallet
: кошелек, полученный из адреса контракта запрашивающей стороны, адреса Airnode и xpub Airnode. Кошелек используется для оплаты расходов на газ для получения случайного числа. Спонсорский кошелек должен быть получен с помощью команды derive -sponsor-wallet-address из интерфейса командной строки администратора. Используйте значение адреса кошелька спонсора, которое выводит команда.
После того, как вы настроили интерфейс командной строки Airnode, установили и собрали все зависимости и пакеты, выполните следующую команду, чтобы получить свой _sponsorWallet
:
Линукс
npx @api3/airnode-admin derive-sponsor-wallet-address
--airnode-xpub xpub6CUGRUo...
--airnode-address 0xe1...dF05s
--sponsor-address 0xF4...dDyu9
Окна
npx @api3/airnode-admin derive-sponsor-wallet-address ^
--airnode-xpub xpub6CUGRUo... ^
--airnode-address 0xe1...dF05s ^
--sponsor-address 0xF4...dDyu9
ANU airnode-address
и airnode-xpub
можно найти здесь.
Пополните sponsorWallet
тестовым ETH. Нажмите кнопку транзакции и подтвердите транзакцию, чтобы установить параметры.
Чтобы сделать запрос, нажмите кнопку makeRequestUint256
, чтобы вызвать функцию и сделать полный запрос.
Теперь вы можете перейти на https://goerli.etherscan.io/
и проверить свой спонсорский кошелек
на наличие новых транзакций.
Возможно, вам придется подождать некоторое время, пока Airnode вызывает функцию fulfill()
в AirnodeRrpV0.sol
, которая, в свою очередь, вызовет контракт запрашивающей стороны по адресу fulfillAddress<. /code> используя функцию
fulfillFunctionId
для доставки данных
(случайное число).
Здесь мы можем увидеть последнюю транзакцию Fulfill
.
Теперь вернитесь в Remix и нажмите кнопку latestRequest
, чтобы проверить ответ.
Если обратный вызов был успешно завершен, будет присутствовать randomNumber
. Значение waitingFulfillment
будет false
.
:::подсказка Если вы хотите узнать об этом больше, ознакомьтесь с примером проекта QRNG.
Подробнее об API3 QRNG.
:::
Также опубликовано здесь.< /а>
Оригинал