Rewriting an Application on Blockchain

Artod
7 min readMar 22, 2018

--

Before and After

I would like to point out at the outset that this article is not about how to write code on Solidity but how the existing classical architecture of your application can be translated into the blockchain rails and how to start thinking in terms of decentralization.

A couple of years ago I worked on an interesting Web App of the p2p package delivery service. For some reasons, the development had to be frozen at the prototype stage, so I just put the source code on GitHub and forgot about it.

Recently, I have had the opportunity to work on several projects related to cryptocurrency and blockchain-technologies. Taking a closer look at Ethereum and its ideology of decentralized applications (ĐApp), I got carried away with this idea: no censorship, no one can close your business, no one can confiscate your funds, it is impossible to simply shut down the server your application is running on.

At some point, I came to the conclusion that only in such an environment my project can have a chance to develop and thrive.

Let’s take a look at the upcoming work

The original idea was that people, who travel often, could deliver any packages in their suitcases or cars for money or for free. A sort of Uber for delivery. Users are divided into travelers and customers. If you are going to travel, say, from New York to Montreal on weekend, you can add a new trip to the service with a description of what you can deliver and when. Subscribed customers are notified of a new trip in this direction and can add requests for the delivery of, for example, some medicine or a new bicycle for a little brother. The parties agree on the payment (escrow on PayPal) and the terms of delivery. After fulfilling the order, the parties can leave ratings and comments about each other. Each user has a small statistic in the profile.

Over time, there was a rethinking of some points in the algorithm of the service. It became clear that it would be more correct if customers added their orders first, and then carriers could choose whom to render the service. As we will see later, this concept provides better flexibility and scalability.

In fact, we need to rewrite the entire back-end in smart contracts and deploy to the Ethereum blockchain. The application will be absolutely transparent, immutable, decentralized and therefore free of regulation even by the developer himself. Thus, we will get a decentralized platform on the basis of which any person can implement their front-end, mobile or server application.

The protocol of such service will be as follows:

  • A Customer adds an Order for delivery from point A to point B
  • A Carrier can add an Offer
  • The Customer can add a Respond to the Offer
  • The Carrier issues an Invoice for payment of the Order indicating the amount of the Prepayment and Deposit
  • The Customer pays the Invoice and can set a Key to the Deposit
  • The Carrier fulfills the Order and receives the Key to the Deposit (QR-code for example)
  • The Carrier can at any time refund the money to the Customer
  • The Carrier and the Customer exchange their ratings and comments

Let’s get started

This protocol will be implemented by a smart contract in Solidity, which we will call Osliki. First, we will create variables to store orders, offers, invoices and statistics:

Order[] public orders;
Offer[] public offers; // here will also be stored responses from customers
Invoice[] public invoices;
mapping (address => Stat) internal stats; // mapping from user addresses to their stats

Description of all structs:

struct Order {
address customer;
string from; // geo coordinate in 'lat,lon' format or Ethereum address '0x...' or empty
string to; // geo coordinate in 'lat,lon' format or Ethereum address '0x...' or empty
string params; // package params in 'weight(kg),length(m),width(m),height(m)' format
uint expires; // expiration date in SECONDS since Unix Epoch
string message;
uint[] offerIds; // array of carrier offersaddress carrier; // chosen carrier
uint invoiceId;
EnumOrderStatus status;
uint createdAt;
uint updatedAt;
}
struct Offer {
address carrier;
uint orderId;
string message;
string respond; // customer respond
uint createdAt;
uint updatedAt;
}
struct Invoice {
address sender; // carrier
uint orderId;
uint prepayment; // amount for the prepayment
uint deposit; // amount for the deposit
EnumCurrency currency; // ETH or OSLIK (no fee)
uint expires; // expiration date in SECONDS since Unix Epoch
bytes32 depositHash; // Ethereum-SHA-3 (Keccak-256) hash of the deposit key string provided by the customer
EnumInvoiceStatus status;
uint createdAt;
uint updatedAt;
}
struct Stat {
uint[] orders;
uint rateSum;
uint rateCount; // averageRate = rateSum / rateCount
mapping (uint => Review) reviews; // mapping orderId => Stat
}
struct Review {
uint8 rate; // range between 1-5
string text;
uint createdAt;
}

