如何在智能合約中使用 ANU 的量子隨機數生成器
為了滿足智能合約對隨機性的需求,去中心化僞隨機數生成器是一種常用的方法。
原文:A Guide to Using ANU’s Quantum Random Number Generator in Your Smart Contracts
作者:Vansh Wassan
原用標題(譯後):指南:在智能合約中使用 ANU 的量子隨機數生成器
編譯:ChinaDeFi
隨機數生成器 (RNG) 一直是使用智能合約時最大的問題之一。確定性虛擬機無法產生 “真正的” 隨機性。
為了滿足智能合約對隨機性的需求,去中心化僞隨機數生成器是一種常用的方法。最常用的方法之一是 Chainlink 的 VRF 或可驗證隨機函數,它在鏈上提供密碼可證明的隨機數。它生成一個鏈下隨機數和用於驗證結果的加密證明。
然而,這種配置與其他第三方預言機網絡存在相同的問題。設置一個可以提供 PRNG 的預言機節點會暴露潛在的攻擊載體,比如女巫攻擊,也缺乏源透明性和去中心化。例如,需要信任治理實體來選擇網絡參與者,這意味着去中心化的 PRNG 只與治理實體一樣安全和去中心化。
量子隨機數生成
QRNG 通過量子現象產生隨機性。它使用一個 “真正的” 熵源,利用量子物理的獨特特性來產生真正的隨機性。
實現 QRNG 的方法各不相同,但共同點是得到的數字將是真正隨機的,因為量子事件的結果在理論上是不確定的。因此,QRNG 是隨機數生成的黃金標准。
澳大利亞國立大學的 QRNG Airnode
正如我們已經討論過的,通過第三方預言機網絡提供 RNG 會為攻擊載體打开大門。但是由 QRNG API 提供商直接運營的第一方預言機 (airnode) 會以最佳方式應對女巫攻擊風險。
API3 QRNG 是澳大利亞國立大學 (ANU) 提供的公共實用程序。它由 ANU 量子隨機數托管的 Airnode 提供動力,這也意味着它是第一方服務。澳大利亞國立大學的量子光學部是該領域世界領先的研究機構之一。該部門還運行一個 REST API,即量子隨機數 API,以服務於 Web2 中的 QRNG。
它作為一種公共產品,所以也是免費的 (除了 gas 成本),當需要鏈上 RNG 時,它通過一個易於使用的解決方案提供了 “真正的” 量子隨機性。
Airnode 和 API3 QRNG 是如何工作的?
首先,我們需要使用能夠匹配上的贊助者錢包進行部署並贊助 QrngRequester。QrngRequester 將是檢索隨機數的主合約。
QrngRequester 向 AirnodeRrpV0 提交一個隨機數請求。Airnode 從 AirnodeRrpV0 協議合約中收集請求,從鏈下檢索隨機數,並將其發送回 AirnodeRrpV0。一旦接收到,它將使用隨機數執行回調到請求程序。
編碼 QrngRequester.sol
开始
請確保已安裝以下軟件:
- Node.js
- yarn/NPM
另外,請確保已經克隆並安裝了 Airnode Monorepo。如果還沒有,用以下命令克隆 Airnode Monorepo:
$gitclonehttps://github.com/api3dao/airnode.git
要安裝依賴項,請執行以下步驟:
$ yarn run bootstrap
要構建所有的包,使用這個命令:
$ yarn run build
編制合約
為了編譯 QrngRequester 合約,我們將使用 Remix IDE。它是一個在线 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() 函數,該函數將請求添加到其存儲中並返回一個 requestId。
- 目標鏈下 ANU Airnode 收集請求並使用隨機數向請求者執行回調。
請求參數
makeRequestUint256() 函數需要以下參數發出有效請求。
- airnode (地址) 和 endpointiduint256 指定端點。
- sponsorWallet 指定將使用哪個錢包來完成請求。
響應參數
對 QrngRequester 的回調包含兩個參數:
- requestId:在發出請求時會被首次獲取,並在這裏作為參考傳遞,以識別響應所針對的請求。
- data:在成功響應的情況下,這是已被編碼的請求數據,除了其他響應數據外,還包含時間戳。使用 abi 對象中的 Decode() 函數對其進行解碼,以獲得隨機數。
轉到 Remix IDE,創建一個合約,並將其粘貼到 QrngRequester 代碼中。
現在,點擊儀表板右側的 compile 並編譯智能合約。
部署合約
我們將把我們的 QrngRequester 部署到 Goerli。確保錢包中有足夠的測試網 ETH 來部署合約,並在以後資助 sponsorWallet。
轉到部署,運行交易,並在環境下選擇 “Injected Provider — MetaMask” 選項。連接 MetaMask。確保是在 Goerli。
_rrpaddress 是主 airnodeRrpAddress。RRP 合約已經部署在鏈上。
填充_rrpAddress 之後,單擊 “Deploy”。確認 MetaMask 上的交易,並等待它部署 Requester 合約。
確保是在 Goerli。
調用合約
當 QrngRequester 部署完成後,轉到 Deploy,運行交易,然後單擊已部署合約下的請求者並下拉列表。
現在選擇 setRequestParameters 並下拉菜單來設置所有的參數。
將以下內容添加到函數的相應字段中。
- _airnode:所需 QRNG 服務提供者的 airnode 地址。從 ANU Airnode 查看它的值。
- _endpointIdUint256: Airnode 端點 ID 將返回一個隨機數。從 ANU Airnode 查看它的值。
- _sponsorWallet:一個由請求者合約地址、Airnode 地址和 Airnode xpub 派生的錢包。這個錢包用來支付 gas 費用,以獲得一個隨機數。贊助者錢包必須使用命令 derived -sponsor-wallet-address 從 Admin CLI 中派生。使用命令輸出的贊助者錢包地址的值。
在設置好 Airnode CLI,安裝並構建所有依賴項和包之後,運行以下命令來派生自己的_sponsorWallet。
Linux
npx @api3/airnode-admin derive-sponsor-wallet-address \
--airnode-xpub xpub6CUGRUo... \
--airnode-address 0xe1...dF05s \
--sponsor-address0xF4...dDyu9
Windows
npx @api3/airnode-admin derive-sponsor-wallet-address ^
--airnode-xpub xpub6CUGRUo... ^
--airnode-address 0xe1...dF05s ^
--sponsor-address 0xF4...dDyu9
用一些測試網 ETH 資助 sponsorWallet。單擊交易按鈕並確認交易以設置參數。
發出請求,單擊 makeRequestUint256 按鈕調用函數,並發出完整的請求。
現在可以前往並檢查自己的新交易了。https://goerli.etherscan.io/sponsorWallet`
可能需要等待一段時間,因為 Airnode 調用 AirnodeRrpV0.sol 中的 fulfill() 函數,它將使用函數 fulfillment functionid 在 fulfillAddress 處回調請求者合約來傳遞數據 (隨機數)。
在這裏,我們可以看到最新的 fulfillment 交易。
現在回到 Remix 並點擊 latestRequest 按鈕檢查響應。
如果回調已經成功完成,randomNumber 將會出現。waitingFulfillment 的值將為假。
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。
區塊鏈愛好者
文章數量
34524粉絲數
0