跳至主要內容
本頁面使用機器翻譯自英語,可能包含錯誤或不清楚的語言。如需最準確的信息,請參閱英文原文。由於更新頻繁,部分內容可能與英文原文有出入。請加入我們在 Crowdin 上的努力,幫助我們改進本頁面的翻譯。 (Crowdin translation page, Contributing guide)

經驗證的隨機數字產生器 (vRNG)

本文件為 Proof of Play 所提供的驗證隨機數字產生器 (vRNG) 指南的概述,專為與 Kaia 整合而設計。 vRNG 系統利用 drand 隨機性信標,為 Kaia 區塊鏈上的智慧合約提供安全且可驗證的隨機數。

驗證隨機數字產生器 (vRNG) 已針對隨機數字的低延遲傳輸進行最佳化,以盡量減少應用程式的延遲。它的設計強調可靠性和可擴展性。

註冊​

在早期存取期間,所有使用驗證隨機數字產生器系統的使用者都必須手動註冊。要使用它,您的合約地址必須獲得核准,否則任何請求都會退回。

信息

參賽隊伍可以透過 官方表格,或是直接聯絡 Kaia 團隊來申請核准,視乎哪種方式更方便而定。

vRNG 合約地址​

網路地址API URL
Kaia Mainnet0xf628f7843d94064c5072704a53b9ec455bcc4abbhttps://vrf.proofofplay.com/v1
啟動測試網路0xd14d984603b0b7ade91be52f3fc4a917dfa77bcdhttps://staging.vrf.proofofplay.com/v1

使用方式​

要求隨機號碼​

以下介面提供了一個請求隨機數的方法。

您的契約可以呼叫部署在每個鏈上的 VRFSystem。您可以選擇提供一個 traceId,它會註解到每個事件 (如果您有一個執行許多步驟的交易,使用者可以在連鎖上追蹤他們的交易,這是很有用的)。此為非必要,可保留為 0。


// SPDX-License-Identifier: MIT LICENSE
pragma solidity ^0.8.26;
uint256 constant ID = uint256(keccak256('com.proofofplay.vrfsystem.v1'));
interface IVRFSystem {
/**
* Starts a VRF random number request
*
* @param traceId Optional ID to use when tracing the request
* @return requestId for the random number, will be passed to the callback contract
*/
function requestRandomNumberWithTraceId(uint256 traceId) external returns (uint256);
}

隨機數回呼​

只要 drand 中的第一個號碼可以送出,就會送出所要求的每個隨機號碼。這可能需要長達 3 秒鐘的時間。

備註

您的呼叫將在您第一次提交 requestForRandomNumber 之後***送達。這可確保在使用者要求隨機號碼之前,***不會知道該號碼。


// SPDX-License-Identifier: MIT LICENSE
pragma solidity ^0.8.26;
interface IVRFSystemCallback {
/**
* Callback for when a Random Number is delivered
*
* @param requestId Id of the request
* @param randomNumber Random number that was generated by the Verified Random Number Generator Tool
*/
function randomNumberCallback(uint256 requestId, uint256 randomNumber) external;
}

如果我想在同一個 3 秒視窗中使用不同的數字,該怎麼辦?​

預設情況下,我們會在 drand 提供的相同 3 秒視窗內向所有請求提供相同的數字。這很好,可以驗證,但如果您希望使用者在這段時間內都有不同的數字,我們建議您加入一個熵源。

以下是每個交易擁有唯一隨機號碼的幾個範例。


