The Tale Of Our Micro-Economy: Ethereum & Internal Ledger

Teodor Pripoae
Kuende
Published in
4 min readNov 15, 2018

As mentioned in our previous article, due to various reasons we have decided to initially develop our micro-economy as a mixture between Ethereum Blockchain and a proprietary Internal Ledger. In this series of articles we will go through the mechanics of our economy, looking to address every actionable part of it, from deposits/withdraws to challenge creation, curation and participation.

Users will interact with our Internal Ledger through a Smart Contract deployed for each user. This contract allows users to deposit KUE by sending the amount they want to deposit to the contract address. The funds are locked into the contract address until the user decides to withdraw the tokens from our platform.

The contract looks like this:

Kuende Deposit Proxy Contract

We had two options for allowing users to interact with our Internal Ledger. Deploying one Smart Contract for each user or generating one wallet for each user. This is the case because we want to allow users to deposit from multiple wallets without knowing in advance the user’s wallet address.

Smart Contract VS Wallet Address For Each User

Smart Contract
We deploy a pool of smart contracts which are not assigned to any user. When the users click the deposit button, one of the unassigned contracts is assigned to them. If the user already deposited in the past we return the same smart contract address used. Users can deposit at any time to that contract address and we adjust the balance in our Internal Ledger.

Users then can send KUE tokens to the contract address. We are monitoring all transactions of Kuende Token and if one transaction matches funds sent to an address which is a deposit address, we process the transaction and add the funds to the user’s internal balance.

When the user decides to withdraw tokens from their balance, we verify that the tokens are not currently staked in any challenges and we decide if the user is allowed to withdraw that amount or not. If successful, we call the smart contract withdraw_with_fee method. Since calling this function requires the Gas to be paid by us, we take a fee which will be calculated in tokens based on ETH/KUE parity. The tokens are locked in our Internal Ledger starting from the moment when user clicks withdraw until the transaction is confirmed on the blockchain and a number 30 of blocks are confirmed.

Advantages

  • We pay only for one transaction when the user withdraws funds.
  • Gas for the withdraw transaction is paid from the address which deployed the contract

Disadvantages

  • Wallets need to be generated in advance (deploying a smart contract usually takes 1–2 minutes)
  • Deploying a smart contract costs a small amount of ETH (the Gas to be paid for deploying the contract)

Wallet
When the user decides to deposit KUE into our platform we generate one wallet, storing the wallet public/private key in our database. The user can send KUE tokens to this address and the validation is similar to the Smart Contract deposit presented above.

When the user decides to withdraw the funds from their balance, we send a transaction from their Internal Wallet to their external wallet. We also need to send a transaction from their internal wallet to our wallet for the commission fee.

Advantages

  • We don’t pay anything when we generate the wallet
  • We can modify withdraw logic regarding fees

Disadvantages

  • We pay for two transactions instead of one
  • Internal wallets need ETH to cover the Gas to be paid for the withdraw transaction
  • We need to securely store all the public/private keys for each internal wallet

Taking into consideration both advantages and disadvantages, from the two deposit methods, we decided to implement the smart contract variant.

Implementation

Before we dive into the actual implementation, I need to introduce you to our internal application stack.

We started Kuende as a monolithic Ruby on Rails application which was fast for prototyping but got very difficult to manage after. After our Seed Investment (2016), we decided to adopt micro-services, extracting logic from the monolithic Main application into small services. Since Ruby was slow for applications containing a lot of business logic and concurrency, we decided to adopt Scala and Go as our main languages. Scala and Twitter’s Finagle stack is used for developing our micro-services, while Go is used for most of our infrastructure duties (more details on that on follow up article).

Considering we are using Ruby and Scala for our micro-services we looked after web3 libraries on this platforms. Ruby does not have a good maintained web3 library and for Scala there exists a web3j Scala library which is a wrapper over Java official web3j library.

Unfortunately the web3j library is not integrating well into our async stack being based on sync calls or observables (we are using Async Futures as a concurrency model) so we looked into integrating web3 with Ruby.

Taking into consideration that Parity is written in Rust and knowing that Rust can be easy integrated with Ruby using the Helix library, we decided to go this route. In conclusion, all the blockchain part was implemented using a Rust library - deploying smart contracts, watching web3 events and making smart contract calls. We call all this functionality from Ruby while keeping the same application framework we are already using for the other services.

This is the first step in our quest to be fully transparent to our community and share our journey, technical challenges and important decisions that we made in the past and considering in the future.

Thank you for your support and we welcome your feedback and input on everything we publish here on Medium.

Chat on Telegram (English): t.me/kuende

Visit ICO Website: ico.kuende.com

Check our Product: kuende.com

--

--