Skip to content

ravespaceio/musee-contracts

Repository files navigation

musee-contracts

Build

This repository contains the Solidity contracts, deployment scripts, and metadata deployment to IPFS for Musee-Dezentral NFTs.

Prerequisities

This is a hardhat and Yarn project which builds and deploys an ERC-721 compatible NFT called Frame, targeted for Ethereum/EVM compatible networks.

Configuration

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>

Build

yarn build

Test

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.

Deploy

yarn deploy
yarn deploy:rinkeby
yarn deploy:mainnet

Contract Manifest

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

What is a Frame?

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.

Frame Metadata

Image

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.

Other metadata

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.

Frame Features

Exhibiting

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.

How To Set Your Exhibit

setExhibit(
    uint256 _tokenId,                // tokenId of the _Frame_
    address _exhibitContractAddress, // contract address of the _Exhibit_
    uint256 _exhibitTokenId)         // tokenId of the _Exhibit_

Renting

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).