Introduction
Chainlink Verifiable Random Function (Chainlink VRF) của là một bộ sinh số ngẫu nhiên có thể xác thực cho phép các smart contract truy cập đến các giá trị ngẫu nhiên off-chain mà không làm ảnh hưởng đến sự bảo mật và khả năng sử dụng của nó.
Với mỗi random number request, sẽ có một hoặc nhiều giá trị ngẫu nhiên được tạo ra và đi kèm với chúng là các bằng chứng mật mã (cryptographic proof) cho biết cách mà các giá trị ngẫu nhiên được hình thành.
Cryptographic proof sẽ được công khai và được xác thực on-chain trước khi các ứng dụng có thể sử dụng. Điều này đảm bảo các giá trị ngẫu nhiên không bị giả mạo hoặc thao túng bởi một thực thể nào đó, bao gồm các oracle operators, miner, user hoặc các smart contract developer.
Chainlink VRF hoạt động theo Basic Request Model.
Two Methods to Request Randomness
Chainlink hỗ trợ hai cách để request số ngẫu nhiên:
- Subscription: tạo một subscription1 và nạp vào một lượng LINK nhất định. Sau đó, chúng ta có thể kết nối đến nhiều consuming contract (consumer). Các consumer sẽ giúp chúng ta gửi request đến Chainlink VRF oracle2.
- Sử dụng cách này nếu cần gửi nhiều request thường xuyên.
- Không cần phải ước tính phí giao dịch mà chỉ cần đảm bảo subscription có đủ LINK token.
- Khuyến khích sử dụng cách này vì ta không cần phải thực hiện rút LINK token từ các consuming contract mà không còn được sử dụng.
- Direct funding: sử dụng consuming contract để gửi request đến Chainlink VRF oracle3.
- Sử dụng cách này nếu gửi các request rời rạc không thường xuyên.
- Cần phải ước tính phí giao dịch cẩn thận và đảm bảo consuming contract có đủ LINK token.
Important
Lưu ý: cần phải chuyển vào subscription hay consuming contract một lượng LINK token tối thiểu thì mới có thể sử dụng.
Get a Random Number
Sau khi deploy được các consuming contract và nạp LINK token thì chúng ta có thể tương tác với các consuming contract (bằng Ethers) theo các bước sau:
-
Gọi thực thi hàm
requestRandomWords
của consuming contract. Hàm này sẽ gửi request đến oracle contract và trả về ID của request.Minh họa:
async requestRandomNumber() { const tx = await this.contract.requestRandomWords(); console.log('Transaction hash: ', tx.hash); }
-
Sau đó, ta gọi thực thi getter
lastRequestId
để lấy request ID mới nhất.Minh họa:
async getLatestRequestId() { const latestRequestId = await this.contract.latestRequestId(); console.log('Latest request id: ', latestRequestId.toString()); }
-
Cuối cùng, truyền request ID này vào hàm
getRequestStatus
để nhận về trạng thái của request (request status). Lưu ý: cần đợi một lúc thì request mới được fulfilled. Khi đó, các số ngẫu nhiên sẽ nằm ở trong mảngrandomWords
của request status.Minh họa:
async getRandomNumbers(requestId: BigInt) { const requestStatus = await this.contract.getRequestStatus(requestId); if (requestStatus.fulfilled) { this.randomNumbers.push(...requestStatus.randomWords); this.randomNumbers.forEach((randomNumber) => { console.log(randomNumber.toString()); }); } else { console.log('Request is not fulfilled yet'); } }
Tip
- Luôn fund consuming contract của Oracle trước khi gọi thực thi.
- Luôn đảm bảo có hàm withdraw trong consuming contract.
- Có thể specify gas limit nếu xảy ra lỗi không thể estimate gas.
Footnotes
-
Tạo ở đây VRF | Subscription Management (chain.link). Nhớ chú ý lưu lại subcription ID vì ta sẽ truyền giá trị này vào constructor của consuming contract khi deploy. ↩
-
Tham khảo thêm sample consuming contract của subscription: VRFv2Consumer.sol. ↩
-
Tham khảo thêm sample consuming contract của direct funding: VRFv2DirectFundingConsumer.sol. ↩