RepuX Data Marketplace — Let’s get Technical!

RepuX
RepuX Blog
Published in
6 min readJan 19, 2018

Hello, in this article we’ll go through technical details of RepuX Data Marketplace. If you’re looking for a higher level explanation of what Marketplace is, I encourage you to read: A Token Sale with a Product — RepuX Data Marketplace. Just to be sure we’re clear — what I’ll be writing about in this article is already LIVE! You can visit it here: marketplace.repux.io.

https://marketplace.repux.io

Introduction

RepuX Data Marketplace consists of four technological layers. First, obviously, we have blockchain layer — smart contracts. Then, we have layer for communication between blockchain and our backend. After that, third layer — RESTful API application — PHP backend (for storing files we use IPFS). The fourth layer is frontend — basically it’s what you see when you browse through RepuX Marketplace — JavaScript single-page-application.

Smart contracts layer

Probably, the most interesting feature of RepuX Data Marketplace is Ethereum layer — smart contracts. Under the hood, they’re written in Solidity. We maintain them using Truffle framework. First contract is token contract — that we’re using for Marketplace. As it stands right now — we use Demo Tokens so users can easily test our application (we give each registered user 1000 free Demo Tokens). We also run on Rinkeby, you can get free Ether there by using faucet.rinkeby.io.

Crucial smart contract for Marketplace is Registry. It keeps a list of products that were created by users. Each product is represented by DataProductcontract.

You have control over DataProducts you create. All RepuX tokens earned from selling your products go directly to your wallet — no middleman.

Here’s how buying products works:

  1. User goes to Marketplace, finds interesting product and clicks BUY.
  2. First blockchain call: ERC20 approve(_spender = DataProduct contract, _value = Token Price of Product) method is called by the user — so it’s going to allow DataProduct contract to spend amount from user’s balance required to buy product. When it comes to UX — user needs to just confirm transaction in MetaMask or Mist.
  3. User calls purchase() method on DataProduct contract, that he wants to buy — transaction popup will be shown in MetaMask/Mist.
Purchase function under the hood calls purchaseFor (for transaction sender)

4. After the purchase — Registry.registerUserPurchase function is called — this function will fire PurchaseDataProduct event, which is crucial for application flow.

Function which belongs to Registry and sends purchase event.

5. We listen for PurchaseDataProduct events in our application and — when product is bought — we show download link to the user. When encryption is implemented this will be probably the moment when we can either give users password to the file, or — under the hood — we can decrypt it on the fly when user downloads it — depends if finally download will be direct from IPFS or via our servers.

Blockchain event listeners

Second layer of our application is a Node.js microservice. It serves as a listener for blockchain events and provider of Web3.js methods for backend API.

Ethereum listener in Node.js

As events in blockchain look more like a logs, we can “read these logs” in range between start block and end block. That’s helpful if — for some reason — our process would fail. We can still read and process events that happened when the listener was down. It’s a nice feature of Ethereum blockchain that events work this way.

Backend and data storage

Our backend runs on Symfony 3. We expose REST API for frontend to consume. In future we can also wire mobile applications. When it comes to data files storage we use IPFS. We’re open to alternative approaches to storing data files — as we’d also like to encourage users to replicate data files for better accessibility such as Siacoin. At this moment though, we stick to IPFS.

With regards to security, AES-256 encryption is coming to provide secure way to share files. Our PHP API also calls Node.js API when it needs access to Web3.js methods — such as verifying wallet ownership. We extract wallet address from signed message and then we check if it matches user-supplied wallet address. If it matches — we can confirm that user is owner of the wallet.

Frontend

For writing Enterprise class applications as RepuX Frontend Team we believe that Ember is a way to go. Team is already experienced in this framework, Ember Core Team cares for backward compatibility of new releases and they’ve done a lot of things right. For example, Angular team decided to copy Ember CLI repository and that’s how Angular CLI was made.

We’re using Ember 3.0 without Ember Data. Our application is compatible with Ember FastBoot (server-side rendering using Node.js). However, we‘ve decided to stick to classic deploy for the sake of stability. Currently, we’re just serving JavaScript files without precompiling DOM for our users on production environment.

We use ember-cli-mirage and ember-native-dom-helpers for testing. Mirage makes it really easy to replace our API with mocked one. Ember-native-dom-helpers will allow us to drop jQuery in the long-term thus reducing bundle size. We can also easily deal with asynchrony in our test suite — async/await for the win!

Login page

When it comes to design, we’re using a combination of Material Design and Bootstrap. During development of other applications in RepuX ecosystem — such as forms for Token Sale and KYC registration we’ve developed our own design guidelines. We try to stick to them when creating new views. User experience though is priority for us — that’s why we let users register without verifying their wallet address. We allow them to do it later.

We vastly benefit from using Ember because of it’s reach ecosystem of addons. Validations addon? Check. (ember-changeset-validations) Bootstrap 4 addon? Check. Acceptance testing super-powers addon? Check. (Mirage). That makes our life easier and allows to iterate faster. Shout out to all open-source code authors!

We also need to bundle Web3.js with our frontend application so we have access to consistent API across blockchain browsers and plugins. For example, to work around Mist vs MetaMask Web3.js differences, or one browser might not inject Web3.js at all — just the provider — which happens sometimes when using Mist.

Web3 Service

Summary

Certainly, it’s not an easy task to create decentralised application. There’s a lot of blocks that need to work together. There are issues related to immaturity of tools and technologies around blockchain and lack of documentation. It is really satisfying process though. We’re going to continue pushing the limits and exploring possibilities provided by Ethereum network or other blockchains.

--

--