Skip to content

Commit 1020004

Browse files
"Get a random number" V2.5 tutorials and 1.1.1 cleanup (#1954)
* Add baseline files * sub: updated most refs * fix link * df: updated most refs * Updated ref and added V2 billing back to nav * add v2 billing back to nav * fix link * Pass param to toggle nativePayment on and off in requestRandomWords * Explain new param, update programmatic sub v2 links * fix links * 1.1.1 change * Unflatten DirectFundingConsumer.sol for 1.1.1 * left nav adj * fix links * Direct funding updates for tutorial and migration guide * Release note about 1.1.1 and more migration page edits * Subscription tutorial image edits, formatting on migration page? * Update cost figures in tutorials
1 parent 4e1fb44 commit 1020004

File tree

11 files changed

+449
-271
lines changed

11 files changed

+449
-271
lines changed
Loading
Loading

public/samples/VRF/v2-5/DirectFundingConsumer.sol

Lines changed: 40 additions & 221 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pragma solidity 0.8.19;
44

55
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
66
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
7+
import {VRFV2PlusWrapperConsumerBase} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol";
78
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
89

910
/**
@@ -17,215 +18,6 @@ import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/V
1718
* DO NOT USE THIS CODE IN PRODUCTION.
1819
*/
1920

20-
/**
21-
* Import IVRFV2PlusWrapper which is not yet available in the chainlink/contracts package.
22-
* https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/vrf/dev/interfaces/IVRFV2PlusWrapper.sol
23-
*/
24-
25-
interface IVRFV2PlusWrapper {
26-
/**
27-
* @return the request ID of the most recent VRF V2 request made by this wrapper. This should only
28-
* be relied option within the same transaction that the request was made.
29-
*/
30-
function lastRequestId() external view returns (uint256);
31-
32-
/**
33-
* @notice Calculates the price of a VRF request with the given callbackGasLimit at the current
34-
* @notice block.
35-
*
36-
* @dev This function relies on the transaction gas price which is not automatically set during
37-
* @dev simulation. To estimate the price at a specific gas price, use the estimatePrice function.
38-
*
39-
* @param _callbackGasLimit is the gas limit used to estimate the price.
40-
* @param _numWords is the number of words to request.
41-
*/
42-
function calculateRequestPrice(
43-
uint32 _callbackGasLimit,
44-
uint32 _numWords
45-
) external view returns (uint256);
46-
47-
/**
48-
* @notice Calculates the price of a VRF request in native with the given callbackGasLimit at the current
49-
* @notice block.
50-
*
51-
* @dev This function relies on the transaction gas price which is not automatically set during
52-
* @dev simulation. To estimate the price at a specific gas price, use the estimatePrice function.
53-
*
54-
* @param _callbackGasLimit is the gas limit used to estimate the price.
55-
* @param _numWords is the number of words to request.
56-
*/
57-
function calculateRequestPriceNative(
58-
uint32 _callbackGasLimit,
59-
uint32 _numWords
60-
) external view returns (uint256);
61-
62-
/**
63-
* @notice Estimates the price of a VRF request with a specific gas limit and gas price.
64-
*
65-
* @dev This is a convenience function that can be called in simulation to better understand
66-
* @dev pricing.
67-
*
68-
* @param _callbackGasLimit is the gas limit used to estimate the price.
69-
* @param _numWords is the number of words to request.
70-
* @param _requestGasPriceWei is the gas price in wei used for the estimation.
71-
*/
72-
function estimateRequestPrice(
73-
uint32 _callbackGasLimit,
74-
uint32 _numWords,
75-
uint256 _requestGasPriceWei
76-
) external view returns (uint256);
77-
78-
/**
79-
* @notice Estimates the price of a VRF request in native with a specific gas limit and gas price.
80-
*
81-
* @dev This is a convenience function that can be called in simulation to better understand
82-
* @dev pricing.
83-
*
84-
* @param _callbackGasLimit is the gas limit used to estimate the price.
85-
* @param _numWords is the number of words to request.
86-
* @param _requestGasPriceWei is the gas price in wei used for the estimation.
87-
*/
88-
function estimateRequestPriceNative(
89-
uint32 _callbackGasLimit,
90-
uint32 _numWords,
91-
uint256 _requestGasPriceWei
92-
) external view returns (uint256);
93-
94-
/**
95-
* @notice Requests randomness from the VRF V2 wrapper, paying in native token.
96-
*
97-
* @param _callbackGasLimit is the gas limit for the request.
98-
* @param _requestConfirmations number of request confirmations to wait before serving a request.
99-
* @param _numWords is the number of words to request.
100-
*/
101-
function requestRandomWordsInNative(
102-
uint32 _callbackGasLimit,
103-
uint16 _requestConfirmations,
104-
uint32 _numWords,
105-
bytes calldata extraArgs
106-
) external payable returns (uint256 requestId);
107-
108-
function link() external view returns (address);
109-
110-
function linkNativeFeed() external view returns (address);
111-
}
112-
113-
/**
114-
* Import VRFV2PlusWrapperConsumerBase which is not yet available in the chainlink/contracts package.
115-
* https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol
116-
*/
117-
118-
abstract contract VRFV2PlusWrapperConsumerBase {
119-
error OnlyVRFWrapperCanFulfill(address have, address want);
120-
121-
LinkTokenInterface internal immutable i_linkToken;
122-
IVRFV2PlusWrapper public immutable i_vrfV2PlusWrapper;
123-
124-
/**
125-
* @param _vrfV2PlusWrapper is the address of the VRFV2Wrapper contract
126-
*/
127-
constructor(address _vrfV2PlusWrapper) {
128-
IVRFV2PlusWrapper vrfV2PlusWrapper = IVRFV2PlusWrapper(
129-
_vrfV2PlusWrapper
130-
);
131-
132-
i_linkToken = LinkTokenInterface(vrfV2PlusWrapper.link());
133-
i_vrfV2PlusWrapper = vrfV2PlusWrapper;
134-
}
135-
136-
/**
137-
* @dev Requests randomness from the VRF V2+ wrapper.
138-
*
139-
* @param _callbackGasLimit is the gas limit that should be used when calling the consumer's
140-
* fulfillRandomWords function.
141-
* @param _requestConfirmations is the number of confirmations to wait before fulfilling the
142-
* request. A higher number of confirmations increases security by reducing the likelihood
143-
* that a chain re-org changes a published randomness outcome.
144-
* @param _numWords is the number of random words to request.
145-
*
146-
* @return requestId is the VRF V2+ request ID of the newly created randomness request.
147-
*/
148-
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
149-
function requestRandomness(
150-
uint32 _callbackGasLimit,
151-
uint16 _requestConfirmations,
152-
uint32 _numWords,
153-
bytes memory extraArgs
154-
) internal returns (uint256 requestId, uint256 reqPrice) {
155-
reqPrice = i_vrfV2PlusWrapper.calculateRequestPrice(
156-
_callbackGasLimit,
157-
_numWords
158-
);
159-
i_linkToken.transferAndCall(
160-
address(i_vrfV2PlusWrapper),
161-
reqPrice,
162-
abi.encode(
163-
_callbackGasLimit,
164-
_requestConfirmations,
165-
_numWords,
166-
extraArgs
167-
)
168-
);
169-
return (i_vrfV2PlusWrapper.lastRequestId(), reqPrice);
170-
}
171-
172-
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
173-
function requestRandomnessPayInNative(
174-
uint32 _callbackGasLimit,
175-
uint16 _requestConfirmations,
176-
uint32 _numWords,
177-
bytes memory extraArgs
178-
) internal returns (uint256 requestId, uint256 requestPrice) {
179-
requestPrice = i_vrfV2PlusWrapper.calculateRequestPriceNative(
180-
_callbackGasLimit,
181-
_numWords
182-
);
183-
return (
184-
i_vrfV2PlusWrapper.requestRandomWordsInNative{value: requestPrice}(
185-
_callbackGasLimit,
186-
_requestConfirmations,
187-
_numWords,
188-
extraArgs
189-
),
190-
requestPrice
191-
);
192-
}
193-
194-
/**
195-
* @notice fulfillRandomWords handles the VRF V2 wrapper response. The consuming contract must
196-
* @notice implement it.
197-
*
198-
* @param _requestId is the VRF V2 request ID.
199-
* @param _randomWords is the randomness result.
200-
*/
201-
// solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore
202-
function fulfillRandomWords(
203-
uint256 _requestId,
204-
uint256[] memory _randomWords
205-
) internal virtual;
206-
207-
function rawFulfillRandomWords(
208-
uint256 _requestId,
209-
uint256[] memory _randomWords
210-
) external {
211-
address vrfWrapperAddr = address(i_vrfV2PlusWrapper);
212-
if (msg.sender != vrfWrapperAddr) {
213-
revert OnlyVRFWrapperCanFulfill(msg.sender, vrfWrapperAddr);
214-
}
215-
fulfillRandomWords(_requestId, _randomWords);
216-
}
217-
218-
/// @notice getBalance returns the native balance of the consumer contract
219-
function getBalance() public view returns (uint256) {
220-
return address(this).balance;
221-
}
222-
223-
/// @notice getLinkToken returns the link token contract
224-
function getLinkToken() public view returns (LinkTokenInterface) {
225-
return i_linkToken;
226-
}
227-
}
228-
22921
contract DirectFundingConsumer is VRFV2PlusWrapperConsumerBase, ConfirmedOwner {
23022
event RequestSent(uint256 requestId, uint32 numWords);
23123
event RequestFulfilled(
@@ -260,27 +52,40 @@ contract DirectFundingConsumer is VRFV2PlusWrapperConsumerBase, ConfirmedOwner {
26052
// Cannot exceed VRFV2Wrapper.getConfig().maxNumWords.
26153
uint32 numWords = 2;
26254

263-
// Address LINK - hardcoded for Arbitrum Sepolia
264-
address linkAddress = 0xb1D4538B4571d411F07960EF2838Ce337FE1E80E;
55+
// Address LINK - hardcoded for Sepolia
56+
address linkAddress = 0x779877A7B0D9E8603169DdbD7836e478b4624789;
26557

266-
// address WRAPPER - hardcoded for Arbitrum Sepolia
267-
address wrapperAddress = 0x29576aB8152A09b9DC634804e4aDE73dA1f3a3CC;
58+
// address WRAPPER - hardcoded for Sepolia
59+
address wrapperAddress = 0x195f15F2d49d693cE265b4fB0fdDbE15b1850Cc1;
26860

26961
constructor()
27062
ConfirmedOwner(msg.sender)
27163
VRFV2PlusWrapperConsumerBase(wrapperAddress)
27264
{}
27365

274-
function requestRandomWords() external onlyOwner returns (uint256) {
66+
function requestRandomWords(
67+
bool enableNativePayment
68+
) external onlyOwner returns (uint256) {
27569
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
276-
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
277-
);
278-
(uint256 requestId, uint256 reqPrice) = requestRandomness(
279-
callbackGasLimit,
280-
requestConfirmations,
281-
numWords,
282-
extraArgs
70+
VRFV2PlusClient.ExtraArgsV1({nativePayment: enableNativePayment})
28371
);
72+
uint256 requestId;
73+
uint256 reqPrice;
74+
if (enableNativePayment) {
75+
(requestId, reqPrice) = requestRandomnessPayInNative(
76+
callbackGasLimit,
77+
requestConfirmations,
78+
numWords,
79+
extraArgs
80+
);
81+
} else {
82+
(requestId, reqPrice) = requestRandomness(
83+
callbackGasLimit,
84+
requestConfirmations,
85+
numWords,
86+
extraArgs
87+
);
88+
}
28489
s_requests[requestId] = RequestStatus({
28590
paid: reqPrice,
28691
randomWords: new uint256[](0),
@@ -328,4 +133,18 @@ contract DirectFundingConsumer is VRFV2PlusWrapperConsumerBase, ConfirmedOwner {
328133
"Unable to transfer"
329134
);
330135
}
136+
137+
/// @notice withdrawNative withdraws the amount specified in amount to the owner
138+
/// @param amount the amount to withdraw, in wei
139+
function withdrawNative(uint256 amount) external onlyOwner {
140+
(bool success, ) = payable(owner()).call{value: amount}("");
141+
// solhint-disable-next-line gas-custom-errors
142+
require(success, "withdrawNative failed");
143+
}
144+
145+
event Received(address, uint256);
146+
147+
receive() external payable {
148+
emit Received(msg.sender, msg.value);
149+
}
331150
}

public/samples/VRF/v2-5/SubscriptionConsumer.sol

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,12 @@ contract SubscriptionConsumer is VRFConsumerBaseV2Plus {
6767
}
6868

6969
// Assumes the subscription is funded sufficiently.
70-
function requestRandomWords()
71-
external
72-
onlyOwner
73-
returns (uint256 requestId)
74-
{
70+
// @param enableNativePayment: Set to `true` to enable payment in native tokens, or
71+
// `false` to pay in LINK
72+
function requestRandomWords(
73+
bool enableNativePayment
74+
) external onlyOwner returns (uint256 requestId) {
7575
// Will revert if subscription is not set and funded.
76-
// To enable payment in native tokens, set nativePayment to true.
7776
requestId = s_vrfCoordinator.requestRandomWords(
7877
VRFV2PlusClient.RandomWordsRequest({
7978
keyHash: keyHash,
@@ -82,7 +81,9 @@ contract SubscriptionConsumer is VRFConsumerBaseV2Plus {
8281
callbackGasLimit: callbackGasLimit,
8382
numWords: numWords,
8483
extraArgs: VRFV2PlusClient._argsToBytes(
85-
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
84+
VRFV2PlusClient.ExtraArgsV1({
85+
nativePayment: enableNativePayment
86+
})
8687
)
8788
})
8889
);

0 commit comments

Comments
 (0)