Lava: Decentralized RNG

Ian Lapham
Becoming Future
Published in
8 min readNov 19, 2018

Building A Random Number Oracle on Ethereum

Written by @kennypeluso and @ianlapham

lavarng.com

8/20/19 : The dapp url has since expired but the contracts are still live on mainnet.

Intro

Random number generation (RNG) is pretty important for building a variety of applications and software platforms. As engineers building decentralized applications (Dapps), we have been examining the decentralized options for RNG to build Dapps that don’t compromise for traditional, centralized, thus insecure methods of RNG. A few options currently exist, but none that are truly decentralized. As a result, we decided to build our own decentralized RNG mechanism that any person on the Ethereum network could interact with; we call it Lava.

In this post, we’ll reflect on our experiences building Lava, a layer-2, decentralized random number generation mechanism for Ethereum. Our goal is to give readers and developers a start to finish guide on Dapp development. We’ll give insights into the architecture of the Lava platform itself, then dive deeper into the stack we used to build the UI associated with the platform. To start we’ll take a closer look in Lava and the mechanisms that make it work.

What is Lava?

Lava is a system that aims to provide random numbers in a decentralized fashion. People can pay to get random numbers, earn money by submitting random numbers, and earn money by predicting the outputted random numbers (more on this next).

You can think of Lava as a game played between 2 parties: randers and preders. Randers submit “random” numbers and preders try to predict what those random numbers will be. Each party deposits wei to “stake” their own trustworthiness. The entire game is financed by customers — entities that purchase random numbers from Lava.

Lava is guaranteed to yield a positive expected return for randers and preders in the long run when certain conditions are met. Randers are required to submit random numbers between 1 and 65536. Furthermore, there should 100 active randers and 100 active preders (if there are ever more than 100 of each player type, then participating players would be incentivized to generate new contracts to meet the conditions for their own positive expected return).

If you’re interested in the math and economics behind Lava check out our github for a more in-depth break-down of the design.

Why Lava?

As we said before, there are RNG oracles that exist right now, and even more in the works. However, we found that existing oracles sacrificed various elements of decentralization. Threshold relay mechanisms are among the most promising but still are under development by most firms (Oroboros, Keep, …) and their complexity may deter participation. Traditional means of decentralized RNG lend themselves to security vulnerabilities. For instance, taking the last few characters of a hash is essentially centralized RNG, and the “stake-reveal-xor” scheme is computationally costly and requires significant staking on behalf of the randers. Then there are oracles, which, for our non-blockchain readers, we discuss briefly alongside centralized RNG.

Let’s say you were playing some gambling game where you flip a coin and bet on whether or not the outcome will be heads or tails. The outcome for this coin flip should be determined by some source of randomness, right? With a centralized source of randomness (including oracles, or external, non-blockchain sources of data, comparable to APIs), it’s easy for the blockchain to just request a random number from the source. However, one of the gamblers may also be that centralized source of randomness, thus compromising the supposed fairness of the game. Hence, we turn to decentralized RNG: Lava.

Lava is simple and vulnerabilities in its promise of true randomness expose profit opportunities for all observant, active randers and preders.

Goals of Lava

We had 2 goals: to solve secure, decentralized random number generation in the simplest way possible and to make this technology as accessible as possible. The contracts and the math empowering them are intended reach the former goal, but we knew that documentation and simplicity alone would not suffice in making Lava fully accessible. Additionally, we were interested in exploring ethjs as an alternative to web3. Therefore, we made a full dapp with ethjs that would show Lava in action with comments.

Together the hope is that we can build a network of preders and randers that serves as a reliable RNG source for developers building platforms and Dapps on Ethereum. Now we’ll take a close look into the development process and breakdown the technologies we used along the way.

Tech Stack Breakdown

The first step in building the Lava platform was to write the smart contracts that hold Lava’s core functionality. There are many development tools for building smart contracts and we considered multiple before we started building.

We predicted that Lava would be a relatively straightforward contract and would not require extensive testing or development of helper contracts. As a result we decided to write the contracts in the Remix IDE and test functionality there. Remix is easy to use and good if you need to write simple contracts fast.

If we had anticipated that the contracts would be more complicated, then we would’ve elected to use a traditional truffle-ganache setup. Additionally, although we knew that truffle and web3 worked well together, it was unclear if the same synergies existed between truffle and ethjs. Being new to ethjs, we played it safe and avoided truffle and related tech altogether.

We won’t look directly at the Solidity code in this post, but if you’re curious in the implementation you can view the contract code here on github.

Initial Evaluation of web3 vs. ethjs

