2. Custom sale contract — Introduction
Introduction to the factory contract
The downside of the simple item sale is that you'll need pre-mint the items that you want to sell (as opposed to minting them on the fly when they're purchased). This can make it difficult to sell many items to a broad user base. Additionally, with the simple item sale method, it's difficult to create custom logic for the sale of your items (like packs of random items, randomized stats for the items that are minted, etc.). If you want any of these features, the Factory
contract is for you!
In order to mint items only when they're purchased, OpenSea provides a Factory
interface that you can use to define how your items will be minted. You then use OpenSea to create custom "orders" that call your minting function. Here's a look at the main mint
method of the Factory
contract.
interface Factory {
...
/**
* @dev Mints asset(s) in accordance to a specific address with a particular "option".
* Options should also be delineated 0 - (numOptions() - 1) for convenient indexing.
* @param _optionId the option id
* @param _toAddress address of the future owner of the asset(s)
*/
function mint(uint256 _optionId, address _toAddress) external;
}
The mint
method takes in an _optionId
and a _toAddress
. The _toAddress
is the address to which the items will be minted. The _optionId
is a unique identifier used by the mint method to distinguish what logic to call to mint the items. For example, _optionId
1 might mint a single item, while _optionId
2 might mint several random items. It's really up to you what you want your options to do! Since you can include any logic in the mint
method, the possibilities are limitless!
OpenSea Creature Sale Example
To make this more concrete, let's look at an example. In the OpenSea creature factory, we have three different options:
- Option 0: Mint a single creature
- Option 1: Mint four creatures all at once
- Option 2: Mint a lootbox of creatures
Here's what the code looks like for that logic:
function mint(uint256 _optionId, address _toAddress) public {
Creature openSeaCreature = Creature(nftAddress);
if (_optionId == SINGLE_CREATURE_OPTION) {
openSeaCreature.mintTo(_toAddress);
} else if (_optionId == MULTIPLE_CREATURE_OPTION) {
for (uint256 i = 0; i < NUM_CREATURES_IN_MULTIPLE_CREATURE_OPTION; i++) {
openSeaCreature.mintTo(_toAddress);
}
} else if (_optionId == LOOTBOX_OPTION) {
CreatureLootBox openSeaCreatureLootBox = CreatureLootBox(lootBoxNftAddress);
openSeaCreatureLootBox.mintTo(_toAddress);
}
}
This means that when you call mint(0, <destination_address>)
, the destination address will receive one new OpenSea creature, when you call mint(1, <destination_address>)
, the destination address will receive four new OpenSea creatures, etc.
If you'd like to deploy the OpenSea Creature example contract yourself, simply check out the OpenSea Creatures Github repository and uncomment the lines in migrations/deploy_contracts.js
(you'll want to comment out the line above it as well, as your newly uncommented code will also deploy the Creature NFT).
As we'll learn in the next section, each option will have a dedicated page on OpenSea and (excitingly) can be sold in any of the many ways that regular items can be sold on OpenSea!
Updated 7 months ago