【问题标题】:How can I implement chainlink vrf with giving reward to a RANDOM owner of my nft when someone mints it?当有人铸造它时,我如何实现chainlink vrf并奖励我的nft的随机所有者?
【发布时间】: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


【解决方案1】:

您应该铸造令牌并将铸造逻辑放入fulfillRandomness 函数中,以访问您需要的数据,我建议您拥有一个包含所需数据的结构数组,记住random 返回一个requestId,使用请求 id 作为索引以获取存储的数据然后对其进行铸造,如果您想在铸造 nft 后删除数据,则由您自己决定

【讨论】:

    最近更新 更多