HBZ payments - A technical perspective by Carlos Beltran (Blockchain Dev Helbiz INC.)

in #helbiz5 years ago

What’s going on under the hood when using HBZ tokens for scooter rides inside the Helbiz app
By Carlos Beltran (blockchain dev @Helbiz | focused on building the future 🚀) Helbiz INC.
Original Post https://medium.com/helbizofficial/hbz-payments-a-technical-perspective-dc089029a1ad

1_IBbnymAh0wggw_-B9aDffA.jpg (Graphics by Graphic Designer, Alexey Yalyshev)

Today HBZ payments was introduced into the Helbiz app and in this blog post, we’ll go over HBZ (HBZ Coin) payments from a technical perspective, giving a high-level overview of each component from wallet management to smart contract event monitoring. The purpose of this post is to educate developers who are curious about what’s going on under the hood when using their HBZ tokens for scooter rides.

Overview

First, I’ll summarize the project as it was described this Medium post.

1- First, HBZ take ownership of customers’ HBZ tokens when they transfer them to their in-app wallet.
2- Then, Helbiz’s private network registers these deposits and credits the user’s HBZ balance in the application.
3- Finally, every HelbizGo scooter rental deducts from this balance until the customer has to acquire more HBZ.

It’s important to note that we’re not processing payments for EACH scooter rental on Ethereum, only the initial deposit of tokens and that no tokens are directly held by Helbiz. We are managing tokens this way to avoid paying gas fees making the entire experience more seamless. Eventually, we’ll process token payments on a private blockchain (this is discussed in more detail later).

The solution

The solution developed for this feature can be broken down into a couple of components:

  • A set of scripts to generate Hierarchical Deterministic wallets (HD wallets) and sign transactions
  • A nodeJS app that subscribes to events on the Ethereum blockchain — specifically the Transfer event on the HBZ token contract
  • An AWS Lambda script that processes each Transfer event, updating our records
  • A REST API built on express that exposes information about wallets and their transactions
  • A front-end app similar to a block explorer — but only displaying owned wallets and associated transactions (transfers, to be more specific)

1_e-EQKJBZQHSttd6pJT4JKA.jpg
Helbiz app v1.4.0

HD wallets and Truffle

An HD wallet is a wallet that could be derived from a master/root node, and can itself also be a master/root node if more wallets are derived from it. For more info, check out this well-written post. For HBZ payments, we generated wallets for all our users from one seed and only have to run a few scripts to sign transactions to move tokens across accounts.

Here’s sample code to generate an Ethereum wallet from a master seed.

// generate a master seed
const mnemonic = bip39.generateMnemonic();
const seed = bip39.mnemonicToSeed(mnemonic);
const rootKey = hdkey.fromMasterSeed(seed);
const hardenedKey = rootKey.derivePath("m/44'/60'/0'/0");

// now we can derive a child wallet
const childKey = hardenedKey.deriveChild(i); // 0<i<WALLETS_COUNT
const wallet = childKey.getWallet();
const publicKey = wallet.getAddress();
const privateKey = wallet.getPrivateKey();

We wrote these scripts making use of Truffle, a framework for compiling and deploying smart contracts on Ethereum. It makes development easier as we can run a local blockchain using ganache-cli and simulate token transfers, testing our code.

Monitoring smart contract events with web3

To monitor transfers on the wallets we generated for users, we can subscribe to the Transfer event on the HBZ token contract. To do this, we must first initialize the web3 library using a websocket provider, and since we’re using Infura as our node provider, we set the URL to their websocket endpoint (along with our API key).

// initialize web3 with ws provider
const Web3 = require('web3');
const web3 = new Web3.providers.WebsocketProvider(wss://mainnet.infura.io/ws/v3/${process.env.INFURA_API_KEY});

// the contract instance is created using truffle-contract
contract.setProvider(web3.currentProvider);
const helbizToken = await contract.at(helbizTokenAddress);

// subscribe to events
helbizToken.contract.events.Transfer({ fromBlock: 'latest'}, handler);

Process transactions with AWS Lambda

To offload the work of processing transactions, we deployed a script on AWS Lambda that is invoked from our app whenever a transaction emits the Transfer event. It’s a fairly straightforward lambda, but moving the logic there allows for increased and precise horizontal scaling. It’s also worth noting that this lambda sits behind a Virtual Private Network (VPN) for added security.

For reference, this is the event emitted by the smart contract:

event Transfer(address indexed from, address indexed to, uint256 value);

1- If the to value of the transfer event is one of our wallets, we should process it
2- If the transaction hash exists in our records and we received the websocket event twice for some reason, skip
3- If it’s a new transaction to one of our wallets — record the value, the transactionHash, and the blockNumber
4- Finally, make a request to the mobile app to update the user’s reflected balance

REST API

Although we push data to the mobile apps whenever we process a transaction, we provide information about a wallet and its transactions via an API using Express (obviously with an authentication strategy). The one significant endpoint we expose is to refresh the balance of a given wallet. We do this because websocket connections are not 100% stable, and Infura actually drops the connection every hour or so (see this old issue on Github). To mitigate the issue where we don’t register some transactions, we expose this endpoint so when a user goes to refresh their payments page, we can read the HBZ balance directly from the blockchain and update our records if needed.

Wallet explorer

To make life easier for the team to monitor wallets as users deposit tokens, we also added a page in the Helbiz admin panel that lets us search for wallets and individual transactions, showing information like a block explorer would.

1_k6kisJm7aCvZbg7CWSM3KA.jpg

Things to note

  • There’s a few details we left out for security reasons. Now, this probably isn’t the most secure solution, but we didn’t need to over-engineer it. That being said, any time you are dealing with real tokens, you need to take certain precautions. In this case, it would include keeping the master seed as well as private keys offline — never exposed to the internet. Also, limit access to your scripts and applications by deploying them behind a VPN and add authentication strategies to your API endpoints.

  • We mentioned earlier how the next step of this solution would be to actually process transactions on a private blockchain (can’t use a public one for obvious reasons). We’ve begun looking into several options such as Kaleido, Hyperledger Sawtooth, and deploying Ethereum with PoA on our own servers. This bleeds into the development required for building out the ecosystem for HBZ, so it’ll be a few weeks of R&D.

  • Development with web3 and its accompanying libraries has been nothing short of a headache — websockets support, beta releases that introduced certain bugs, and incompatible versions to name a few of the issues. It’s important to remember we are building on open source software that is changing and being improved upon on a daily basis!

Hopefully this post was educational for some and at the very least interesting for others.

Sort:  

Congratulations @mansions! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Coin Marketplace

STEEM 0.15
TRX 0.15
JST 0.028
BTC 54045.75
ETH 2247.37
USDT 1.00
SBD 2.30