How to Create the World’s First Mainstream DApp

Remove the high barrier for entry

Alex Roan
Alex Roan
Jun 13, 2020 · 7 min read
Image for post
Image for post
Photo by Joshua Earle on Unsplash

Despite the promise of decentralised applications, user experience is still not ready for mass adoption. There are plenty of projects aiming to improve this. Next-generation wallets, aimed at competing with Metamask, are working to hide the plumbing of Web3 injection. Some prime examples are Torus, Fortmatic, Portis, Unilogin and Authereum. However, in my opinion, none go far enough.

Hiding the Plumbing

My main gripe is one I’ve had since I initiated myself with DApps several years ago. As a user, every time I want to send a transaction on the Blockchain, I’m prompted with an ugly popup asking me to confirm, warning me of the cost, and scaring me away. As someone who’s been initiated in the space for a few years now, this isn’t as big a deal for me. But back then it was, and it still exists. I know for a fact that newcomers in the space are met with the same scary popups every time they try to do something. It’s offputting and is the main reason why the bounce-rate on DApps is so high.

Image for post
Image for post
Figure 1: Metamask transaction confirmation.

I get it, as a platform you need to make the user aware that an operation will cost money. The last thing you want as a platform is to be discredited because you didn’t warn users about the cost of usage, and your gas costs unknowingly drained their accounts of Ether. However, there are much better ways of doing this than the currently accepted norm.

Take a look at figure 1. Unless you’re very well acquainted with Ethereum wallets, DApps and the industry in general, you’re not gonna know what on earth this popup means. Some users will think the whole site bogus since popups emanating from button clicks is often considered shady practice. Yet here, it is the norm. And it appears every time a user wants to interact with a smart contract.

Not only that, but the fact that a whole extension needs to be installed to even be able to interact with DApps seems archaic. This is slowly changing. Opera have released DApp support in their mobile browser, and other wallets come with built-in DApp browsers now. But these are all so niche, they’re most definitely not mainstream.

Short of Google releasing DApp support for their Chrome Browser, or Mozilla for Firefox, the problem will still exist. It doesn’t matter how fancy you make the popups (Fortmatic has some yummy rounded edges), which niche products support Web3 injection, the problem remains.

What should be done?

The users who are using Metamask and other injected Web3 providers already know how they work, they are experienced users who aren’t afraid of DApps. Focussing on making that experience more flashy or smooth or rounded is a waste of time in my opinion. It’s not going to make mainstream users flock to your platform, because you’re not solving their issue. Their issue is the understanding of what’s happening.

Instead of focussing on making the injected Web3 experience more streamlined, aim to scrap it altogether. Build a platform that allows users to interact with smart contracts without even knowing there are smart contracts or a Blockchain even there. Make that clear to investors and enthusiasts, but for the masses, remove it entirely. Think like a bank. Banks don’t show off the internal plumbing of their systems and get users to sign off every little decision, they obfuscate it so that you don’t need to worry. They handle the heavy lifting, users don’t see it.

But how can this be done? Most DApp development tutorials teach Web3.js or and how those libraries are used to interact with the injected Web3 instance in a browser. This is how most DApps are built, and is great for exposing the plumbing and getting Metamask to show those hideous popups. Like I’ve said, great for advanced users, but these libraries can also be used to hide the plumbing, not requiring Web3 support on the client-side.

Why not build a platform that doesn’t require injected Web3. Instead, allow users to signup using their email and a password, or even social logins like Twitter, Google and Facebook. Make it feel familiar to them. OK, so you might need some other skills if you’re new to development, but tried and trusted frameworks like Laravel do this stuff out of the box. No Metamask, no client-side Web3.

Once they’ve logged in and reached your dashboard, let them create an account. By this, I mean let them click a button, which creates a new Ethereum address on the backend.

“But what about private keys?” I hear you ask.

Firstly, for the mainstream user, keeping private keys in the possession of the end-user is not as much of a concern. I completely understand that holding any private keys centrally is a bad idea, goes against the whole premise of Blockchain technology and should be minimised, if not eradicated.

Secondly, I’m not suggesting that we store private keys as plain-text, or even hashed values. Both Web3.js and have encryption and decryption functions which take the key, and a password of the user’s choice to make their keys unbreakable (Scroll down to learn how to use these functions).

So storing these keys alongside their account on your platform is entirely possible. It removes the need for exposing Web3 and requiring Metamask.

Focus on Adoption

Let’s say you’re building a paid platform that has Ethereum Smart Contracts on the backend. You know your users will need to interact with them but you don’t want to require basic knowledge of Metamask and wallets before they can use it. They want to just use your product, not spend hours learning about Web3. Start by building a platform that allows registration and login via Facebook, Google and other social networks.

Build a dashboard that enables the user to create an account. Call it a “user” or something that makes it even more relatable if you’re worried that Blockchain terminology will scare them off. When they do this, ask them for a pin, or an encryption password, or just use their login password to encrypt their private key. Store that encrypted version in the database alongside their user details.

You know transacting on the Blockchain is not free, and your product isn’t free either. FIAT is still the top dog in currency-land. Make that the primary payment method with Stripe or something similar. Whatever your payment structure looks like, whether it’s a one-off fee or a subscription model, load up the user’s wallet with Ether when you receive their payment. For all they know, they’ve just paid their monthly fee to you, but you know that you’ve topped up their account so that they can start interacting with your Smart Contract ecosystem.

Any time they go to submit a transaction to your smart contracts through your platform, your platform is in control of how that message is portrayed to the user. Since their key is encrypted in the database, a request for the pin is all that’s needed to decrypt the key and submit the transaction from their account. This is common practice with traditional banking apps, and there’s no prompting the user with ugly Metamask confirmations. Controlled, and exactly how you want to present it. Make the customer feel comfortable with it, make it familiar, because that’s what they’re used to. Example

The following code sample assumes you have Python3, (which can be installed via pip), and an Infura account and URL to access the Blockchain.

Instead of exposing functionality on the front end, which inevitably requires Metamask or another Web3 wallet, let’s walk through how we can create an account, generate an encrypted version of the account with a password, then decrypt it upon user request using server-side. This functionality is also available in Web3.js as well.

Inside a python terminal, run the following commands:

# Import the library
from web3 import Web3
# Set your Infura url - obtained from the Infura dashboard
infura_url = ""
# Initialize web3 instance
web3 = Web3(Web3Provider.HTTPProvider(infura_url))
# Create an account when the user requests
# This will create a new account object with
# an address and a private key
new_account = web3.eth.account.create()
# Encrypt the account to store in your database
keystore = new_account.encrypt(user_password)

By storing this encrypted keystore, the platform does not know what the private key is. The only way to decrypt and sign transactions would be to know the userPassword value. Let’s take a look at how to do that.

# Retrieve the private key from the keystore and user password
priv_key = web3.eth.account.decrypt(keystore, userPassword)

This private key is all that’s needed to sign transactions on behalf of that address.

Read the full documentation on Python’s or Javascript’s Web3.js.

Further Reading

If you’re interested in Blockchain Development, I write tutorials, walkthroughs, hints, and tips on how to get started and build a portfolio. Check out some of these resources:

The Startup

Medium's largest active publication, followed by +771K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store