Introduction and Motivation

ETH With Friends is my first true foray into the Dapp (decentralized app, an app that is built to interact with the Ethereum blockchain) building world. I love everything about Ethereum and the potential it has to eliminate middlemen, transaction fees, and fraud across a variety of industries.

The fuel of the Ethereum blockchain is Ether (ETH), which is also a virtual currency that can be used to make real world purchases (through something like TenX), exchanged for Bitcoin or other cryptocurrencies, or exchanged back to fiat currency (using something like Coinbase).

One problem is that you need an Ethereum wallet to use ETH in a meaningful way, and these wallets are addressed by a long hexadecimal string of numbers and letters (such as 0x00c63DA10aa538CA40b95e0d0DCd4F8A356AbA1e). Sending ETH to someone else involves copy-pasting this address, where one wrong character will make you send your money to the wrong place.

On the other side with fiat currency, I absolutely love Venmo. It allows me to look up and send money to (or request money from) any of my Facebook friends.

I have a couple of friends who are into ETH like me, and I would love if there was a way for us to pay each other in ETH without the friction of having to ask for the address and copy-paste it each time. This is what motivated me to build ETH With Friends.

Disclaimer: I know about ENS and that the point of that is to solve this problem, but the service is not ready yet, and also it requires people to sign up for a domain name, which is equivalent to asking people to buy a domain name from GoDaddy and the like. There is a lot of friction in this process, and there are no social features.

Building the Dapp

The Stack

Dapps are a really interesting way to build web apps because they are full-stack web apps without a backend. Essentially the Ethereum blockchain is your database and the smart contracts make up the business logic layer. The only infrastructure you maintain is the front end single-page app.

The framework I used for this is Truffle. Truffle is an excellent tool that allows your smart contracts to be used easily in a front end application. Coming from a JS-heavy web dev background, I found their premade React box the perfect starting point.

The Smart Contract

In order to look up your Facebook friends’ Ethereum addresses, the smart contract needs to store a mapping of Facebook profile to wallet address. Should be simple right? We can just use the Facebook profile ID of the user as the unique identifier, and use a method to set your profile ID to the wallet address of the sender, ensuring that you have the private key of the address you are setting.

This would work perfectly well through the Dapp front end, where we can use Facebook’s API to seamlessly pass this information through to the contract. However, you can call a contract directly through an Ethereum wallet and pass any information into the functions directly, bypassing the Dapp. In this situation, we can have a nefarious actor find out someone else’s Facebook profile ID and set it to their own wallet address. Imagine wanting to send money to your best friend, and instead sending it to your worst enemy!

The way we can deal with this issue is through an Oracle. An Ethereum Oracle is a service that provides real world data into the blockchain. It can be used to prove that things happened off-chain, and insert that data on-chain. Oraclize is probably the best known Oracle service. They support a variety of data sources, but the one we care about is the URL data source.

When you log in with Facebook, you receive an access token. This is a token that can be used to confirm your identity and logged in status. We can use a simple REST endpoint with this access token to determine if the token is valid: https://graph.facebook.com/me?fields=id&access_token=<MY_ACCESS_TOKEN> .

Again, this data is seamlessly passed into the contract through the Dapp, so a normal user would never have to worry about it. The purpose is only to prevent nefarious actors from going around the Dapp directly to the contract.

Smart Contract Code

The smart contract code to make this all happen is below:

The main magic in this code is the Oracle. We take the facebookAccessToken that is passed in to the function, and then pass that to an Oraclize query with the formed URL. Note that concatenating strings is not an easy task in Solidity, and I needed to use a library to make the process easier.

Another thing to note is the mapping (bytes32 => address) requestMap; . This is so that we can store the msg.sender with the particular Oracle query (a random ID that would be impossible to fake). This protects against another security issue: a man-in-the-middle attack where someone could call the __callback function directly and try to fake someone’s Facebook profile ID.

The Dapp

The smart contract handles all the business logic and data storage, so the only other part to build is the Dapp, which is the front end to our smart contract. For the UI, I went with the well-designed Material UI Framework, a framework of React components designed according to Google’s Material Design specs.

The main features of the Dapp are:

Interact with the contract to link your wallet address and Facebook profile ID.

Use the Facebook API to find your friends that have also linked their wallet addresses.

Send money to your friends.

The contract abstractions in Truffle make compiling, deploying, and interacting with the contracts extremely simple, and the

The final (inital) UI:

ETH With Friends v1 UI!

The top section notifies the user that they are connected to Web3, and lets them check their mapped wallet address, and set it if they haven’t. It also allows them to log into Facebook if they aren’t already.

The bottom section uses the Facebook API to find your friends who are also signed up and who have registered their address. Clicking on the friend’s name allows you to send money through your Web3 wallet, without having to type in addresses!

Deployment

The app gets deployed as a static website, so there are a few great solutions to make that process very simple. GitHub Pages is a favorite, but I found the workflow for Surge to be nicer. I bought a domain name for the site using my favorite DNS service, Zeit and configured the alias to point to Surge.

Finally, I set up Travis CI so that every time code is pushed to the master branch, it builds and deploys with Surge.

Wrap Up and Future Thoughts

When I tested the tool myself, I was amazed by how easy it was to send ETH to my friend. I have sent ETH to friends before, and it was always a little sketchy feeling to copy-paste addresses.

Some people may not like this idea in general because of the fact that you have to publicly and permanently tie your wallet address to your Facebook profile ID on the blockchain. The overlap of people that view Facebook as a company favorably and the people who transact ETH is not very strong. However, I think Ethereum is going to become more and more mainstream, and tools like this are going to be necessary to power our crypto-currency future. This tool is completely opt-in, and designed to be a convenience for people who want an easy way to pay and request from their friends. I have no problem with tying my Facebook profile to my Ethereum wallet address (one of them at least), so this is something that will work for me.

Future Enhancements

Add request functionality — request ETH from your friends, and pay them back easily from the Dapp.

Move deployment to IPFS — Deploy to a decentralized storage solution.

Improve UI/UX — My web design skills are the weakest of my skill-set as a full-stack dev, so this will take some iterations (I would love feedback and suggestions, though!).

Try It!

The Dapp is live now at http://ethwithfriends.xyz/. It’s running on the Kovan testnet right now, but I plan to migrate it to mainnet after I get a few more people to help me test it.

The code is all open source and available at https://github.com/rhlsthrm/eth-with-friends. I would love to see any feedback, suggestions, bug reports, and pull requests!