Decentralized Uber: Here’s How I Built It With Status.im, Waku, and Vue.js

Instead of putting the taxi driver out of a job, blockchain puts Uber out of a job and lets the taxi drivers work with the customer…

Decentralized Uber: Here’s How I Built It With Status.im, Waku, and Vue.js

Instead of putting the taxi driver out of a job, blockchain puts Uber out of a job and lets the taxi drivers work with the customer directly. — Vitalik Buterin

When I first time read the above quote from Vitalik Buterin, I started to think about how to implement a decentralized Uber-like car-sharing application. Blockchain is expensive and not invented for storing temporary data like car positions. The answer is that not blockchain is the answer. We have to go deeper.

The basic mechanism of a p2p car-sharing app is that the passenger broadcasts a car request with her coordinates. The drivers get this request, and who has a free car, answers to it. The passenger receives the answer and chooses a driver. As you can see what we need is a messaging protocol with broadcast functionality. Something similar is used to broadcast the finished blocks in the blockchain network.

Ethereum has its own messaging protocol called Whisper. Unfortunately, it is not really known and it is not supported by default in the Ethereum clients. Fortunately, there is a project called Status.im that has a protocol called Waku that replaces Whisper. Waku is based on libp2p and supports topic messaging through gossipsub, so it fully meets our needs. (I have an article about libp2p. It’s recommended to read it to understand the basics.)

Now we have a basic concept and a pub/sub protocol. Let’s design a minimalistic UI for it. My minimalistic UI looks like this:

A simple google map with 3 buttons. The first button is the profile button. I’ve tried to find the easiest solution that is possible for profile management. Gravatar is a simple general profile service where you can assign a profile image and some profile data to your e-mail address.

It’s used in many services like GitHub, WordPress, etc. and it can store basic profile data, so it will be good for us. On the profile panel, you have to give your e-mail address only, and the application will download all of your profile data from gravatar. It is important to set a phone number or a Skype account because your possible passengers can access you through it.

The second button is a toggle button for car sharing. If you click on it, the color of the button changes to green, and the app will subscribe to the broadcast topic. If an incoming call comes the app will show a blue marker. If you click on the marker, you can make an offer to the possible passenger.

The last button is for the passengers for calling a car. If a passenger clicks this button, the app will broadcast the request to the drivers. If a driver mak an offer, a green marker will be shown. The passenger can choose one of the drivers and he can call her using the given Skype account or phone number.

That’s all. As I wrote before. It is a fully minimal implementation of the conception. The aim of it is to help to understand how the p2p pub/sub system works under the app. Let’s look at the code.

Initializing Waku is really simple.

this.waku = await Waku.create({ bootstrap: true }); await this.waku.waitForConnectedPeer();

These 2 lines of code will download the actual list of Waku bootstrap nodes and wait for some peers to be connected. After this initialization, our application will be a part of the Gossipsub mesh, and ready to send and receive messages.

let privateTopicName = "/waku-uber/1/" + parsedAvatarData.hash + "/proto";
this.waku.relay.addObserver(
(wakuMessage) => {
this.processPrivateMessage(wakuMessage);
},
[privateTopicName]
);

Every client subscribes to a special private topic that is generated from the e-mail hash to make it unique. The app will use this topic when a driver makes an offer to a possible passenger. The subscription is done by waku.relay.addObserver. The topic name can be anything, but Waku has a recommendation for the topic name format.

const payload = proto.WakuUberMessage.encode({ 
type: proto.Type.REQUEST,
lat: this.myPosition.lat,
lng: this.myPosition.lng,
avatarHash: parsedAvatarData.hash,
});
const wakuMessage = await WakuMessage.fromBytes( 
payload,
broadcastTopicName
);
await this.waku.relay.send(wakuMessage);

Messages can be sent by waku.relay.send method. The method has only one parameter, a WakuMessage that is built from a payload and a topic name. Waku uses binary payloads. It is possible to send strings as messages, but the binary format is recommended because it’s more compact. There is a tool called Protocol Buffers for defining message structures and encoding/decoding them. Our simple message format definition looks like this:

enum Type { 
REQUEST = 1;
RESPONSE = 2;
}
message WakuUberMessage { 
Type type = 1;
float lat = 2;
float lng = 3;
string avatarHash = 4;
}

It contains a type field that can be REQUEST (customer call a car) or RESPONSE (the driver makes an offer), a lat./long. for the geographical coordinates, and the hash of the sender’s e-mail address. The application can get the gravatar info with the e-mail hash and the private topic is also generated from it.

In nutshell, these are the important parts of the application. You can find the full code on GitHub.

I know, this is a really minimal implementation of a car-sharing app, but with some improvements, it could be developed into a real application. Let’s see some of these improvements:

  • Real identity management. A blockchain-based identity system could ensure trust between the driver and the passenger. The messages could be encrypted and signed by the peers’ public/private keys, and the peers could be identified by 3rd party identity providers that could prove the validity of the profile data, check the driving license validity, etc.
  • Location-based broadcast. In the current implementation, every driver receives every request even if the passenger is at a great distance from the driver. This could be managed by more broadcast topics that are based on geohash.

As you can see when you build a decentralized application blockchain is not always the answer. Sometimes it’s worth digging deeper into the p2p stack. Peer-to-peer pubsub services like Waku can be used in many ways. You can build your decentralized Uber or decentralized Airbnb, you can build decentralized databases or your very own blockchain.

Happy coding…

This article was originally published here.