How we pulled off the sale
Cardano successfully transitioned into the Mary era on March the 1st, which means it is now possible to create your own native tokens on top of Cardano.
But without smart contracts the flow between tokens is hard and this was the challenge SpaceBudz had. NFTs without smart contracts could be already achieved with a time based policy. This is what we did, but the question was still, how do we mint 10,000 NFTs and distribute them. Two problems we had:
- minting 10,000 NFTs and distributing them one by one after we received a payment is slow, allows for human errors and is simply a bad user experience.
- minting the tokens beforehand, would require a lot of ADA inside of that wallet because of the minValue parameter.
So we had to think of a way how we can solve these problems and automate the process. Problem two was quickly solved after understanding, that tokens can be created on the fly in a transaction and can be directly sent to the target address. The buyer himself was basically covering the minValue, when he made the payment.
Problem one was a tougher one. Without smart contracts you can’t really embed or trigger logic when you send a transaction. Currently all I can do is send ADA to an address and that’s it. So we had to build on top of this limited logic and we came up with the idea that we can basically encode the information in the ADA amount that are sent.
With this idea we could suddenly simulate a simple smart contract, but of course in a centralized way. We used one of my Raspberry Pis, which ran the Cardano node and a wallet. The UTxO set of this wallet was constantly scanned through. On this server was also a mapping from ADA amounts to ids. So whenever the wallet had a UTxO that matched one of the amounts in the mapping, the wallet was directly triggered and created a mint transaction with the according id. The token was sent to the input address of that UTxO (the buyer).
Afterwards this key-value pair was deleted out of the mapping to prevent the same token id from being minted twice.
Whenever a UTxO was coming in that didn’t match any amount of the mapping, the ADA were sent back to the original sender, so basically a refund.
In case two transactions with the same ADA amount were coming in, only one got the token and the other one was refunded.
The Raspberry Pi was of course hidden from the end-user to prevent DDoS attacks and to keep the wallet keys secretly. In order to fetch an available ADA amount on the website we had an extra server, running on Firebase, and a common Database between the Raspberry Pi and this Firebase server. The Raspberry Pi was constantly updating the DB with the available ids. So whenever someone was requesting to buy, the Firebase server was checking in the common DB for available ids and sent the end-user the according ADA amount he has to pay for that. Of course the end-user didn’t know what id was behind that amount, because we wanted to distribute the tokens randomly and fairly. First after the payment the id was revealed.
Why didn’t we just choose one specific ADA amount for all ids? People that know how to use the cardano-cli would have been able to buy multiple SpaceBudz in parallel. They could have bought for example 100 SpaceBudz with 1 transaction. We wanted to prevent that and that’s why we chose different amounts for all ids. The goal was to distribute everything as good as possible.
To prevent the end-users from fetching the same amount we created a reservation list. So whenever someone was fetching an amount, this amount was put in the reservation list for 15 minutes and no one esle could get this amount for this time window. If no payment happened during this time, the amount was released again.
Thanks to the UTxO model, we didn’t have to wait until one transaction was confirmed. Everything could happen in parallel. It didn’t matter if one transaction was coming in or hundreds. One buyer was essentially one UTxO. All of them were handled at the same time and all the UTxOs are independent from each other. This allowed me to give a great user experience, because you had an almost immediate response as end-user.
Overall the sale was a huge success and everything worked out as expected, besides some tiny errors. Nevertheless this is not the prime example of how to sell NFTs on Cardano. Smart Contracts are the way to go as soon as they are released.