Let’s Make a Coin

An ELI-5 introduction to blockchains and smart contracts

It is going to be the best, let’s call itTHE coin.

On a piece of paper, we’ll write down who owns how many of them. If I give you 5 of them, then we’ll remove 5 from my count and add 5 to yours.

But what if it rains and the paper gets all wet and smudgy and we lose count of who owns how many coins?

Let’s store it on the cloud instead. A cloud is just a bunch of computers, somewhere. They’re all over the place, so it’s fine if one of them gets rained on for a while. They talk to each other, so if we write on one of them then it’ll tell the others.

 

With the cloud, the guy who pays for the computers gets to decide what the computers do. Fair enough, but our coin is going to become very valuable, and we don’t trust them to not change the number of coins that we have.

Surprisingly, there is a solution.Blockchains.

A blockchain is a cloud that no one owns. Anyone can write to it, by paying a fee. We all can see who wrote what, and when. And we can only overwrite what we wrote: I can’t modify your data, and you can’t mine.

For us, in one way, nothing much changes: instead of paying for the computers, we pay for the ability to write on the blockchain. But in another way, everything changes: we are now guaranteed that none of us can cheat.

Tasks

»

Write a program that remembers who owns how many coins

»

Deploy this program on the blockchain

The computer programs that run on the blockchain are called smart contracts. But there is nothing particularly smart about them, they are as smart or dumb as any other computer program. They are just regular programs, they just happen to run on the blockchain.

Since they’re regular programs, we can write them in any programming language. A compiler can translate the same program to make it run on the blockchain that we want to run them on. Like how you can write a program once and it can run (with some modifications) on Linux or macOS.

Let’s write our program in Solidity. It is a popular language for writing blockchain programs. It looks like JavaScript.

We also need to pick the blockchain on which we will run our program. Not surprisingly, there are many blockchains (it’s quite easy to create one). Let’s start with Ethereum, a fairly popular one.

Tasks

»

Write a Solidity program that remembers who owns how many coins

»

Deploy this program on the Ethereum blockchain

We’re are far from the first ones trying to do this, people have been creating coins on the blockchain for a while now. We can look at their programs and do something similar, or just copy paste one of the existing programs and tweak it for our coin.

It gets easier. People have already created open-source libraries for doing these common things like creating coins. So we can just import the program from the library, no need to even copy paste.

In fact, one would imagine that it is such a common requirement, creating coins, that people might have already created standards for how such programs should behave, so that it is easy for these programs to talk to each other.

And indeed they have. On Ethereum, the blockchain that we’ll be using, it is the ERC20 standard.

So we need to find a library that has a program that implements the ERC20 standard. OpenZeppelin is one such library. Let’s start writing our program by importing it.

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

Don’t worry if you fully understand the code - we’ll write just a few lines, and the details don’t even matter. The nice folks at OpenZeppelin have even built a nice UI wizard that you can generate these programs for you, and there is a link to it at the end.

What that import line does is that it goes to a library named @openzeppelin/contracts and borrows a program named ERC20.sol from the token/ERC20 folder.

If you’re a developer, then you can imagine the easiest way to model a coin would be a hash map from addresses to coins. The library that we imported just that: There are a few lines of code in it to conform to various interface requirements, but the essential data structure is mapping(address => uint256) private _balances. The security, the thread safety, the scalability, the fault tolerance, the redundancy, all these and more come implicitly from the blockchain’s execution environment.

The library will give us a generic, nameless, white-labeled coin. Let’s put our sticker on top of it.

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract OurCoin is ERC20 {
    constructor() ERC20("The Coin", "THE") {}
}

Again, the details don’t matter, but let’s see if we can follow what that code is saying:

  • OurCoin is a contract (a program that runs on the blockchain).
  • Specifically, it is an ERC20 contract. i.e., it follows the ERC20 standard.
  • The ERC20 standard is defined in the library we imported.

The library also provided a working implementation of ERC20. However, to be fully functional, we need to tell it two things:

  1. The name of our coin.
  2. A ticker symbol, which is like a nickname for our coin.

We can write anything we want here. We can call it BTC if we want, there is nothing stopping us. There is no central authority that defines who gets what symbol, and there is no concept of copyright. The king is the one who people crown.

This is where blockchains go beyond technology and into human behaviour. What gives Mona Lisa value? Where does it gain its legitimacy?.

Another interesting piece of that code is the constructor(). This allows us to write some code that is run only when the program is executed for the first time (constructed).

How convenient, cause that gives us the perfect place to create our coins.

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract OurCoin is ERC20 {
    constructor() ERC20("The Coin", "THE") {
        _mint(msg.sender, 121 * 10 ** decimals());
    }
}

