Hackatom V — NFT Marketplace Smart Contract
From October 16th till October 31st, Tendermint hosted their fifth Hackatom which we took as a great opportunity to flex our creative muscles and learn something in the process. Our team has been working very hard (and also very late) on stitching our project together and we’re very proud of what we achieved. With that being said, we’d like to share our Hackatom V experience with you in this article, what we’ve accomplished, hurdles we had to overcome and what we’ve learned at the end of the day.
The Blockscape Team
Of course, this whole endeavor would not have been possible without the people who put their expertise and time into this project. The core developer team consists of Fabian, Marcel and Douglas — Douglas created the NFT marketplace contract with the support of Fabian while Marcel took on the battle function and the frontend. Our colleague Björn helped us create the art for our Cosmons, and we couldn’t be happier with the results.
Our Project Idea: A Generic NFT Marketplace
In the past, we’ve seen quite a few CosmWasm-based smart contracts for selling, buying and trading custom NFT tokens, and we actually quite liked those. What we noticed with these contracts, however, was that they only processed one sale per contract, so essentially, each NFT token put up for sale would need to have its own smart contract. Keeping in mind, that many other smart contracts could be deployed in parallel, we imagined it would be a nightmare skimming through a whole pile of different smart contracts in order to find the one(s) people are interested in — and this is essentially where our idea for an NFT marketplace emerged.
We pictured a smart contract that would allow users to sell, buy, trade and auction CW721 tokens in exchange for CW20 tokens in one central place for maximum visibility. The key feature was to make our marketplace generic, so as to allow any CW721 token to be sold for any CW20 token with plans to add support for cross-chain interoperability, allowing us to introduce other native tokens, like Atoms. As a cherry on top of our idea, we also wanted to create a fun Pokémon-inspired NFT contracted called “Cosmons” which would allow users to battle other Cosmons with a nice little frontend in addition to selling, buying, trading and auctioning them.
Alright, let’s summarize, what our plans were thus far:
- A generic NFT marketplace smart contract
- putting any CW721 token up for sale for any amount of any CW20 token
- buying CW721 tokens with CW20 tokens
- trading any CW721 token with any other CW721 token
- putting any CW721 token up for auction with a time limit and a bidding function
- A custom CW721 contract called “Cosmons”
- battling other Cosmons
- provide a neat little frontend
Challenges: Rust Strikes Back
The biggest challenge we had to face can be summed up in one word: Rust. Neither one of us had that much experience with Rust and the inner workings of a CosmWasm smart contract, so we had to learn both more or less from scratch during those two weeks of competition. What was hard about learning Rust in particular was not so much learning its syntax, but estimating how far we’d get and how many of our ideas we’d eventually be able to implement. Another challenge was getting Keplr working with our frontend, as we have also never done that before.
What We Had to Drop
Unfortunately, we had to learn the hard way that our goals were a little too ambitious for the time we had, so we had to drop some of our cool ideas.
First thing we realized was that we wouldn’t be able to implement all the marketplace functionality we envisioned. We then settled for a cut-down version that would allow users to sell tokens, buy them off of a global list of offerings and withdraw offerings.
Second thing we had to drop was our custom Cosmons images, simply due to the fact that we ran out of time adding those to the project. We did, however, add them after the deadline because it’d be a shame if people wouldn’t be able to see our original artwork. Since we managed to finish the marketplace contract just in time (literally), we haven’t been able to finish the frontend interface for it either. That was also added after the deadline.
The Marketplace Contract Under the Hood
The marketplace works in conjunction with any CW20- and CW721-based contracts. Here’s an overview of the message flow:
The only time you have to interact with the marketplace itself is either for querying the current list of offerings or when you want to withdraw an offering you previously made. In order to trigger a sale or purchase of a token, the token-specific contract needs to be talked to.
Both the CW20 and the CW721 standards specify a “send” / “send_nft” message which can be executed on the contract. These are used to ‘transfer’ tokens to other contracts which must implement a “receive” / “receive_nft” message. The tokens are not really transferred, merely the ownership is changed to the recipient contract which is also notified about the transfer via the “receive” message.
So, all in all, our marketplace is compatible with any tokens adhering to the CW721 and CW20 standards right out of the box. Just build, deploy, instantiate and you are ready to go.
Apart from finishing our marketplace contract with basic functionality and learning a great deal of Rust, we’re also pleased to have contributed to improving CosmWasm by finding a bug in the module (which got fixed immediately).
The current state of our marketplace contract is already pretty useful and has some great potential in terms of extending its functionality and providing support for cross-chain interoperability. It provides a great foundation for our future implementation plans and we’re definitely going to tackle them.
Finally, we’d like to thank Ethan Frey and Orkun Külce! Their support was greatly appreciated!
If you’d like to check out the contract for yourself, check out our GitHub!