Behind the scene of MekaVerse Launch

Miinded
11 min readOct 18, 2021

--

Miinded x Mekaverse

Hi everyone!

I’m Ekco 👋
I’m going to tell you a little bit about Miinded and how we worked on the drop of MekaVerse.

About Miinded

Miinded is a French development studio. We are a four-person team consisting of Hiro and Wybo, who are designers and front-end developers, and Starker-Xp and Ekco (myself), who are full-stack developers. We develop websites and smart contracts for projects such as Pudgy Penguins, CryptoFoxes, and most recently, MekaVerse.

We began NFTs in February 2021, which is 9 months ago. We built CryptoFoxes.io, which features two pixel art collections of foxes. It was a daydream shared by four buddies. The first collection was produced at random and minted on Opensea. To develop our own ERC721 smart contract, we needed to improve our Solidity abilities.

We already collaborated with numerous artists to develop websites and smart contracts! We formally founded Miinded for MekaVerse; previously, we didn’t have a name and were referred to as “CryptoFoxes developers” or “Pudgy Penguins devs.” It wasn’t very professional.

Miinded

Miinded x MekaVerse

MekaVerse had just revealed a sneak peek from their collection, and it quickly grew in size. They were seeking for a team that was willing to assist them with the technical aspects of their project. Wyb0 was approached by one of MeKaVerse’s founders. They are also French, therefore the globe is tiny.

Their visuals and world were fascinating! They’d seen our previous efforts, and after some back-and-forth, we began on the MekaVerse adventure. As a result, we began working on the project in early September.

Deal with it

Due to the complimentary nature of our team, Wyb0 and Hiro began work on the website, while Starker and I began R&D to choose the appropriate technology. The project evolved as time passed.
It had to be a classic mint with a gas war, 50% pre-sales + traditional mint, and then a raffle.

The goal was very simple: create a smooth drop with no gas war and avoid bots.

That alone, especially when you consider the number of followers, was a technological difficulty.

Without a major gas war, how can 250K+ people get a chance to buy a MekaVerse NFT? After talking with the entire team, we decided to hold a raffle and allowed people to mint only two with maximum protection to avoid botting or hacking attacks.

The MekaVerse Team gave us the following instructions for the mint:

  • Max 2 NFTs per wallet
  • Registration must be free
  • A price of 0.2 ETH per NFT
  • Minting has to be simple, clean, and smooth

The Registration

Raffle registrations had to be free (and without paying gas), which is why they were not on the blockchain; otherwise, you would have had to pay a minimum of 15/20$ each registration. It’s a bit ridiculous to avoid a gas war while wasting more than $2.5 million in signatures (170K+ wallets registered which would have been $15 per signature, for a total of $2.5 million).

We have set up the following on the site to minimize bots as much as possible:

  • Google ReCaptcha V3
  • Checking MetaMask Wallet funds
  • Discord or Twitter Authentication
  • An EIP 712 V3 signature (We were unable to support Hardware Wallets because of the V3 signature)

This system greatly limited the wallet bots. Without all this technical part, there would have been far more than 170,000 registrations and the raffle would have been a disaster.
We could do nothing against an army of truly human beings who would be fake twitter accounts or discord to sign up. We only had one day to check 170,000 registrations and it was humanly impossible to check 1 to 1 each wallet.

Especially for avoid any risk of leak of our database we did not save Twitter and Discord IDs in our database. So, it was not possible to check Twitter or Discord accounts 1 by 1!
According to some people’s research, the bots only managed to hit a very (very) small amount of Mekas, so I apologise for the owners who were not selected because of them…

The Mint

We attempted to make hacking harder while also concealing our tracks:
Some may have observed that all connections to the website were encrypted, both transmitted and received. We’ve noticed someone attempting to decipher it in the server logs. For the time being, I don’t know if someone has already decrypted it.

We dispersed many distinct copies of our contract on the Rinkeby test network, each of which included a security vulnerability, in order to provide a bone to gnaw for anyone who wanted to try their luck. That is why, as a precautionary step, we did not reveal the contract prior to the sales.

Earlier in the day on Thursday 7th, a few hours before the sales began, a really kind person discovered a problem in our smart contract (based on one of the contracts we had left lying around on Rinkeby).