When the program is run for the first time (or, in blockspeak, when the contract is deployed), the constructor would run. Inside it, we call the _mint function. The _mint function creates new coins. In our case, it will create 121 new coins, and give them to the person who deployed the contract (msg.sender). We multiply 121 by 10 ** decimals() to scale it up properly, so that each of the 121 coins is divisible into decimals() cents.

That’s it!

There are a details that need to be taken care of

  • keeping a mapping of who owns how many coins
  • allowing people to give their coins to others
  • allowing exchanges to trade coins on someone’s behalf
  • emitting events when interesting things happen

but the library internally does that for us. There are many possible ways we could’ve decided on the total supply of the coin (e.g., create new coins once a month), but we went with the simplest way – create a fixed number of coins when the program starts its life on the blockchain, and give them all to the person who deployed the program.

Tasks

»

Write a Solidity program that remembers who owns how many coins

»

Deploy this program on the Ethereum blockchain

Now that we have the program, let’s deploy it.

Remember, the blockchain is not one person, or one computer, or one company. It is just a bunch of computers talking to each other. It’s more cloud than the so called cloud.

With the cloud, while the computers that make up the cloud are spread all over the place, they are still owned and operated by a single company. Amazon runs the AWS cloud, Microsoft runs the Azure cloud. To deploy our program on a cloud, we would give our program to this company, and then they would spread it out over all the computers that they manage.

With the blockchain, none of that. There is no owner, no manager, no one in charge. As fantastic as it sounds, it is true. It is just a bunch of computers talking to each other.

This is what people mean when they say that blockchains are decentralized.

To deploy our program, we can just join in the bunch. We don’t have to ask permissions from anyone, nor do we have to register anywhere.

This is what people mean when they say that blockchains are permissionless.

We just find the address of one of the existing computers that are participating in the blockchain, and ask our computer to talk to it. These addresses are easy to find, and most blockchains also have special bootstrap computers that have well known addresses so that newcomers always have someone to connect to.

The blockchain computers (they’re called nodes) gossip all the time, it’s like computer Twitter. Once we are talking to any one of them then it’ll tell us the addresses of the other ones too, and soon our computer will be talking to all of them. This way of making computers talk to each other without a central authority is not new: blockchains learnt this from BitTorrent.

It sounds like a lot of work, but in practice the software for blockchain nodes that we can install on our computers will do all of it automatically for us. That said, it is still a bit of a bother: our computer might just be our mobile phone, and we don’t want this stuff eating our battery and internet by continuously talking to all the other nodes.

Wouldn’t it be nice if someone were to run a node for us, and we (our computer, or our mobile phone) can just talk to the node?

Indeed, that is possible. Companies provide nodes-as-a-service, which allows us to get our foot in the blockchain without dealing with the whole lot of it. When we want to talk to “the blockchain”, we just tell what we want to say to our node, and it relays that to the rest of the nodes on the blockchain. And if there is something that our node hears that is relevant for us, it lets us know without us needing to listen all the time.

And they’re free! These services make money by providing commercial offerings, but many of them also provide free access for casual users.

So instead of installing full nodes, we can install lightweight wallets that automatically connect to such node services. In addition, wallets also create and manage our keys.

A key is a (really) long randomly generated number. They’re generated in pairs: a public number and a private number. The process of generating them is such that they act as two parts of a jigsaw puzzle that fit into each other.

  • The public number acts as an identity, as an address.
  • The private number can sign a message to guarantee that it comes from the public number.

The public number (aka, the public key) is like your Twitter username. And the private number (aka, the private key) is like your password, ensuring that only you can log into the account and send messages.

The difference is that in the case of Twitter username/password, there is a central authority (Twitter) that checks that the username and password match. Who does that check for wallet keys? Mathematics.

Enough conversation, let’s install a wallet. MetaMask is a popular one, let’s download it from metamask.io. It works on both mobile and desktops.

The first time we run it, MetaMask will generate the keys for us. The public key will become our account address. The private key will be secret and it will be shown to in the form of 24 words.

Anyone who sends a message to the blockchain has to pay some fees: this provides the incentive for nodes to process our message. On the Ethereum blockchain fees are paid in the form of Ether (nicknamed ETH). So we need to get our hands on some Ether.

We can buy Ether at various places. However, there is an alternative while we’re experimenting – instead of using the real Ethereum blockchain (called the Mainnet), we can use one of the playground blockchains (called Testnets). We can get testnet Ether for free by using faucets. Then when we’re done experimenting we can just buy real Ether and deploy on mainnet.

Let’s tell MetaMask to connect to one of the testnets instead of mainnet. We can do this in MetaMask settings by selecting “Ropsten Testnet”.

