How to build your crypto game for SAP Quorum
After the introduction on how to start developing your Smart Contracts for SAP Quorum using Embark, let’s try to build something tangible.
Here I’m proposing a crypto game. The idea of it is that users should open a url in their browsers, which will initialise the app with an associated crypto account containing preloaded balance of crypto funds (it’s $100 by default). Users then should be able to buy and sell assets (emojis) fluctuating in price. The goal of each player is to maximise their own balance by making smart investments (buy low and sell high).
This is how the app looks like:
The ‘progress bar’ on top counts 10 seconds until the next fetch call to refresh the player’s emojis balance and prices from the server. I promise to implement something more elegant next time 🙂
So players interact with the blockchain and our Ethereum smart contract without even knowing it by tapping buttons on the screen of their mobile device. They don’t have to pass authentication or to create any crypto wallets or to memorise a seed phrase. Their account will be vanished in the browser as soon as they close the tab.
The price fluctuations are not hugely scientific at the moment as they’re just randomised by the contract’s logic. However, it would be interesting to simulate a pricing model dependent on supply/demand for each asset (emoji) in the real time.
The game winning conditions should also be defined in a more strict way in the future.
Let’s have a look at the details.
High level architecture
The app consists of three layers: UI built on OpenUI5, middleware built on TypeScript and smart contracts written in Solidity.
Yes, it’s an example of a centralised architecture. I will explain why I’ve introduced the middleware layer just a bit below.
It’s quite simply built on OpenUI5. It’s responsive, but it’s quite heavy at the moment for such a simple screen. So the front end app needs to be optimised in the future. SAP React components is probably the way to go to make it fast.
The canonical flavour of an decentralised app is a serverless one, where the entire interaction happens between the client and the blockchain. However, in this case a user has to establish a connection to their web3 provider via the very popular Metamask browser extension, which acts like a lightweight client to the blockchain and works as a digital wallet containing public/private keys for user’s account.
When users perform state-changing actions on smart contracts by submitting transactions, Metamask will sign those transactions client-side and relay them to the Metamask public nodes.
What to do then for those users who don’t have Metamask? We want to enable user perform blockchain transactions directly from the UI5 application without needing to install any software at all. The easiest answer is to establish a connection to a public blockchain node (similar to Infura for Ethereum). In our case we have to create such a basic node ourselves. It will act as a gateway for contract functions and contain access keys to the smart contract’s cloud hosting (SCP).
So our node is merely an Express.js instance handling the API routes and calling the underlying contract’s interface methods. I made it TypeScript based, but it’s a mess at the moment and doesn’t pass many of the basic TS linter checks. It can potentially include reactive libraries to make it more declarative and robust.
This is the most interesting part. The contract re-uses the OpenZeppelin’s ERC20 implementation adapted for our use case (it’s also versioned down for solc 0.4.24). The main difference here is that all the funds inside of the application are not fully decentralised and always belong to the ‘master account’. This is due to the fact that we have to operate via the central account hardcoded in the middleware node on behalf of the account actually calling the contract. So the standard ERC20 allowance mechanism has been slightly enhanced to enable the ‘master account’ to acquire funds of the users’ accounts.
On contract instantiation it is supplied with one hundred million coins to have enough liquidity for all the buy/sell operations. The ‘master account’ automatically deposits the initial amount of 10000 coins to every newly created account. Theoretically it means that we can register approximately 10000 users after which the ‘master account’ will be depleted and won’t have enough funds to buy emojis from users. But it should be enough for the initial version of the game.
The contract also contains a ‘global inventory’ of emojis for all the accounts. There are 255 emojis for each of eight types created on contract instantiation. All the individual accounts’ balances are tracked by a separate data structure. When a user buys an asset, the amount of funds which equals to the price of the asset is transferred from the buyer to the ‘master account’. Also the count of the asset is decreased by one in the inventory and increased by one in the user’s individual balance structure. Theoretically this limits the lifetime of the contract significantly as the central inventory will most likely be empty for certain types of assets after a hundred or two of new buyers.
So you are very welcome to suggest a better exchange mechanism or an inventory clean up function! There must be a way to create a truly ‘circular’ nano economy in the contract and make the contract’s lifetime indefinite!
This is only an initial step in the topic of tokenisation and micro payments. A few ideas are floating around in the business area here and there, so I believe smart contracts will bring great value to our customers in the nearest future. Gamification just shows that the apps don’t have to be too difficult for the end users to interact with blockchains. Thank you for reading.