Ethereum Beginner’s Guide — Create a simple token

Image credit

Overview

Since the official Ethereum tutorial is using the GUI (Graphical User Interface) wallet, I think it would be necessary to do a tutorial using the CLI (Command Line Interface).

In this tutorial, I will demonstrate how to create your own cryptocurrency from scratch. I’ll also try to explain some confusing points from the official tutorial.

Tools & Language that I’ll use in this tutorial:

  • macOS terminal
  • Geth (go-ethereum) version 1.7.0: CLI for running Ethereum node
  • Solidity: smart contract programming language
  • Remix: browser-based Solidity compiler and IDE

Set up the development environment

Before start writing the smart contract of our own crypocurrency, let’s setup of the environment first. In this tutorial, we’ll use geth to launch the private network, and deploy the smart contract on it.

1. Open up the terminal and type the following command to launch the private network. (Make sure you have already installed geth!)

geth --rpc --rpcaddr 127.0.0.1 --rpcport 8545 --dev --datadir blockdata// blockdata: the directory for storing the blockchain data, name it whatever as you like it

2. Open another terminal, and type in the command for opening up the geth console. (Keep the old terminal for making the connection)

geth attach ipc://Users/RobinHung/blockdata/geth.ipc// use your own ipc url!
// it should be inside the directory you just created

3. In the geth console, we’re going to create a new account. (By default, there’s no account prepared for you)

// check for the accounts, [] means no account has been created
> eth.accounts
[]//create our first account. Inside the parentheses, type in the password for that account, and make sure you remember that!
> personal.newAccount('password')
"0x4bad91389a955367ac59823e10810664676e7bd2"// check for accounts again, you should see your account been listed
> eth.accounts
["0x4bad91389a955367ac59823e10810664676e7bd2"]

That’s the basic setup for the environment, and we’re going to move on to start writing the smart contract! Just keep both of the terminal open, and we’ll come back later!

The terminal for launching the private network. (First)
The terminal for Geth console. (Second)

Let’s start writing the smart contract (Solidity)!

For writing Solidity, I use Sublime Text as the text editor, and use Remix as the compiler and for generating the web3 deploy code. (If you’re using Sublime Text, make sure to install the Ethereum package with Solidity syntax highlighting)

  1. Let’s start coding with the basic functionality.

In this piece of code, I only create the VERY VERY BASIC functionality of a cryptocurrency. With the simplest coin-transferring function, it only checks if the sender have enough coin to do the transfer.

For more information about creating a more complex token, you can check out the official tutorial. Great explanations of the code are over there.

2. Use Remix — Solidity IDE to compile the code

After writing the simple Solidity smart contract, we need to compile the code first, and then we can deploy the smart contract to the network. The simplest way is to use the Remix — Solidity IDE to do the task.

In Remix, press the “+” button on the left corner to start a new Solidity file with .sol extension. Copy and paste the code in the center region. Since Remix will auto-compile the code by default, there should be no error or warning messages showed up in the right panel.

If no error message is generated, that means our code is compiled and good to go.

3. Generate the javascript file in order to deploy the contract.

The best reason for using Remix is that it will generate the web3 deploy code automatically and you can utilize it to simply load that script to the network.

On the right panel of Remix, click “Contract details(bytecode, interface etc.)”, and you can get quite a lot of information about the contract.

In the Web3 deploy field, copy all the code in that field. You can use the terminal text editor or Sublime Text to generate the new Javascript file with .js extension, and paste the code you just copied.

I’m going to show you how to use nano, the terminal text editor to generate the file and also edit the code.

  • Generate a new file called MyCoin.js, type “Control+O” (^O) to save the file.

If you mistype the file name with nano command, just use^X to exit the editor mode, and the file won’t be saved. (before you use ^O to save that file!)

nano MyCoin.js// Then you will enter a text editor mode
// The file will only be saved if you type "Control+O" (^O)
How the nano — terminal text editor looks like.
  • Paste the code which you copied from Remix. In this case, we need to modify the code to set the value of “initialSupply”. Set initialSupply = 10000.

After editing the code, type ^O to save the file, and ^X to exit the text editor mode.

4. Deploy the contract!

Remember that there’s two terminal being idle for a while, it’s time to come back to them. Actually you only need to focus on the geth console window, leave the terminal for making the connection at the corner, just need to make sure the network is connected!

Now, we need to load the script we just created to our private network. Before loading the script, you need to unlock the account.

> personal.unlockAccount(eth.accounts[0], 'password')
true// eth.accounts[0] is the account we created earlier, and 'password' is the password for that account.

Then it’s the time to load the web3 deploy script you created.

> loadScript('/Users/RobinHung/MyCoin.js')
null [object Object]
true// use your own file path!

The contract is now waiting to be mined. The contract is successfully deployed to the network until it’s being mined!