The shame

The danger was not critical because it still required a number of favorable conditions to be exploited. But we couldn’t leave it there. That’s why, we fixed the problem and redeployed a new contract in full transparency and without creating any doubts about the error.

Randomization process

Many people criticized us for not using VRF (random in the contract) for metadata distribution. We were unable to do so since we received the final information 6 days AFTER the raffle event, after the sales were complete, making it difficult to predict and code anything.

The draw of entries were handled by a handcrafted Python algorithm that picked the winners. Here is the function’s output:

+ — — — — — — — — — — — — — — — — — — — — -+
| PRODUCTION |
+ — — — — — — — — — — — — — — — — — — — — -+
— 1. Wallets recovery —
Total: 172,876 wallets
Total value: 172,876 wallets
— 2. Formatting wallet and retrieving counts —
Count the cut: 2
Count(1): 56945 wallets
Count(2): 115931 wallets
Total Token reserved : 288807
Len wallets: 172876
Total number: 288807
— 3. Calculation of totals —
Unsold token: 8806
First token: 83
Last token: 8888
Max token: 8806
Temp distribution: {1: 1736, 2: 3534}
Temp Total distribution : 8804
Distribution dif: 2
Final Distribution: {1: 1736, 2: 3535}
Total distribution: 8806 tokens
Wallets : {1: 1736, 2: 3535}
Total wallets: 5271 / 172876 (3,05%)
— 4. Processing...— 5. End —
Total selected: 5271 wallets
Last TokenId: 8888

