3

I'm looking to have an ERC1155 smart contract with a set number of tokens, each with their own max supply, and when a user mints it selects randomly from the available tokens.

Creating the 5 tokens (for example) I'm fine with. I have an ownerOnly createToken function that will mint a quantity of 1 of the new token to the owner and set the max supply for the new id which is just a custom mapping mapping(uint256 => uint256) private _maxSupply;

So now I have for example token ids 0 - 4, with a total supply of 1 for each of them and a max supply of 100 of each.

When somebody wants to mint I'd like to randomly select from the available tokens, taking into account total supply and max supply, and would like to use Chainlink VRF for the randomness.

Given the _mint and _mintBatch functions in ERC1155 require the token id(s) am thinking the public payable function would be something like a startMint call to request the randomness, and the actual mint would occur later when the randomness is fulfilled.

I'm just stuck on a) how to get multiple random numbers when a user is minting more than one token; and b) the best / most efficient way to select the random tokens while keeping track of availability with each selection and then finally calling _mint or _batchMint with relevant tokenId(s) and qty(s).

I've written the following for the startMint. The requestToQuantity and requestToSender are custom mappings so I can match up later for the mint.

function startMint( uint256 quantity, uint256 userProvidedSeed )
    public
    payable
    whenNotPaused
    returns (bytes32)
    {
        // validations etc and payment amount checks
        // ...

        bytes32 requestId = requestRandomness( keyHash, fee, userProvidedSeed );
        requestToQuantity[requestId] = quantity;
        requestToSender[requestId] = msg.sender;

        return requestId;
    }

And I've started the fulfillRandomness function. Any help or guidance with this would be hugely appreciated.

function fulfillRandomness( bytes32 requestId, uint256 randomNumber )
    internal
    override
    {
        // TODO: determine the available token ids (using _totalSupply[id] and _maxSupply[id] mappings)

        uint256 qty = requestToQuantity[requestId];
        address to = requestToSender[requestId];

        if ( qty == 1 ) {
            // TODO: pick a random available token id
            // _safeMint( to, id, 1, "" );
        }
        else if ( qty > 1 ) {
            // TODO: pick multiple random available token ids
            // keeping track of availability with each selection
            // _mintBatch(to, ids, amounts, "");
        } 

 
    }
2
  • have you completed it? can I see the contract? Commented Nov 1, 2022 at 18:12
  • @CypherArts the project went in a different direction and I didn't end up going with any of this randomness
    – nifty
    Commented Nov 3, 2022 at 0:19

1 Answer 1

1

For (a) you could look either into pseudo randomness approaches or Chainlink VRFv2 (see "Getting multiple random values"): https://docs.chain.link/docs/chainlink-vrf-best-practices/

For (b) this answer might help: https://ethereum.stackexchange.com/a/119121/82355

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.