Bộ sinh số ngẫu nhiên đã được xác minh (vRNG)

Tài liệu này cung cấp tổng quan về Hướng dẫn Sinh số ngẫu nhiên đã được xác minh (vRNG) của Proof of Play, được thiết kế để tích hợp với Kaia. Hệ thống vRNG sử dụng beacon ngẫu nhiên drand để cung cấp các số ngẫu nhiên an toàn và có thể xác minh cho các hợp đồng thông minh trên blockchain Kaia.
Bộ sinh số ngẫu nhiên đã được xác minh (vRNG) được tối ưu hóa để cung cấp số ngẫu nhiên với độ trễ thấp, giúp giảm thiểu độ trễ của ứng dụng. Nó được thiết kế với sự chú trọng đặc biệt vào độ tin cậy và khả năng mở rộng.

Đăng ký
Trong giai đoạn truy cập sớm, tất cả người dùng của hệ thống Sinh số ngẫu nhiên đã được xác minh (Verified Random Number Generator) phải được đăng ký thủ công. Để sử dụng nó, địa chỉ hợp đồng của bạn phải được phê duyệt, nếu không, bất kỳ yêu cầu nào cũng sẽ bị hủy bỏ.
Các đội có thể yêu cầu phê duyệt bằng cách nộp đơn qua biểu mẫu chính thức hoặc liên hệ trực tiếp với đội ngũ Kaia, tùy theo phương án nào thuận tiện hơn.
Địa chỉ hợp đồng vRNG
| Mạng | Địa chỉ | Địa chỉ URL API |
|---|---|---|
| Mạng chính Kaia | 0xf628f7843d94064c5072704a53b9ec455bcc4abb | https://vrf.proofofplay.com/v1 |
| Mạng thử nghiệm Kairos | 0xd14d984603b0b7ade91be52f3fc4a917dfa77bcd | https://staging.vrf.proofofplay.com/v1 |
Cách sử dụng
Yêu cầu một số ngẫu nhiên
Giao diện sau đây cung cấp một phương thức để yêu cầu các số ngẫu nhiên.
Hợp đồng của bạn có thể gọi hệ thống VRFSystem được triển khai trên mỗi chuỗi. Bạn có thể tùy chọn cung cấp một traceId, sẽ được gắn vào mỗi sự kiện (Hữu ích nếu bạn có một giao dịch thực hiện nhiều bước, người dùng có thể theo dõi giao dịch của họ trên chuỗi). Điều này không bắt buộc và có thể để nguyên là 0.
// SPDX-License-Identifier: MIT LICENSEpragma 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); }
Gọi lại số ngẫu nhiên
Mỗi số ngẫu nhiên được yêu cầu sẽ được cung cấp ngay khi số đầu tiên từ drand có sẵn để cung cấp. Quá trình này có thể mất tới 3 giây.
Cuộc gọi của bạn sẽ được kết nối với số điện thoại đầu tiên sau khi yêu cầu đầu tiên của bạn cho số ngẫu nhiên (ForRandomNumber) đã được gửi đi. Điều này đảm bảo rằng số không thể được biết trước khi người dùng yêu cầu số ngẫu nhiên.
// SPDX-License-Identifier: MIT LICENSEpragma 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; }
Nếu tôi muốn có các số khác nhau trong cùng một khoảng thời gian 3 giây thì sao?
Theo mặc định, chúng tôi trả về cùng một số cho tất cả các yêu cầu trong cùng một khoảng thời gian 3 giây mà drand cung cấp. Điều này thật tuyệt vời khi có thể xác minh, nhưng nếu bạn muốn các người dùng có các số khác nhau trong khoảng thời gian này, chúng tôi khuyên bạn nên thêm một nguồn entropy.
Dưới đây là một số ví dụ về việc sử dụng các số ngẫu nhiên duy nhất cho mỗi giao dịch.
// 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))
Những giá trị này không được đảm bảo là đã được chuẩn hóa, nhưng sẽ giữ nguyên các tính chất ngẫu nhiên của các giá trị ở trên. Chúng tôi khuyến nghị điều chỉnh theo ý muốn của bạn để đạt được mức độ chuẩn hóa cao hơn hoặc thấp hơn (ví dụ: thêm sequenceId vào randomNumber sẽ khiến kết quả bị lệch rất nhiều, trong khi sử dụng blockhash sẽ khiến kết quả được chuẩn hóa rất cao).
Nếu bạn muốn có các số khác nhau trong cùng một khối, chúng tôi khuyến nghị bạn nên tái băm cùng một số nhiều lần trong cùng một giao dịch.
functionThatUsesNumber(randomNumber); randomNumber = uint256(keccak256(randomNumber)); functionThatUsesNumber(randomNumber);
Nếu tôi muốn có các số khác nhau trong cùng một giao dịch thì sao?
Theo mặc định, chúng tôi sẽ chỉ cung cấp cho bạn một số duy nhất cho mỗi giao dịch. Chúng tôi khuyến khích các nhà phát triển sử dụng số này để suy ra các số khác từ nó nhằm tạo ra các số mới.
//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
Sự kiện Blockchain
Hợp đồng sẽ phát sinh các sự kiện sau đây.
/// @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);
Bạn có thể tra cứu các sự kiện này ở cấp độ RPC để xem liệu chúng đã được gửi hay chưa, hoặc sử dụng trình khám phá khối để xem luồng sự kiện.
Xác minh số tròn / số ngẫu nhiên bằng drand
Nếu bạn muốn xác minh số ngẫu nhiên, bạn có thể kiểm tra trực tiếp với drand cho mục đích này. Chúng tôi sử dụng quicknet của drand cho việc này.
Ví dụ, để xem số tròn 11:
GET https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/11
{ "round": 11, "randomness": "ebdcbfe855d10c56db22455fa5a18963c1f62d85f859c35c310273449b49d284", "signature": "163d14081e191a3f5d81e2f580eab591ea608402fda4f6e44b5a0bde11e368070e77d07ad3240726ea33e410c84d4b09ea0a4a0291f6c3c485d8630e1c0edf0a" }
Chúng ta có thể thấy ở đây số ngẫu nhiên dưới dạng hex là ebdcbfe855d10c56db22455fa5a18963c1f62d85f859c35c310273449b49d284