Statuses:

enum EnumOrderStatus { New, Process, Fulfilled }
enum EnumInvoiceStatus { New, Settled, Closed, Refund }
enum EnumCurrency { ETH, OSLIK } // fee of 1% for ETH and no fee for OSLIK

Next, I will not list the bodies of functions, otherwise it will take too much space. Below, there is a link to the source code on GitHub.

A Customer adds an Order for delivery:

function addOrder(
string from,
string to,
string params,
uint expires,
string message
) public;

A Carrier adds an Offer:

function addOffer(
uint orderId,
string message
) public;

The Customer responses to the Offer:

function respond(
uint offerId,
string message
) public;

The Carrier issues an Invoice:

function addInvoice(
uint orderId,
uint prepayment,
uint deposit,
EnumCurrency currency,
uint expires
) public;

The Customer pays the Invoice:

function pay(
uint invoiceId,
bytes32 depositHash // customer sets a keccak256 hash of the key for accessing to the deposit, it can be empty if there is no deposit and all funds are paid in advance
) public payable; // after payment, the invoice is attached to the order, and the sender of the invoice is considered to be chosen as a carrier.

The Carrier fulfills the Order and receives the Key to the Deposit (scans QR-code for example):

function fulfill(
uint orderId,
string depositKey
) public;

The Carrier can at any time refund the money to the Customer:

function refund(
uint invoiceId
) public payable;

The Carrier and the Customer exchange their ratings and comments:

function addReview(
uint orderId,
uint8 rate,
string text
) public; // here we update stats

Plus a few more functions for retrieving data.

As a result, we have 2 contracts:

  • Osliki contract that implements our protocol and is the core of the platform for building any business related to or dependent on delivery.
  • Token OSLIK — inner currency that can be used for payments without fee. Tokens can be sold through the crowdfunding campaign to raise funds for the development and promotion of the platform and services built on this platform.

Examples

Essentially, the Osliki contract is an open database of delivery orders that can be used by any individual, organization or some kind of drone like Amazon Prime Air.

Imagine an entrepreneur with a fleet of cargo drones based on the roof of some building in your city. Drones scan the database in the blockchain and if an order corresponds to some specific parameters (an acceptable range and cargo dimensions), they automatically send offers and invoices, and then fly to fulfill the order.

Imagine Mr. X from Craiglist that grows in his backyard a very fragrant variety of cannabis (of course, in countries where it is legal). He sends you a link where you can add an order to Osliki containing the ethereum-address of Mr. X directly, so that other carriers could not spam the offers. Then you receive an invoice, you pay, and in couple of hours the parcel is in your hands. And even if the account of Mr. X will be blocked on Craiglist, fans of his agricultural talent will always remember where to send orders.

You can also imagine a marketplace where farmers sell their organic vegetables, fresh milk and meat. Delivery can be carried out, for example, by drivers shuttling between town and country. Farmers will thus have unlimited access to retail customers bypassing supermarkets.

As well, the original idea with travelers delivering something in their suitcases or cars remains relevant.

Plans

It would be nice to have here a decentralized marketplace (Osliki Marketplace) or classifieds (Osliki Classifieds) as a part of the platform. Or, perhaps, use ready solutions.

By using the methods of BigData and AI, we could more deeply analyze the behavior and statistics of each user and get results about his reliability. For example, identify users who cheated with ratings.

At the moment, the task is to implement the front-end application osliki-js (as one of the variants) and publish it with GitHub Pages (or any other static site hosting) so that we could work with contracts in the usual way in the browser. Plus a set of widgets for embedding on websites.

If this topic seems interesting to you, you can join the development.

Links

Links to the source code on GitHub:

Contracts are currently deployed on the test network Ethereum Ropsten. Test ethers are dispensed here.

Addresses of contracts:

--

--