nft-marketplace-contracts
v1.0.21
Published
Smart contracts for NFT trading on Avalanche
Downloads
3
Readme
NFT Marketplace Contracts
Introduction
This repo contains the smart contracts for running a custodial NFT marketplaces and scripts helpful for their deployment on the Avalanche network. The code utilizes the hardhat development environment for easy deployment.
Prerequisites
NodeJS and Yarn
First install the LTS of nodejs which is 14.16.0
at the time of writing. NodeJS bundles npm
.
Next install yarn:
npm install -g yarn
Python3
If you plan to generate a matched collectible/pack schema from a definition schema, you'll need to install Python3. Python3 comes preinstalled on many distributions, but is also available here: https://www.python.org/downloads/.
Dependencies
First clone this repo and download the necessary packages.
git clone [email protected]:topps-digital/contracts.git
cd contracts
yarn
Create your env config
Rename the .env.example
file to be .env
. Edit the file to use your own deployment variables. You can obtain the neccesary Pinata keys from https://pinata.cloud. CUSTODIAN_ADDRESS
should be the Avalanche address of the signing custodian.
Building
In package.json
there's a compile
script.
"compile": "npx hardhat compile",
Run yarn compile
to make sure your project compiles.
Deploying a Collection
Collections consist of packs which each contain a number of collectibles. Both collectibles and packs are NFTs deployed to the Avalanche blockchain.
Collectible/Pack Assignment
Collectibles are assigned to packs off-chain. For each pack to be minted, the selected collectibles are concatenated along with a securely generated, cryptographic salt. A hash is then created by taking the sha3 hash of the concatenated string. This hash is then added to the pack during minting. To open a pack, the user (or custodian) must supply the pack's contents along with the salt. The smart contract will then verify the hash by computing its own. If the hash passes, the pack will mint the corresponding collectibles to the pack owner.
Collection Schemas
Deployment Schema
Collections are specified by JSON files. For each pack and collectible, the file must specify a name, symbol, description, and image filepath. In addition to the packs and collectibles, the json file must provide a list of packs to mint, namely the name of the pack, the collectibles inside, and their corresponding salt. These JSON files are specified by schemas/deployment_schema.json
.
Generation Schema
To assist with generating deployment JSON files, there is a Python script that takes a more general collection specification and turns it into a deployment specification. The input to this script is a JSON file that meets the Generation Schema's criteria. Essentially, the schema specifies a list of packs and a list of collectibles. For each, the schema requires you provide a name, symbol, image filepath, and number to mint. For packs, you must also specify the number of collectibles in each pack. The schema is located in schemas/generation_schema.json
. Example collection generation specifications are available in examples/
.
Generating a Deployment Specication
Final JSON deployment specifications may be generated by any means. One such method is through the collection_generator.py
script. This script takes a generation specification and produces a deployment specification. Essentially, it checks that the number of collectibles to be minted matches the number of available slots in packs. It then randomly assigns the collectibles to packs and generates a salt for each. The generation procedure is not sophisticated. The distribution is uniform and you can have duplicates of the same item in a pack. Make sure to call the script from the top-level directory. The script takes one argument: the generation specification to generate from. The output is dumped into data/matched.json
. An example call:
python3 scripts/collection_generator.py examples/example_collection1.json
Deploying
Process
Deploying requires a collection deployment specification JSON file. Currently, the spec must be located at data/matched.json
. For each pack and collectible in the spec, the deployment script will upload the image asset to IPFS and pin it using Pinata. It then uses the image's CID to create an NFT-compliant metadata file which is also uploaded and pinned to IPFS. The assets are replicated with the Pinata account's default replication preferences.
After all assets are uploaded, the pack and collectible contracts are deployed. Next, the script mints all of the necessary packs by calculating the individual open hashes. After all packs are minted, the process is complete.
Execution
Hardhat enables deploying to multiple environments. In package.json
there is a script for deploying.
"deploy": "npx hardhat run scripts/deploy.js",
You can chose which environment that you want to deploy to by passing in the --network
flag with avash
, fuji
, or mainnet
for each respective environment. If you don't pass in --network
then it will default to the hardhat network. For example, if you want to deploy to mainnet
yarn deploy --network mainnet
When you deploy to avash
, fuji
or mainnet
you can add your private key(s) as an array to the respective environment's accounts
field in hardhat.config.ts.