What are we building?
Our goal is to build an NFT marketplace where NFT owners can put their NFTs up for auction and other users can bid on them using ICP. We will follow the english auction model:
- The seller of the item specifies a starting price, a minimum increment amount, a duration and a buy now price and escrows the item to a third party.
- A potential buyer can either place a higher bid than the current highest bid or immediately buy the item if they are willing to pay the buy now price. When bidding, the user escrows the money to a third party, and the third party refunds the previous highest bidder.
- When the auction ends, the third party gives the money to the seller and the item to the highest bidder.
In our scenario, the item is an NFT, the currency is ICP and the escrow will be a canister that handles all the auction mechanics.
Our application should offer the following functionalities:
- Allow the users to mint and own NFTs
- Provide a wallet view which can be used by the users to examine the NFTs they own
- Allow the users to put the NFTs they own to auction
- Allow the users to view the auctions they created in a separate view
- Allow the users to view the undergoing auctions and place a bid on them
- Handle the auction flow as described above
The architecture of the internet computer is based on canisters.
A canister smart contract is a bundle of WebAssembly bytecode logic and memory pages. Dapps on the Internet Computer are created from one or more canisters.
We can compare the Internet Computer stack with a classic Web2 stack in the following way:
|Database (MongoDB, PostgreSQL etc.)
|Persistent in canister memory
|Backend(s) (Node.js, Go, Java etc.)
|Canister(s) [Motoko, Rust]
|Frontend hosted on a canister [JS with React framework]
In our project we will create 2 canisters in which we will define 2 actors that will handle NFT interaction, auction logic and data storage. Actors are defined using the Motoko programming language. When an actor is built, the compiler generates the following files:
- WASM - The compiled bytecode that will run on the canister after deployment.
- Candid interface - A file that contains RPC definitions. We will use these functions to perform operations on the canister.
- TS and JS declarations - Files that map the candid definitions to JS functions in order to allow us to easily call our actor from the frontend.
In our project we will also use 2 official Dfinity canisters to handle authentication and ICP transactions: The Ledger canister and the Internet Identity canister.
The frontend will be concerned with presentation and user interaction. It will communicate with the actors by calling the functions defined in the declaration files.
The following diagram illustrates how the canisters interact between each other:
We will go more into detail in the following chapters.