Ethereum has a bunch of testnets, named after metro stations in Stockholm. Let’s use Ropsten because it has an easy to use faucet.

MetaMask settings after switching to the Ropsten Testnet

Then let us copy our account address in MetaMask, go to the Ropsten faucet at faucet.ropsten.be, paste our address there and get some Ether.

Tasks

»

Write a Solidity program that remembers who owns how many coins

»

Deploy this program on the Ethereum blockchain

»

Connect to the Ethereum blockchain

»

Create an account (public-private key-pair)

»

Add some Ether to our account

Good, so with MetaMask we have (a) a way to talk to the nodes on the blockchain, and (b) our keys. And we got some (c) Ether to pay for sending messages. So now we can use MetaMask to broadcast a signed copy of our coin program to the blockchain.

There is one last thing we need to do. The way we’ve written our program, in a programming language, is a nice intermediate representation that both humans and computers can understand. But space and computation on the blockchain is at a premium. So it would be better to use a shorter representation that is easier for computers to store and execute.

We can do this by compiling our program. This translates the program into a short representation that we can then put in an envelope, sign it, and broadcast on the blockchain. Nodes can get the envelope, check the signature, take the fees, and then directly save the short representation on the blockchain.

This saved program on the blockchain gets its own address, called the contract address. Then later if someone wants to execute the program (say they want to send some of their coins to their friend Stinky), they can send a message to the blockchain asking the nodes to execute the program saved at that contract address. Nodes take the fees, check their signature, execute the contract, Stinky gets the coins, and everyone is happy.

To compile our program, let’s head over to remix.ethereum.org. Remix is a way to write, compile and deploy blockchain programs in our browser itself, without needing to install anything else.

Select the contracts folder, and press the “Create New File” button above it. This will create a new file in the contracts folder. Name it OurCoin.sol (the name doesn’t matter). Let the the other files be as they are for now – we don’t need them but they won’t hurt us either.

Create a new file in Remix

Copy our program and paste it into the new file we just created.

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract OurCoin is ERC20 {
    constructor() ERC20("The Coin", "THE") {
        _mint(msg.sender, 121 * 10 ** decimals());
    }
}

Right click on OurCoin.sol in the file list, and select “Compile”.

Compile our file in Remix

Remix will give us some warnings, but like professional software engineers, we can ignore them for now.

Tasks

»

Write a Solidity program that remembers who owns how many coins

»

Deploy this program on the Ethereum blockchain

»

Connect to the Ethereum blockchain

»

Create an account (public-private key-pair)

»

Add some Ether to our account

»

Compile our program

We now have all the bits we need to deploy. The easiest way to do this is to connect MetaMask to Remix. Remix has the compiled program. MetaMask has the keys and the connection to the blockchain, and the Ether to pay for the fees.

In Remix, switch to the “Deploy & run transactions” panel by clicking on the third icon in the left sidebar.

Switch to the deploy panel in Remix

Open the “Environment” dropdown, and select “Injected Web3” option.

With Web3, our wallet is our identity. We can pay for things, and prove our identity(-ies), as many as we want, without needing to create accounts with third party services.

Right now it is a bit clumsy to use, but expect browsers to add in-built support for wallets soon.

Select the Injected Web3 environment in the Remix deploy panel

When we do that, MetaMask will ask us if we want to connect our account to Remix. Allow it to connect.

In the “Contract” dropdown, select our contract (OurCoin.sol).

Select our contract in the Remix deploy panel

We’re all set! Press deploy.

Press the deploy buttonin the Remix deploy panel

MetaMask will ask us if we want to authorize this transaction. Press confirm.

Within a few seconds the transaction will get processed and our program will be live on the blockchain. We can see it on a online blockchain explorer like Etherscan. Copy the address of the deployed contract from Remix and then paste it into Etherscan - it should look something like this.

Remember that this a real coin. The only toy aspect of it is that we deployed it on a testnet instead of the actual Ethereum blockchain to avoid the hassle of getting and paying real ETH. But otherwise it as real as it gets. For example, we can buy it and sell it - thisis an example trade on Uniswap.

Uniswap itself is a smart contract that acts as a purely automated exchange. Anyone can list their coins, anyone can buy them, anyone can sell them. None of the parties involved need to know each other, or trust each other. We’re well on on our way to achieve Satoshi’s vision – “What is needed is an electronic payment system based on cryptographic proof instead of trust.” – and it is going to extend beyond, much beyond, just electronic payments.

If this lights a spark of interest, then I would suggest heading next to proper tutorials. Ethereum’s website is a good start. There are many tutorials on YouTube too.

Here is the link to the OpenZeppelin Contracts Wizard.

ETH’s go!