// Add the requestId (Most Gas Efficient)
uint256 newRandomNumber = requestId + randomNumber;
// Hash with requestId
uint256 newRandomNumber = uint256(keccak256(abi.encodePacked(requestId, randomNumber)
// More expensive, but more normalized, hash based on requestId in last 256 block hashes
uint256 newRandomNumber = uint256(keccak256(abi.encodePacked(blockhash(block.number - (requestId % 256)), randomNumber))

備註

這些資料不保證會規範化,但會保留上述的隨機性屬性。我們建議依您的喜好調整,以達到或多或少的規範化(例如,將 sequenceId 加入 randomNumber 會非常偏斜,而使用 blockhash 則會非常規範化)。

如果您想在同一區塊中使用不同的號碼,我們建議您在同一筆交易中多次重複使用相同的號碼。


functionThatUsesNumber(randomNumber);
randomNumber = uint256(keccak256(randomNumber));
functionThatUsesNumber(randomNumber);

如果我想在同一筆交易中使用不同的號碼,該怎麼辦?​

預設情況下,每次交易我們只會給您一個號碼。我們鼓勵開發者使用這個號碼,從中衍生出其他號碼,創造出新的號碼。


//Example 1: Keccak derive
uint256 randomNumber = 12398012938091283113928;
uint256 randomNumber2 = keccak256(randomNumber);
uint256 randomNumber3 = keccak256(randomNumber2);
//Example 2: Split the number and use both sides
uint256 randomNumber = 234345234523452345;
uint256 randomNumber2 = randomNumber >> 128; // Take upper 128 bits
uint256 randomNumber3 = randomNumber & ((1 << 128) - 1); // Take lower 128 bits

區塊鏈活動​

合約會發出下列事件。


/// @notice Emitted when a random number request is initiated
/// @param requestId The unique identifier for the random number request
/// @param callbackAddress The address to which the random number is requested
/// @param traceId The trace ID used to track the request across transactions (0 if no trace ID)
event RandomNumberRequested(uint256 indexed requestId, address indexed callbackAddress, uint256 indexed traceId);
/// @notice Emitted when a random number is successfully delivered
/// @param requestId The unique identifier of the fulfilled request
/// @param callbackAddress the address was random number is requested to
/// @param traceId The trace ID associated with the request
/// @param number The round number that was used for the random number
/// @param randomNumber The random number that was generated
event RandomNumberDelivered(uint256 indexed requestId, address indexed callbackAddress, uint256 indexed traceId, uint256 roundNumber, uint256 randomNumber);

您可以在 RPC 層級查詢這些事件,看看它們是否已傳送,或使用區塊瀏覽器檢視事件串流。

使用 drand 驗證圓數/隨機數​

如果您想要驗證隨機號碼,可以直接向 drand 查詢。我們使用 drand 的 quicknet 來達到此目的。

例如,要查看圓數 11:

GET https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/11


{
"round": 11,
"randomness": "ebdcbfe855d10c56db22455fa5a18963c1f62d85f859c35c310273449b49d284",
"signature": "163d14081e191a3f5d81e2f580eab591ea608402fda4f6e44b5a0bde11e368070e77d07ad3240726ea33e410c84d4b09ea0a4a0291f6c3c485d8630e1c0edf0a"
}

我們可以在此看到十六進制的隨機數是 ebdcbfe855d10c56db22455fa5a18963c1f62d85f859c35c310273449b49d284 。

使用 EIP712 簽章進行手動重試​

信息

** 此功能正在預覽中**。如果您想使用,請聯絡 Kaia 團隊。

在非常罕見的情況下,您可能會看到隨機號碼無法傳送。在大多數情況下,這會是合約方面的問題。

在這些情況下,您可以選擇自己交付此號碼。首先,您應該向我們的 API 伺服器請求 EIP712 簽署,您可以使用該簽署直接將隨機數傳送至區塊鏈上的合約。

請求:


GET https://vrf.proofofplay.com/v1/vrf/{chainId}/{txHash}

回應:


{
"requestId": Number,
"roundNumber": Number,
"randomNumber": BigInt,
"signature": String // bytes data of signature
}

有了回應,您現在可以呼叫 VRFSystem 契約


vrf.deliverSignedRandomNumber(requestId, roundNumber, randomNumber, signature);

警告

您將比賽正常的中繼流程。如果您收到帶有 InvalidRequestId 的 tx revert,這表示已經有中繼者傳送了這個隨機號碼。隨機號碼只能遞送一次。

讓這個頁面變得更好