跳至主要內容
本頁面使用機器翻譯自英語,可能包含錯誤或不清楚的語言。如需最準確的信息,請參閱英文原文。由於更新頻繁,部分內容可能與英文原文有出入。請加入我們在 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,這表示已經有中繼者傳送了這個隨機號碼。 隨機號碼只能遞送一次。

讓這個頁面變得更好