【发布时间】:2025-12-08 17:00:02
【问题描述】:
我正在创建一个 nft 集合,我希望随机所有者在每个铸币厂收到一定百分比的铸币厂价格。但是由于我需要等待 VRF 响应,所以无法弄清楚如何实现随机函数以及将百分比发送到 vrf 响应(随机所有者)的函数。
pragma solidity >=0.7.0 <0.9.0;
import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
contract Sofb is ERC721Enumerable, Ownable, VRFConsumerBase {
using Strings for uint256;
string baseURI;
string public baseExtension = ".json";
uint256 public cost = 0.015 ether;
uint256 public maxSupply = 7070;
uint256 public tokenCounter;
bool public paused = false;
bool public revealed = false;
string public notRevealedUri;
bytes32 internal keyHash;
uint256 internal fee;
uint256 public randomResult = 0;
address payable giftAddress = payable(msg.sender);
uint256 giftValue = 0;
mapping(bytes32 => uint256) public requestIdToRandomNumber;
mapping(bytes32 => address) public requestIdToAddress;
mapping(bytes32 => uint256) public requestIdToRequestNumberIndex;
uint256 public requestCounter;
constructor(string memory _name, string memory _symbol, string memory _initBaseURI, string memory _initNotRevealedUri, address _vrfCoordinator, address _linkToken, bytes32 _keyHash, uint256 _fee)
VRFConsumerBase(_vrfCoordinator, _linkToken)
ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
setNotRevealedURI(_initNotRevealedUri);
keyHash = _keyHash;
fee = _fee;
}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
// public
function getRandomNumber() public returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
requestIdToAddress[requestId] = msg.sender;
requestIdToRequestNumberIndex[requestId] = requestCounter;
requestCounter += 1;
return requestRandomness(keyHash, fee);
}
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
requestIdToRandomNumber[requestId] = randomness;
uint256 requestNumber = requestIdToRequestNumberIndex[requestId];
}
function mint() public payable {
uint256 supply = totalSupply();
require(!paused);
require(supply + 1 <= maxSupply);
require(msg.value >= cost);
if (msg.sender != owner()) {
require(msg.value >= cost);
}
if (supply > 0) {
require(randomResult > 0);
giftAddress = payable(ownerOf(randomResult));
giftValue = ((supply + 1 == 5) || (supply + 1 == 10)) ? address(this).balance * 1 / 100 : msg.value * 10 / 100;
(bool success, ) = payable(giftAddress).call{value: giftValue}("");
require(success);
}
_safeMint(msg.sender, supply + 1);
getRandomNumber();
}
...
}
【问题讨论】:
-
这个怎么样? 1.创建所有者映射; 2. 将映射长度存储为 uint 变量并适当地递增/递减它; 3、用户发起铸币交易时,在所有require语句后,根据mappingLength变量在范围内调用VRF; 4. 在fulfillRandomness 内部创建一个新的token,并根据回调数字从映射中将铸币价格的百分比发送给随机所有者
-
@Andrej,您是否愿意将其发布为答案,甚至可能带有一些伪代码?
标签: solidity smartcontracts nft chainlink