This repository contains the Solidity contracts, deployment scripts, and metadata deployment to IPFS for Musee-Dezentral NFTs.
This is a hardhat and Yarn project which builds and deploys an ERC-721 compatible NFT called Frame, targeted for Ethereum/EVM compatible networks.
Create your own .env
file in the root folder with the naming convention .env.<network>
(e.g. .env.rinkeby
), with the following environment variable definitions:
MNEMONIC=<your 12 word Ethereum mnemonic phrase>
INFURA_ID=<your Infura account ID, for deploying>
INFURA_SECRET=<your Infura account secret, for deploying>
PINATA_KEY=<your Pinata account key, for uploading and pinning metadata>
PINATA_SECRET=<your Pinata account secret, for uploading and pinning metadata>
yarn build
yarn test
Note: test
folder uses a small set of dummy images and metadata to test IPFS upload utilities, and Frame Solidity functionality and requires internet connectivity.
yarn deploy
yarn deploy:rinkeby
yarn deploy:mainnet
Contract | Usage |
---|---|
abstract/Exhibitionable.sol | Abstract contract allowing setting, getting, and clearing of an Exhibit |
abstract/Rentable.sol | Abstract contract alowing renting of a Frame to another address |
interface/IExhibitionable.sol | Public interface for the Exhibitionable contract |
interface/IRentable.sol | Public interface for the Rentable contract |
interface/IVersionedContract.sol | Public interface for a simple versionable contract |
mocks/TokenMock.sol | A mock contract used in testing to simulate LINK token |
mocks/VRFCoordinatorMock.sol | A mock contract used in testing to simulate the Chainlink VRF provider |
Frame.sol | An ERC-721 compatible token contract implementing the Exhibtionable and Rentable functions, and a minting process using Chainlink VRF |
A Frame is an ERC-721 compatible NFT token, representing a dedicated digital exhibition space in the Musee Dezental.
This Frame allows you to:
- Set an Exhibit, another ERC-721 or ERC-1155 compatible NFT the owner of the Frame also owns, which allows the Exhibit to be rendered and displayed inside your beautiful Frame inside Musee Dezental.
- Rent out your Frame to any account for any number of blocks, which gives the Renter for that period the same rights to display their own Exhibit in the space.
- The Frame owner determines the rental price per block which must be paid by any renter seeking to utilise the coveted space inside Musee Dezental.
There are 221 individual NFTs, each representing a single Frame. Each will have it's own visual display style, represented as the image
property in each NFT metadata.
Images for each of the 221 Frames will be committed to the utils/images
folder and uploaded and pinned as a single folder to IPFS using Pinata and additionally permanently pinned using Arweave (see https://ipfs2arweave.com). This occurs during the yarn deploy
stage automatically, as long as the images are already in place under utils/images
.
Note: the image
property on each Frame will represent an empty Frame without an Exhibit inside it.
Individual metadata for each Frame is the following attributes only:
- Floor (EG, 1OG, 2OG)
- Category (A to K)
- Image (An IPFS link to the image data)
Metadata will be committed to the utils/metadata
folder and uploaded and pinned as a single folder to IPFS using Pinata. The resulting hash of the IPFS folder upload will form the baseUri for the token contract. Each token will then have a metadata URL of ipfs://<hash>/<tokenId>
as generated by the token contract.
The following accounts may set the Exhibit on a Frame at any time:
- The current ERC-721 owner of the Frame token.
- The current Renter of the Frame token.
An Exhibit is a reference to an ERC-721 or ERC-1155 compatible NFT also owned by the owner or current Renter. Musee Dezentral will render the image
property of the metadata URI provided by each contract.
- For ERC-721 NFTs the account setting the Exhibit must be the owner as confirmed by the
ERC721.ownerOf(tokenId)
interface. - For ERC-1155 NFTs the account setting the Exhibit must hold at least 1 (one) of this tokenId type as confirmed by the
ERC1155.balanceOf(address, tokenId)
interface.
Note: Attempting to set your Exhibit to a contract that doesn't implement either of these interfaces will not succeed.
setExhibit(
uint256 _tokenId, // tokenId of the _Frame_
address _exhibitContractAddress, // contract address of the _Exhibit_
uint256 _exhibitTokenId) // tokenId of the _Exhibit_
Any account that pays the requisite rental fee to a Frame in advance may rent and Exhibit in that Frame for as many blocks as they can afford or wish.
- The
rentalPricePerBlock
must be set by the Frame owner before anyone can rent the Frame, using the function:
setRentalPricePerBlock(uint256 _tokenId, uint256 _rentalPrice)
- If the rental price is set, anyone cant rent out the Frame using the function:
function setRenter(
uint256 _tokenId, // tokenId of the _Frame_ to rent
address _renter, // address of the renter
uint256 _numberOfBlocks _ // the number of blocks to rent for
) payable
- This a payable transaction and the renter must supply exactly enough Ether with the function to fulfill the requested amount of blocks.
- One can use the function
calculateRentalCost(_tokenId, _numberOfBlocks)
before renting to determine the exact amount (in wei) you need to supply to the function
The Frame itself may be transferred or sold at any time and this does not affect the rights of the Renter.
The Renter does not have token ownership and is not able to approve, transfer, or perform any other ERC-721 compatible transactions on the contract.
Note: A small proportion of all rental fees (5%) will go toward maintaining Musee Dezentral and will remain in the contract (musee-dezentral.eth
).