Starting your first full-time dev role in the blockchain is surely a nerve-racking experience. Especially when your team casually hands you the task of topping up your Rust skills by building a showcase protocol level runtime module within your first few months!
But this wasn’t enough to phase Jason Tulp. Our newest Junior software engineer at the CENNZnet project grabbed the task with both hands and stunned us with his version of Snake on the blockchain!
We learnt a bit more about how Jason tackled his first dive into developing in the blockchain space and what’s next for CENNZnet snake.
What did you build?
As a relatively new member of the team, I’ve been frantically learning the basics of Rust as well as tackling the intricacies of blockchain development. To help solidify my knowledge Jordy (CENNZnet CTO) and I decided it would be cool if I had a stab at building my own runtime module.
For the last few weeks, I’ve been creating a Snake game as a runtime module for the CENNZnet blockchain. It’s pretty much your classic snake game, but all on-chain. So it works like this:
- You select a command to move the snake. This is read as a transaction by the blockchain.
- The runtime module holds logic to process the transaction and stores updated position values of the snake in persistent storage.
- If the transaction is successful it will create an event that contains the new data and can be read by a Dapp
- The Dapp reads the data from the event and draws the output to a webpage
So at the end of each block finalisation, the snake will move based on the new command.
So, why a snake game?
What exactly is a runtime module on CENNZnet?
A runtime module is a core component that contains logic that works on the CENNZnet blockchain. So rather than have DApp builders create their own smart contracts for every function they want to be communicated to the protocol, our team has built a selection of pre-built core services within the actual CENNZnet protocol. At the moment these module functions include:
- Generic asset which lets you mint, transfer, and burn different types of fungible tokens.
- CENNZX is the on-chain token exchange.
- Attestation allows accounts to issue and verify claims against other accounts (including themselves).
- Staking, which handles staking funds with validators.
It’s a pretty cool modular system that provides devs with a lot of flexibility to choose which blockchain services they want and sort of plug n’ play with them rather than figuring out how to do each from scratch.
What makes up a CENNZnet runtime module?
There are 4 key parts to a runtime module that all work together:
- Storage: This allows for persistent access to data that can be kept around between blocks.
- Module: This part defines the functions that can be accessed from outside the runtime module and acts as a way of communicating between the module and the DApps trying to access it.
- Event: Defines a list of events that are triggered after successful on-chain operations.
- Config: The config part is a bit like the brain of the overall system. It stores the logic of the whole module and determines what to do with the data it receives.
What tools did you use to build the snake runtime module?
- Rust for the backend to construct the module itself.
- Typescript for the front end and to provide an interface to interact with the module.
- The CENNZnet team, who were always there to answer questions and generally provide wisdom.
- I also had to understand substrate, Polkadot and Plug components so lots of reading around their projects.
What was the biggest challenge you faced during the building process?
The hardest part was probably figuring out a way to use randomness to move the piece of food when the snake ate it. This would have been easy in a traditional program however I needed a deterministic approach to work in a runtime module. Essentially, blockchains need to always get the same value from a set of calculations to prove that a specific transaction is correct. This meant that using standard randomness based on the system time wasn’t an option. I had to use an approach that was centred around block number and a constantly incrementing value called “Nonce” to calculate a reproducible random number each time the food was moved. This meant that the “random” number could be recalculated by the validators when finalising the block.
What other challenges did you have building your first runtime module?
- Learning the structure of Substrate runtime modules and how they communicate with each other
- Learning intricacies of Rust language such as ownership and generics alongside fighting with the strict compiler to get the project to build.
- Setting up unit tests in a “mock” test environment of the runtime. These handle all edge cases and provide a basis for the expected behaviour of the module.
- Using Typescript to hook up the front end with the module and call the different functions
- Working around the restrictions of the parity-scale-codec to serialise and deserialise different data types.
What advice would you give anyone trying to build a blockchain runtime module?
I have more of a dive in and work it out as I go approach. If I was doing it again I’d take time to step back and actually learn all of the parts of a runtime module before trying to build them! There are also plenty of resources online from both Substrate and Polkadot that explain runtime modules in depth which I’d advise going through first.
What’s next for the snake module?
There are two potential pathways I’m thinking of for the snake module. The first is simply making it live on our test net as an individual instance game. That would mean anyone who wants to could play their individual snake games and of course, check out the open-source code.
The other thing that I have in mind is to put it on our test net as a community-driven game. This means there would only be one game of snake that everyone could access. Our community members could then vote using the DAO on the next move for the snake.