-
Notifications
You must be signed in to change notification settings - Fork 0
/
MyVRF.sol
125 lines (105 loc) · 4.15 KB
/
MyVRF.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// SPDX-License-Identifier: MIT
// An example of a consumer contract that also owns and manages the subscription
pragma solidity >=0.4.0 <0.9.0;
import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract MyVRF is VRFConsumerBaseV2 {
VRFCoordinatorV2Interface COORDINATOR;
LinkTokenInterface LINKTOKEN;
// A reasonable default is 100000, but this value could be different
// on other networks.
uint32 callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 requestConfirmations = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFCoordinatorV2.MAX_NUM_WORDS.
uint32 numWords = 1;
// Addresses
address vrfCoordinator;
address link_token_contract;
bytes32 keyHash;
// Storage parameters
uint256[] public s_randomWords;
uint256 public s_requestId;
uint64 public s_subscriptionId;
address s_owner;
constructor(
address _vrfCoordinator,
address _link,
bytes32 _keyHash
) VRFConsumerBaseV2(_vrfCoordinator) {
link_token_contract = _link;
keyHash = _keyHash;
vrfCoordinator = _vrfCoordinator;
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
LINKTOKEN = LinkTokenInterface(link_token_contract);
s_owner = msg.sender;
//Create a new subscription when you deploy the contract.
//createNewSubscription();
}
// Assumes the subscription is funded sufficiently.
function requestRandomWords() public onlyOwner {
// Will revert if subscription is not set and funded.
s_requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
}
function fulfillRandomWords(
uint256, /* requestId */
uint256[] memory randomWords
) internal virtual override {
s_randomWords = randomWords;
}
function getRandom() public view onlyOwner returns (uint256[] memory) {
return s_randomWords;
}
// Create a new subscription when the contract is initially deployed.
function createNewSubscription() public onlyOwner {
s_subscriptionId = COORDINATOR.createSubscription();
// Add this contract as a consumer of its own subscription.
}
function getSubscriptionID() public view onlyOwner returns (uint64) {
return s_subscriptionId;
}
// Assumes this contract owns link.
// 1000000000000000000 = 1 LINK
function topUpSubscription(uint256 amount) external onlyOwner {
LINKTOKEN.transferAndCall(
address(COORDINATOR),
amount,
abi.encode(s_subscriptionId)
);
}
function addConsumer(address consumerAddress) public onlyOwner {
// Add a consumer contract to the subscription.
COORDINATOR.addConsumer(s_subscriptionId, consumerAddress);
}
function removeConsumer(address consumerAddress) external onlyOwner {
// Remove a consumer contract from the subscription.
COORDINATOR.removeConsumer(s_subscriptionId, consumerAddress);
}
function cancelSubscription(address receivingWallet) external onlyOwner {
// Cancel the subscription and send the remaining LINK to a wallet address.
COORDINATOR.cancelSubscription(s_subscriptionId, receivingWallet);
s_subscriptionId = 0;
}
// Transfer this contract's funds to an address.
// 1000000000000000000 = 1 LINK
function withdraw(uint256 amount, address to) external onlyOwner {
LINKTOKEN.transfer(to, amount);
}
modifier onlyOwner() {
require(msg.sender == s_owner);
_;
}
}