Let’s get started with Ethereum from scratch — set up, write and deploy a simple smart contract using Truffle

An article that will go over EVERYTHING — installations, code editors, compiling and deploying smart contracts, and admiring what you did for the popular development blockchain network — Ethereum! A one-stop end to end guide for beginners.

Vishakha Lall
6 min readJul 20, 2019

The intent

Okay, I started maintaining this article when I was a few days into developing distributed apps on blockchain networks and had spent quite some time scratching my head solving errors. I needed a document I could rely on. Perhaps you can too!

I’ll try to be comprehensive so you could replicate all the setup to begin the actual development. The goal of this article is not to explain Ethereum networks, smart contracts and their underlying magic(maybe once I completely understand, I would write a short article about that too), but to understand how to really implement them without giving up.

As a note, my system configurations at the time of this article are Linux 16.04 over Windows Linux Subsystem.

First things first

  • I wouldn’t want to assume that you already have a code editor (which you probably do and should jump over to the next point). Visual Studio Code and Atom are great options. Personally, I like Atom.
  • A great idea is to have syntax highlighting for Solidity installed in your code editor. Here are the steps for Atom:
File -> Settings -> Install -> Search for ‘language-solidity’ -> Install
  • Next, we need to install Node.js. We’ll install the latest version of Node.
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.5/install.sh | bash
source ~/.profile
source ~/.bashrc
nvm --version #my nvm version 0.34.0
nvm install stable

Here I’m not using the standard apt-get method to install Node.js. Nvm tool gives us the ability to install and use multiple version of node, and prevent the (bad) usage of sudo for running node application. Trust me, I just saved you hours of debugging install errors. Thank me later.

  • Check the versions of Node and npm to validate the installation.
node -v #my node version v12.6.0
npm -v #my npm version 6.9.0
  • Install truffle and ganache-cli
npm install -g truffle
npm install -g ganache-cli
  • A quick look at my versions:
Truffle v5.0.28 (core: 5.0.28)
Solidity v0.5.0 (solc-js)
Node v12.6.0
Web3.js v1.0.0-beta.37
Ganache CLI v6.5.0 (ganache-core: 2.6.0)

You can check the versions using:

truffle version
ganache-cli --version

A simple contract deployment to a local test network

Let’s deploy the popular HelloWorld smart contract and ascertain our setup is good to go.

  • Start the test network
ganache-cli

The default port on which ganache-cli starts is 8545. It will show a list of available accounts and private keys. Let it run.

  • Create a new directory and initialise truffle
mkdir hello-world
cd hello-world
truffle init
  • Create a new contract
truffle create contract HelloWorld
  • Write the following code in contracts/HelloWorld.sol
pragma solidity ^0.5.0;contract HelloWorld {
address private creator;
address private lastCaller;
string private message;
uint private totalGas;

constructor() public {
creator = tx.origin;
totalGas = tx.gasprice;
message = ‘hello world’;
}
function getMessage() public view returns(string memory){
return message;
}
function getLastCaller() public view returns(address){
return lastCaller;
}
function getCreator() public view returns(address){
return creator;
}
function getTotalGas() public view returns(uint){
return totalGas;
}

function setMessage(string memory newMessage) public{
message = newMessage;
lastCaller = tx.origin;
totalGas += tx.gasprice;
}
}
  • Create a new migration
truffle create migration deploy_hello_world
  • Write the following code in migrations/<migration_name.js>
const HelloWorld = artifacts.require(‘HelloWorld’)module.exports = function(deployer) {
deployer.deploy(HelloWorld)
}
  • Compile and deploy the contract
truffle migrate — reset

If all goes well, you should see something like this:

Compiling your contracts…
===========================
> Everything is up to date, there is nothing to compile.
Starting migrations…
======================
> Network name: ‘development’
> Network id: 1563629256080
> Block gas limit: 0x6691b7
1_initial_migration.js
======================
Deploying ‘Migrations’
— — — — — — — — — — —
> transaction hash: 0xa6a1dcbc517186b66d7ac5275e92d6dd004d795079abbfd884e8b4595b92c744
> Blocks: 0 Seconds: 0
> contract address: 0x09D6F2C4f0aa40d3C68B998e3f96c430f81b6456
> block number: 1
> block timestamp: 1563629275
> account: 0xECAA5B0d76eD145093F3fC1479a3e56fC2Ed55DD
> balance: 99.99477214
> gas used: 261393
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00522786 ETH
> Saving migration to chain.
> Saving artifacts
— — — — — — — — — — — — — — — — — — -
> Total cost: 0.00522786 ETH
1563624951_deploy_hello_world.js
================================
Deploying ‘HelloWorld’
— — — — — — — — — — —
> transaction hash: 0x6bfaf7448627d709d8cb89b54f80a5f9f860ef52e62d56ce24752e26b46f93fd
> Blocks: 0 Seconds: 0
> contract address: 0x43aF94f287B2B7f4406ab85f0e455CbEF1782559
> block number: 3
> block timestamp: 1563629276
> account: 0xECAA5B0d76eD145093F3fC1479a3e56fC2Ed55DD
> balance: 99.98506912
> gas used: 443128
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00886256 ETH
> Saving migration to chain.
> Saving artifacts
— — — — — — — — — — — — — — — — — — -
> Total cost: 0.00886256 ETH
Summary
=======
> Total deployments: 2
> Final cost: 0.01409042 ETH
  • Test the deployment
truffle consoleinstance = HelloWorld.deployed()

This returns the details of the deployed contract, it’s abi, bytecode, functions etc.

Let us call the getMessage function now.

HelloWorld.deployed().then(function (instance){return instance.getMessage()})

Voila!

Connecting to a private Ethereum network not running on LocalHost

Most of you would not find this useful but if you’re trying to connect to a private Ethereum network (possibly in your organization) and cursing your life, gear up! Here’s what you need to do.

Truffle creates a truffle-config file in the root directory where you installed truffle. It has all the configuration properties which are commented by default.

vi truffle-config

Uncomment the development network in networks and add your details as follows

development: {
host:”<machine name or ip>”,
port: <the port on which geth is running on the machine>,
from: “<0x+the default account address to use for transactions>”,
network_id: “<find network id of your network, steps below>”,
gas: <set high gas limit like 2000000>
}

Here’s how you can check the network_id of your network, start the Geth JavaScript console in your host machine and run

admin.nodeInfo

The network_id is displayed under

protocols > eth > network

The official Truffle documentation is helpful to check out the configuration parameters.

Troubleshooting

Well, you’re obviously reading this because something messed up. Don’t worry, you’re not alone. First off try to understand the error message. There could be three categories of error you encounter:

  1. Compilation error: Your Solidity code did not compile cleanly. It usually gives a meaningful error. Different versions of Solidity compilers have different syntaxes and keywords. Read the first line of code in your contract (.sol file). If you used the same code as me, try checking your Truffle and solcjs (it is instaled with truffle) version. Fix compilation errors and make sure you delete the build folder before you compile and deploy again.
  2. Deployment error: Check the network configurations (Address and port) in truffle-config.js file. Make sure your network is running. Check if Migration.sol is compiled and deployed too.
  3. Saving to network error: Validate that ganache-cli is updated to the latest version (not test-rpc).

Now, if you’re still stuck, alas you would have to Google your errors, but here’s the catch. All the npm modules and Solidity are in their baby development stages and go through a lot of frequent changes. Make sure you are reading an answer/approach that is latest and relevant to the version that you are using. Official documentations are most reliable.

Make sure you comment any errors that you found(and how you conquered it) here so we make a strong sustainable community of beginners.

What’s next?

In my next article, I will explore transactions and developing distributed applications. I will keep you guys updated.

--

--

Vishakha Lall

I have short periods of hyper excitement when I publish my thoughts (mostly for me to come back to them later in life).