Build a bridge between 2 chains during a hackathon. A screenshot of the somewhat working end result:
Context
MultiversX is a blockchain that decided to host a hackathon for some reason that’s not explicitly stated. I wonder if they are looking for new developers, or if they are looking for new ideas, or if they are just looking for some publicity. I don’t really care. They decided to host a hackathon with the help of the Encode Club organisation. Also, there’s probably a reason why they removed the letter e
from the word Multiverse
in their name, but I don’t know what it is.
TLDR Rules of the hackathon. We had like 30 days to build something dope on the MultiversX blockchain. We must submit a project, video demo, and business case description.
Blockchains and cryptocurrencies are a hot topic these days. Most discussions I read about the issue on hacker news
or on /r/programming
tend to shine the whole domain in quite a negative light. But this is not a philosophical blog to convince you of the opposite opinion. As a matter of fact, I like the chaotic nature of the domain. I enjoy the technical challenges because “blockchains make things complicated”. Also, my day job for the past 2-3 years has been working on blockchain-related projects, so I’m familiar with the domain.
I enjoy building things, especially writing lousy code that does the job. Not that I dislike writing beautiful code, or like I don’t see the benefit of doing things “the proper way”. I just don’t have a mental block that would prevent me from doing things in an ugly but working way. This is a good trait for a hackathon.
This is not my first hackathon but it is my first online hackathon. Every other hackathon I’ve participated in has been an in-person 48-hour event. I’ve been to 4 or 5 hackathons and won 1 of them. I’m not saying this to brag but to give you some context about my experience. I’m not a beginner, but I am not a grandmaster either.
Provencraft Community is a community of developers, friends, entrepreneurs, designers, awesome people. A member of the community, Alexe, was looking for people to join him in the hackathon, so I signed up, along with one other guy Ronald from the community.
Day -6
Six days before the official beginning of the hackathon, we had already formed a team and had our first call on what we wanted to build. We settled on building a bridge between 2 chains, where one of the chains would be MultiversX and the other one would be decided later.
It just so happened that we never agreed on the second chain — this will be important later
We all liked the concept of IBC and Cosmos-related blockchains (the other ideas were shit). A fundamental concept is the ability to transfer tokens and other stuff between chains using a generic and well-agreed protocol.
We wrote down the core concept on a Figma Jam board and were ready to go.
And yes, before you ask me, on the call, I was moving those triangles and squares around like a madman trying to explain how this shit works.
Well, we concluded that this would be complicated af, and that we would not have a bridge between 2 chains. We’d just mock user balances in our backend because implementing a full IBC-compatible bridge in 30 days would be a suicide. We decided that we would market our bridge as an IBC bridge, even though it was not really an IBC bridge and just a random ass backend with REST endpoints that would send transactions to our smart contract to mint tokens and periodically scrape the contract to understand when we should update our JSON file database of balances. It’s the idea that matters…
Day 0-3
We chillin’
Day 4
Another friend from the Provencraft Community decided to jump into the hackathon and join our team. We added him to our group chat. He still has yet to send a single message since then.
Day 5-9
We’re going through the video materials provided by MultiversX and trying to understand how to write contracts & interact with them.
Day 10
I created a GitHub repo called multiverse-x-hackbros. I made the first commit called batman
because it has no parents.
Also, another guy Richard joins our team. We also assign him a task from our “brainstorming taskboard”. Red - we don’t know how to do it. Green - we probably know how to do it.
Day 11
I scrambled code from my personal projects to bootstrap our repo with some pipelines, checks, audit actions, etc. (which we just ignored for the project’s lifetime, but now I have another reference of GitHub actions that I can copy pasta into my future projects). I set up a simple Rust backend, which will provide REST endpoints for the frontend and communicate with the MultiversX blockchain.
I became a part-time project manager. There is a lot of internal team communication in trying to explain the idea, ensuring everyone understands their tasks.
Also, Ronald is trying to comprehend the frontend tutorial material.
Day 12
We got an email from the orgs that we can submit our project for the intermediate check. We decided to submit it, even though we have nothing to show. We just sent them a link to our GitHub repo.
We also have internal syncs on how to create the UI. We decided we would mimic the official bridge that MultiversX already provides.
I also examine the difference between a custom EVM-MultiversX bridge that’s already available and our IBC bridge. A perfect way of doing it was by telling the guys to look at this map of interconnected chains and telling them “imagine if MultiversX could talk to all of them”
As the day grows older, all my homies start getting grey hair from the developer experience:
Day 13
We have a sync call where we all tell each other that things are not looking as good as we initially thought. We’re all struggling with the developer experience. The frontend is non-existant. It is not possible to read events from smart contracts (necessary for the backend flow). Also, we have no idea how to sign a transaction from Rust because there are no docs on the website. The Rust SDK has no docs either, and because no one uses this blockchain, there are no examples or guides on how to do it. Our custom smart contract at this point only has 2 functions, set_value(u64)
and get_value(u64)
, which is far from a vault smart contract that could lock
, mint
and burn
fungible tokens.
Day 14
In the middle of the night, at 3 am, Ronald finds a dapp template.
I complain that no one responds to my MultiversX dev support question on Discord during a hackathon.
We have the scheduled call with Klara from the org team to sync and see each other for the first time. We complained about the slow dev support during the hackathon, and they poked their tech team to look at the question, ”this guy is usually good at answering questions“.
After the call, we also looked through the submission document and everything we needed to submit. We’ll get back to this on the last day of the hackathon.
Ronald wants to join the call with the ops team, too:
And I am still complaining that there’s no simple way to receive live events from the chain:
I am at a very low point in my life. I am considering just dropping the idea. I don’t see us moving forward if, even for local development, we need to spin up 3-4 random services and have a local node running. Ofc everything is undocumented / without examples.
Alexe has a dumb but brilliant idea to not emit any events and write things into vectors and maps on the contract state that can be queried. This would never fly in a production environment. Still, when your only other alternative is quitting life, this seems like a good idea.
Future me: I never actually figured out how to query the state of a hashmap, and reading state from a vector took me hours to get right, and not even for all data types. But we worked around that.
Day 15
With the new data storage approach, I have become overly optimistic about the project timeline. Ronald is still wrangling beasts in the frontend.
Day 16
I am waiting for Alexe to deliver something on the smart contract side so I can integrate with it. He is learning from the existing open-source bridge codebase.
Honestly, I have no idea where Richard has been for the past 2 days.
Day 17
Disaster strikes because we conclude that the smart contracts module works on Alexe’s computer but not mine. This means that I cannot integrate my backend with his contracts.
MultiversX has 2 tool suites for working/ deploying/ integrating with the contracts, one written in Python and the other in JS. After switching from the mxpy
tool suite to the JS one, I can compile the contracts and integrate with them.
Foreshadowing: later, it turns out that the JS suite does not work on Windows because one of the dependencies,
xsuite
, is not compatible with Windows, creating a lot of headaches for Ronald.
We also decided to skip the “local node” setup and just deploy everything to devnet because the JS flavour of the MX tool suite did not have a way to spin up a local node.
And Ronald is now trying to figure out how to communicate with the contracts from the front end.
Also, it later turns out that Ronald had been trying to create a new server-side hydrated frontend project from scratch rather than using their dapp template. This is why he was struggling so much. Also, he has some sudden internal realisations about the frontend:
Richard and I are figuring out how to communicate with the smart contracts from our Rust backend.
Our calls, where eventually the whole team joined, remained fruitless. The operation’s main culprit was the lack of docs and examples of proper communication between Rust and Smart Contracts. We only had a few keywords that we could extract from the `mx-sdk-rs ” SDK, only a few methods that allegedly interacted with contracts, all hidden behind an endless amount of generic traits and types and structs. No docs. Late at night, on the 4th or 5th page of the GitHub search, I found the repository that would change the direction of the whole hackathon. This one repository was responsible for all of our success. From now on, that repo is referred to as “the holy grail 🏆” repo.
Day 18
At 2:30 am, Ronald gives us an update that, at this point, he has tried every possible framework and toolchain except the official dapp template.
But the gods heard our prayers, and the next day, we received an email that the template dapp had been updated. Although the code was not? I am still trying to understand what was updated, but Klara has become our saviour since that day.
Later, Richard tells me he cannot compile his Rust code. I tell him to stash his changes, and then it will compile.
Day 19
At 00:03 am, I managed to get my Rust code to compile and interact with the smart contracts. Maybe it wasn’t Richard’s fault that his code didn’t compile.
During the day, we decided to rebrand our bridge and call it xChains.
Richard is trying to figure out how to send the transaction from the backend. I’m consulting with the holy grail 🏆.
Day 20
We are preparing an intermediate submission. Generating some AI logos, simple descriptions about the project, and the team members.
Because most of the work we do is fully asynchronous, we need to use Discord text chat for syncing purposes of trying to understand how far everyone has gotten. This is a snippet of how I attempt to sync with the team:
Day 21
I started worrying that we might not make it. We have 9 days left until the submission, and my ass starts burning. This means that we need to start pushing for more internal calls.
Ronald cannot make it to the call, and we still have 0 progress on the front end. I am worried that we will not have anything in time for the submission. The project is not in a good state. We have our “universal warrior”, Richard, who I keep plugging into every crack we have in the project. During the call, I assigned him to have a call with Ronald, sync & understand the frontend state, and even suggest taking over parts of it.
We also rename the repo from multiverse-x-hackbros
to xchains-multivers-x-hackathon-entry
. Slightly verbose, but at least it’s clear.
I also created another picture of how the flow will work because I forgot.
Day 22
I keep pushing the guys to have a sync between them regarding the state frontend.
Day 23
Alexe pushes code on the smart contracts, allowing users to bridge tokens from MultiversX to the other chain. Referred to as the “deposit logic”.
Day 24
With the deposit logic on the smart contracts, I can fully integrate the contracts from the backend. I finished all the flows and let the guys know that the current missing business functionality is the whole frontend (we still have no frontend). And that smart contracts don’t have the logic behind the public APIs.
It turns out I had misinterpreted some parts of the public API and have not fully integrated with it. I consulted with Alexe because there are some weird types that I don’t fully comprehend. I also try to consult with the holy grail 🏆 but it does not use the same in-built types because it’s outdated or has a different logic flow. Either way, I try to fake it til I make it and write some random code that allegedly creates the correct data type. No confidence, tho.
Ronald got a boost of confidence:
Day 25
We are 4 days away from the submission deadline.
At 4:30 am, Ronald drops an update that he is pulling an all-nighter:
It’s not a proper hackathon if someone does not sacrifice their sleep.
The same day, we had a call where Ronald demoed his progress.
I want to highlight that Ronald had not slept at all. He kept staring into the camera, mumbled something and started laughing hysterically. There was not a lot of sanity left in him.
Day 27
Richard is working on the frontend, integrating the MultieversX JS SDK, trying to communicate with their API and communicate with the contracts. Alexe is chipping in and letting him know where and how to get the smart contract ABI.
Also, Alexe is still working on the business functionality of the smart contracts. He is trying to figure out how to mint (create) fungible tokens on MultiversX.
It Turns out he managed to deploy the token; he just misinterpreted the logs.
Then, we face every frontend developer’s arch-nemesis: CORS. Albeit fixing it was literally 3 lines of code that I had forgotten to add.
Day 28
48 hours until the submission
I helped with another minor CORS issue.
Also, remember the xsuite
issue I mentioned on Day 17? Well, Ronald was the one who works on Windows, and shit just doesn’t work. He cannot compile the contracts from Windows because xsuite
does not work. On WSL2, there are issues with installing node_modules
for other (unrelated?) reasons.
We have a call, and we conclude that we don’t know how to fix it. Accept defeat. Workaround: Ronald won’t need to compile the contracts; we’ll give him the compiled contract ABI and all the other artefacts. We need more time to investigate the issue in-depth. During the call, Ronald highlighted issues displaying the token balances. As a developer from 2023 that follows every hype train, I use ChatGPT to generate code for Ronald that would help him with formatting and displaying the token balances (this caused issues later down the road where I had to assign Richard to fix the code on the last day).
During the call, we concluded that there was an issue on the backend (Mutex
never released) — I have to admit that I never tested my backend code manually. I just told the guys “I’m done and you can integrate with it” 🙈.
This is 2 days before the submission. Ronald primarily owns the frontend and knows what’s happening there. Still, he won’t be available the following evening. We need to squeeze all the juice we can from him today.
We do some pair (triplet?) programming with Ronald, Richard and myself to get as much done as possible. Ronald is screen-sharing his IDE, and we all try to look for solutions for every problem we face. As issues in the backend get found, I quickly fix them and push the changes to the repo. Ronald pulls the changes, and we continue. When Ronald concentrates, he tends to lean into his monitor so much that his face touches the screen. I am not sure if he’s trying to see the code better or if he’s trying to become one with the code. But this is how I saw him for the majority of the time:
The call lasted for quite a while:
To boost the spirits of the team during the call, I shared a picture of my absolute unit of a cat:
Day 29
Last day before the submission
I dropped the call at midnight, but Ronald and Richard remained there for another hour. Before I left, we had a somewhat working flow for bridging tokens into MultiversX, with no logic on the frontend for bridging them back out. At 1 am, Ronald dropped a message that they got the whole frontend flow working.
Based on how much stuff I had to fix on the “bridge in” scenario, I expected that I’d have to fix many things on the “bridge out” scenario. But sometimes, I get lucky and write code that works.
We need to submit everything within the next 24 hours. The plan is to have a call in the evening and create all the documents, record the video and whatever else is needed. But during the day, Ronald is still fixing bugs on the frontend and trying to do everything he can to make the frontend look good.
The guys and I have a call in the evening. Richard is fixing the last UI bugs (the ChatGPT code I provided last night) and recording the video demo for all the flows. Alexe and I are working on the submission document. Ronald had personal endeavours to attend, but he already had spent the last week of his life not sleeping and grinding on the UI. The man had sacrificed enough 🙏.
In the evening, Ronald drops us a message that he has an important thing stored in the frontend/public
folder. Me and the guys checked it out, and it indeed was something important:
Alexe finished up with the business case description for the submission document. I need to remind him that in Web3, people hate the word “backend” and we should use the word “infrastructure” in its place. We don’t have backend devs; we have infrastructure devs.
Richard finishes fixing the UI bugs and records the video with OBS. Out of me, Alexe and Richard himself, he was the only one who actually had tried running the UI and worked on it from his machine. After I receive the video, I do a quick edit and do a voice-over explaining what can be seen there:
And after we had the video, Alexe could submit the project. We were done. We had a working bridge between 2 “chains” (1 real, 1 JSON file). We had a front end that looked good. We had a video demo. We had a submission document. We had a team. We had a project.
I want you to read and understand the implications of the following screenshot:
It essentially means that we are “selling” a POC of something that could be made but in no shape or form actually does anything IBC-related. It’s all smoke. This is going to be important in 2 days.
Day 30
This is the last day of the submission, but we already submitted the previous night. Today we chillin’.
Day 31
This is the day when the winners are announced. We have a call with the boys to watch the event livestream together. Alexe, being from Romania, attended the event IRL.
Well, as it turns out, we got nothing. Our “Infrastructure and Dev Tooling” track was won by other teams. Such is life.
As the stream is ongoing, I get a DM from one of the MultiversX organisers:
Well, everyone gets super excited after chatting with the guy. He wants someone from the team to come and meet him in person (the only eligible person for that criteria is Alexe). There’s allegedly a guy who wants to speak with us. The guy’s name is ”Sunny Aggrawal”. I have no idea who the dude is, but after a quick google lookup:
And Alexe started shitting his pants.
…
Well, it turns out that the guy had left the event, and we could not meet him. I think it’s even for the better. It’s not like we would’ve left a good impression with the abomination we had created 😂.
But Alexe managed to talk to the orgs and the judges to get some inside info:
Conclusion
This hackathon was a wild experience. Not having participated in an online hackathon before, I did not know what to expect. Having a great team was a huge advantage. It was super chaotic. We only knew what was happening 3 days before the submission. I am amazed that things came together and that a lot of good quality inside jokes were born from this experience.
Everyone should participate in a hackathon every now and then. As software engineers, we either only build shit at work or have an infinite amount of side projects that never actually see the light of day. Within a hackathon setting, you either participate and submit whatever you managed to build or you don’t participate.
You might not work with your friends in day-to-day life. Hackathon is a great way to build things together, have some external pressure to add some adrenaline into the mix, and’s generally a great reason to have calls with the bros and just have a fun time and laugh about the absurdity of building some random bridge between a JSON file and a blockchain.
This would not have been possible without the holy grail repo 🏆, so thanks, random person who built it🙏.