In addition to building the Lava contracts and deploying them to Ethereum’s Mainnet and Rinkeby networks, we also wanted to build a UI that would interact with the Lava contracts. This gave us an opportunity to test some new Javascript libraries, and the code we wrote will also help us educate others on how to interact with Lava using javascript. The UI needed to be able to do 3 simple things:

  1. Have a button to request random numbers.
  2. Have a field to submit random numbers.
  3. Have a field to predict random numbers.

To build this UI, we decided to create a simple one-page React app. We also needed to chose an Ethereum compatible Javascript API for interacting with contracts on the Ethereum blockchain. Web3js is the most popular choice among developers but we decided to try an emerging alternative called ethjs for the purposes of learning and exploring its potential as a better alternative to web3js.

Ethjs brands itself as a “optimised, light-weight” alternative to web3, boasting an impressive 106kB minified size while web3 seems to still be growing ad infinitum. Due to this reason alone, if ethjs was all it promised to be, then we would elect to use it over web3 in future projects. Now we’ll take a closer look into the code itself and how we used ethjs to interact with the Lava contract.

A Look Into The Code

We built the UI as a single page React app. We decided to store useful contract information in the application’s state and update as we go like this:

Storing Contract Info In State

The ethjs library works similarly to web3js for getting an instance of a contract on the Ethereum network. To get an instance of a contract you first get the ETH instance with the current provider, then use that ETH instance to create a contract instance as follows:

Getting A Contract Instance

Moving on, it helps to have a function to check if a transaction has been mined or not. Just like with web3js you can write a simple function to do this utilization transaction hashes. Here’s how it looks with ethjs:

Waiting For A Transaction To Be Mined

Next, developers building on top of the Lava platform will need to call functions within the Lava contract. Here’s an example of how you would do that using ethjs and the Lava contract information. (Here we are submitting a random number ).

Submitting A Random Number

Its similar to web3js in that you get an instance of the actual Lava contract, then call functions with the required parameters.

Developers will also need to listen for events being broadcasted by the Lava contract. Our Dapp doesn’t listen for random number submission but yours might! Below is an example of how you would use ethjs to listen for events broadcasted by a smart contract. Note that in ethjs, one uses the filter module to do this listening. After creating an instance of the Lava contract, create a filter instance for the event of interest.

An Event Listener In ethjs

Check out the UI code repo to see the entire front-end implementation here.

Some Thoughts On Our Experience

Overall the development process (including smart contract development, environment setup, UI development, and deployment) was fast and relatively straightforward. However, the biggest pain points came from learning and using ethjs. To start, it was hard to find good documentation for the library. Additionally there are few quality tutorials that demonstrate how to build a Dapp using ethjs. Despite this lack of good documentation we were able to get the Dapp working (after diving deep into the ethjs codebase itself and looking through obscure ethjs bug threads).

We successfully provided an example of ethjs in production, and we learned a lot along the way. Among those bits of learned knowledge: Don’t use ethjs. The community pales in comparison to that of web3 in scale and ethjs is still riddled with unresolved errors that its small development staff doesn’t seem to have the time to fix. For instance, in listening for contract events with ethjs’s analog of web3.eth.filter(), we always would receive an unresolved and known error holding the result we want instead of just the result. When we did receive the result, the error existed anyway. Therefore, we decided to lookout for that error by default, and take the result we wanted from the error. Such is life.

Moving Forward

Lava is a great development in the space of decentralized RNG and should be considered as a public utility. The UI we built is primarily for educational purposes (of which a lot of the content in this post is drawn from).

As we move forward, there are more tools and libraries we’d like to incorporate in the development of our platforms and Dapps. One is OpenZeppelin smart contract libraries. Lava uses the OpenZeppelin smart math libraries to ensure secure computation and functionality, but this is just one example of how useful the OpenZeppelin library can be. We’ll keep using OpenZeppelin solutions to provide exceptional security in our smart contract layers.

As we mentioned earlier we’d prefer to use truffle development tools in future projects as well. We chose to omit them in this project because of the lack of tried-and-true truffle-ethjs compatibility, but if we’re using web3js, truffle can provide a lot of benefits for development flows, deployment, and testing as well.

Conclusion

Lava is an important and exciting project that will act as a reliable source of RNG when building on Ethereum. Building the Lava platform was enjoyable and adding a UI to help educate others proved to be valuable as well. We’d love to get feedback on the project and are always open to improvements and iterations on the design.

Checkout the Lava website here and play around.

Our goal with these posts is to share our experiences with others in hopes that we can further strengthen the development community in the space. Feel free to reach out to us if you have specific feedback or just want to chat.

This post was co-authored and edited by Ian Lapham and Kenny Peluso.

Ian’s Twitter : @ianlapham

Kenny’s Telegram: @kennypeluso

Fork us on GitHub!

Stay tuned for more projects and posts on Super Deep Bytes.

--

--