5. Advanced item sale structure

Another interesting sale structure is to run a sale with a lootbox component. Each lootbox can be traded just like regular items — but they can also be "opened" to redeem the actual game item. For example, a game might want to issue a pack of items randomly generating an item of a certain ability level, or a set of cards with some probability of getting a "mythic" or "legendary" card.

To do this, you can create an ERC721-compliant LootBox contract. You can mint these LootBox as you would normal ERC721 NFT's, which means they can be instantly listable on OpenSea. These NFT's will simply implement the unpack method, which burns the LootBox and mints a new NFT of the item.

As an example, if we were to implement a CryptoPuff presale, we could create a CryptoPuffPreSaleItem that inherits from ERC721Token. In the unpack method, it would create new CryptoPuffs according to some pseudo-random logic.

 * @title CreatureLootBox
 * CreatureLootBox - a tradeable loot box of Creatures.
contract CreatureLootBox is TradeableERC721Token {
    uint256 NUM_CREATURES_PER_BOX = 3;
    uint256 OPTION_ID = 0;
    address factoryAddress;

    function unpack(uint256 _tokenId) public {
        require(ownerOf(_tokenId) == msg.sender);

        // Insert custom logic for configuring the item here.
        for (uint256 i = 0; i < NUM_CREATURES_PER_BOX; i++) {
            // Mint the ERC721 item(s).
            Factory factory = Factory(factoryAddress);
            factory.mint(OPTION_ID, msg.sender);

        // Burn the presale item.
        _burn(msg.sender, _tokenId);

Check out the full code on Github.

Tradeable packs

If you want your presale packs themselves to be tradeable, there's no extra configuration required. You can sell your presale packs on OpenSea (using fixed price, Dutch auctions, English auction, or even bundles), or through our SDK. You'll just need a way for users to unpack the packs on your site.