We have saved 82 mekas (#1 to #82) on the whitelist per MekaVerse’s request. As a result, the selection function begins with token #83. To avoid a panic and questions, we didn’t want to mint the 82 Mekas before the sales: “How come there are already 82 mints, what the heck is going on? Has the contract been hacked? Etc.”

In order to have a fair allocation between the 1 NFT wallet and the 2 NFTs wallet.
We divided the lists into two categories and chose the winners at random from each. We wanted to ensure that each group received the same chance. Once the distribution is complete, the server will randomly choose wallets from the two lists every minute during the raffle until the stocks run out in 30 minutes.

We had expected in our contract that some of the winners would be unavailable to mint during the event. We didn’t know how much, but we knew it would happen, which is why the mintUnsoldTokens method existed. We were able to mint unsold tokens because to this functionality. As I type these words, the 295 unsold tokens have yet to be produced. We’re waiting on MekaVerse to inform us what they want to do with it and how (new raffle, giveaway, etc.).

How the images were assigned to each token

Randomization was built in Python with the help of a simple function:

random.shuffle(list)

Essentially, we assign a random number to each image, place the photos in a sheet (like in Excel), randomly mix all the lines, and assign them to the minted token; it’s easy, repeatable, quick, and free of gas expenses.

To be able to use the randomization if needed, we used a seed:

random.seed(561)

Why the number 561? Again, it’s completely random for greater transparency.
We had an unwanted file that snuck into the center of the mix when we mixed all of the random NFTs (a Thumbs.db file). He arrived to take the position of the Meka #5227, which we had to manually repair.

When the 8,888 Mekas are minted and revealed, everyone can verify that the random number generator was not tampered with.

The procedure is as follows:

1. Retrieve the 8,888 images (48gb) without renaming them.
2. Delete the image of Meka #5227 that was added after.
3. Add the placeholder by naming it "1080_placeholder.png".
4. Add a file named "Thumbs.db" that had nothing to do with it.
5. Replace the Legendary Meka files with their ticket as : Legendary_Meka_Tickets_1.png, Legendary_Meka_Tickets_2.png, ...
6. Launched the script python.
And you will have exactly the same result as on OpenSea (with missing metadata for the Meka #5227)

Source code @github : https://github.com/MiindedStudio/MekaVerse-random-pictures/

Simple, Basic

Regarding IPFS

“IPFS is a God”

Everyone wants IPFS, but you have no clue how great and compassionate you can be with NFTs and an external API that is well-designed. Anyway, about IPFS, MekaVerse indicated before the announcement that all NFTs will be on IPFS few days after the reveal, therefore I have nothing else to say about it.

Patience…

We put the placeholder on IPFS to demonstrate that everything will be on IPFS.

Was there a metadata leak? No!

There was no metadata leakage.
On Wednesday, 13th, around 9:30 a.m. CET, we received the final files (7:30 before the reveal). For further protection, the files were uploaded to our servers at 4:30 p.m. CET, approximately 30 minutes before the announcement. I urge you to browse the sales between 4:30 and 5:00 p.m. to see whether someone actually managed to breach our servers and get the list of rare meka and buy them before 5:00 p.m.

I’m Hackerman!

We employed an automated method for the reveal, which was ready in a second. Because of our automatic reveal mechanism, we made a mistake on Sunday, October 10th. We did not postpone the reveal timetable in response to the announcement of MekaVerse, so at 11:00 p.m. CET our servers on reveal metadata, but of another project to us: LuckyDucks.win (Send him plenty of ❤❤❤, he needs it)

Our hosting and servers

“Give me the Facebook’s servers please!”

230,000 people on Discord and Twitter, the most hyped NFTs project ever, everything is played for a short period and everything is put together to blow up any server!

We had a budget of more over $2,000 for the two and a half days.
To back up our numbers, we utilized our current host Scaleway, which let us to connect dozens of instances to a load balancer for around $15 per hour.
To host the backend API, either 10 backend servers + 1 loadbalancer + 1 cluster redis.
We had the equivalent of 448 server cores, 1.5TB of RAM, and 12Gb/s of bandwidth!

We hosted the files for the frontend of the site via Netlify, a high-quality CDN with servers all over the world and at a reasonable fee (840$+ for 7 days).

The frontend is developed with VueJS and the backend with Python / FastAPI.

The calm before the storm

We were prepared, having put everything in place three hours before the registration began. All we had to do was sit and wait.

We could notice the gradual loading:

  • 3h before: 8k visitor
  • 2h before 12k visitors
  • 1h before 20k visitors
  • 50min front: 40k visitors
  • 20 minutes before: 60k visitors
  • 5min before: 70k visitors
  • 1min forward: 80k visitors
  • Launch: 130k visitors

The number of visitors were insane, with more than 50,000 arriving in less than a minute.
Servers 1–4 took the majority of the demand, and certain services were quickly saturated. Servers 5 through 10 were heated, but they remained standing. Google recaptcha, Twitter authentication, and Discord all blocked us for 3 minutes without warning due to too many connections being active at the same time. The database swelled and grew overburdened with connections.
“That was insane, you were insane ❤”

This is FINE!

But we were there, and all eyes were on our 12 terminals, which were continuously flashing logs and stats; it was like the Matrix 4 trailer!

While I was attempting to restart services on servers 1 through 4, Starker-xp was managing database connections and multiplying the number of database connections by 1000.
We’d switch on a server, he’d be hot in five minutes, and then we’d turn on another, and so on. And we did it for 35 minutes, by which time the majority of the individuals who were linked had completed the registration.

It’s Hot

We had four more servers planned, but we didn’t use them due to time constraints. I’m not sure how your experience on the site was within the first 35 minutes, but it was intense for us! After 35 minutes, everything had settled, and the servers were able to manage each 15k connections concurrently.

It was a first for us to manage so many people at once! It wasn’t perfect, but we did it! And, just in case, we’ll switch on four additional servers the following time.

In terms of sales, the servers were significantly less sought. There was no database or server failure, and everything ran well (probably thanks to the experience of the previous day).

Finally

We worked really hard on this project because we only had three weeks to complete everything, and you can’t imagine the strain of having 230,000 people (at the absolute least) watching and evaluating you.

We are and will always be humans, with all our qualities and faults.
We made a few minor errors, but nothing major that would detract from the Meka’s beauty.

“One of my favorite Gadians is the twin sword! I see you, #6785, one day you’ll be mine!”

MekaVerse is neither a rug, or a scam. MekaVerse is a challenge and a very beautiful journey that has only recently begun and will be around for a very long time! Heartfelt gratitude to everyone who has helped or supported us ❤. We have learnt a lot and that we will constantly strive to do better in the future. 🚀

Love ❤,
EKCO from Miinded.

Miinded

--

--

Miinded

Team of 4. We develop smart contracts and websites for NFT artists.