Description

Usually with ERC721 contracts, a single contract is used for an NFT collection. While it is possible to do that with the proposed implementation for ERC1238, we can go further and take advantage of the benefits brought by modelling it after ERC115 and allow for multiple NFT collections to live inside the same contract. Each collection is represented by a baseId.

Example scenario: Let’s imagine a single contract for different courses, each identified by a baseId. This extension lets you create certificates for a course where each certificate has a unique id but also a reference to the baseId it belongs to. As a result, one is able to lookup if an account holds a certificate for a specific course by querying by baseId.

How it works

This extension lets you create “semi-fungible” tokens, which are non-fungible tokens with a shared baseId embedded in their token id using bit packing. This is how each token has a reference to a baseId.

Here’s how values are packed in the id (which is 256 bits in total): [baseId (48 bits)][owner (160 bits)][counter (48 bits)]

<aside> 💡 The token owner’s address is included to construct the token Id but there is no validation done, i.e nothing prevents someone from minting to address A a token Id which includes address B. Should this extension be more opinionated and enforce validation?

</aside>

Account balances for each baseId are tracked via a mapping.

Interface

Querying an account’s balance for a given baseId

/**
 * @dev Returns the balance of an address for a specific baseId.
 */
function balanceFromBaseId(address account, uint48 baseId) external view returns (uint256);

Token ID construction