// start mining
> miner.start()
null
> null [object Object]
Contract mined! address: 0x2d29437ff1c7c90f58316ffaac697faefaf56985 transactionHash: 0x1ac0da0d8128955008c7b4dbf1d11fa12b22b4173bc263654f30a80c30d7495b// stop mining
> miner.stop()
true

Now, we need to make sure the contract is actually being deployed to the network.

The name of the contract we just deployed by the script is “browser_mycoin_sol_mycoin”. For convenience, create a better-name object representing the contract.

> var myCoin = browser_mycoin_sol_mycoin
undefined> myCoin
{
  abi: [{
      constant: false,
      inputs: [{...}, {...}],
      name: "transfer",
      outputs: [{...}],
      payable: false,
      type: "function"
  }, {
      constant: true,
      inputs: [{...}],
      name: "balance",
      outputs: [{...}],
      payable: false,
      type: "function"
  }, {
      inputs: [{...}],
      payable: false,
      type: "constructor"
  }, {
      anonymous: false,
      inputs: [{...}, {...}, {...}],
      name: "Transfer",
      type: "event"
  }],
  address: "0x2d29437ff1c7c90f58316ffaac697faefaf56985",
  transactionHash: "0x1ac0da0d8128955008c7b4dbf1d11fa12b22b4173bc263654f30a80c30d7495b",
  Transfer: function(),
  allEvents: function(),
  balance: function(),
  transfer: function()
}

Now, we know that the contract is created successfully. We can start to utilize the object “myCoin” to do some simple transactions!


Time to test the contract!

First, let’s check the balance of the account we just created. In the constructor (the function having the same name as the contract), we assign the balance to be initially 10000 when the contract is deployed.

> myCoin.balance(eth.accounts[0])
10000// we make balance[address] "public", so that we can reference it.

Now, we can try to test the transfer functionality. Before testing it, we need to create another account so that we’re able to implement the coin-transfer from one to the other account.

// create a new account -> this will be eth.accounts[1]
> personal.newAccount('password')
"0x92611eeecc5f3210b50a45d98d3481a801d5e8a2"// check the accounts list to make sure everything goes correctly
> eth.accounts
["0x4bad91389a955367ac59823e10810664676e7bd2", "0x92611eeecc5f3210b50a45d98d3481a801d5e8a2"]

Since the new account is just created recently, and we didn’t have any setting with the new accounts (any account except the coinbase account), the balance of new accounts should be zero.

> myCoin.balance(eth.accounts[1])
0

It’s time to test the coin-transfer functionality.

> myCoin.transfer.sendTransaction(eth.accounts[1], 500, {from: eth.accounts[0]})
Error: authentication needed: password or unlock
.
.
.

When doing any coin transfer, you will be required to unlock the account of the sender first because this transaction will consume the Gas.

// check the amount of gas
> eth.getBalance(eth.accounts[0])
65000000000000000000> personal.unlockAccount(eth.accounts[0], 'password')
true// coin transfer
> myCoin.transfer.sendTransaction(eth.accounts[1], 500, {from: eth.accounts[0]})
"0x8a8a52f3ec847f73a636a6a2ce0c95dc3d823c2f481e384c4fbd095ca00aeb3b"> miner.start()
null
> miner.stop()
true> myCoin.balance(eth.accounts[0])
9500
> myCoin.balance(eth.accounts[1])
500// transfer the coin again
> myCoin.transfer.sendTransaction(eth.accounts[1], 250, {from: eth.accounts[0]})
"0x70cd164f76be35b6aeb57df4736e3397d273b50efb901eb71547629a66580d1b"// Even though the transfer function is sent to the network, it will only be valid after being mined! -> balances are NOT changing!
> myCoin.balance(eth.accounts[0])
9500
> myCoin.balance(eth.accounts[1])
500> miner.start()
null
> miner.stop()
true// balances of the account are changed finally!
> myCoin.balance(eth.accounts[0])
9250
> myCoin.balance(eth.accounts[1])
750

The transfer command is “myCoin.transfer.sendTransaction(eth.accounts[1], 500, {from: eth.accounts[0]})”, sendTransaction() is the Web3 Javascript API function, we need to call it in our transfer function.

Because transferring the coin is going to change the blockchain state, the transaction would need to be picked up by the miner on the network to let this transaction be valid. We need to add the mining process (miner.start()) to make this transaction valid.


Now, you have a basic token with the transfer functionality!

Hope this tutorial helps you get a basic understanding of the Ethereum, smart contract, and also the CLI development. Although the Command Line Interface might seems quite intimidating at first, through more and more practical experiences you’ll figure out that it’s a really handy and useful way to do the development tasks.

This is my first try writing an article and also a tutorial about Ethereum. I’m also on the road of learning it, so if there’s any flaw in this article, please leave the comment and point them out! If you have some suggestions or you are confused with some part of this tutorial, share your ideas and we can try to make this tutorial better!

Thanks for reading :)

Robin Hung

Taipei Ethereum Meetup

台北以太坊社群專欄