Smart Contract Development, Simplified, End-to-end Example

William Mendes
10 min readFeb 16, 2018

--

Introduction to Smart Contract Development that breezes through the tools, smart contract code and automated testing for smart contracts.

Working with the LeanLaunch.Network team provided me an opportunity to go deep and understand the blockchain from inside out: from creating a token to releasing a crowdfunding smart contract.

Although much is spoke about blockchain nowadays, learning its technicals was and nuances has been indeed a rocky road.

My goal in this article is to make you take you through an end-to-end smart contract creation process, providing you with introductory information and examples of each one fo them.

Are you ready? Let’s start!

What you will do here?

In this tutorial, I will take you through the following:

  1. Understand the concept of Smart Contract

2. Setup your personal, local, ethereum blockchain

3. Create a smart contract

4. And finally, test executing functions from your smart contract.

We used this setup to write unit-tests (using tuffle) and create our continuous integration system for the smart contract.

Continuous Delivery of Smart Contracts?

It is impossible to do continuous delivery with smart contract, because they are immutable in the blockchain, but you can keep them tested.

1) Understand “Smart Contracts”

Smart contracts are, in a way, like classes in a object-oriented programming. Once these smart contract are deployed in the Ethereum blockchain, it’s possible to call it’s “objects” or “functions”.

Having that said, we will basically need a smart-contract that will do what we request it to and a blockchain to deploy it in.

Once the smart-contract is in the blockchain, anyone can call this contract and it’s functions. Let’s start our example to clarify things.

Wanna know more about concepts? Read our Blockchain Glossary.

2) Setup: What you will need?

  1. Node.JS, that’s the framework
  2. Geth, to create our local blockchain node
  3. Ganache, to allow us managing our blockchain via RPC
  4. Truffle, compiler & unit-test framework for our smart contract.
  5. OpenZeppelin, helpers library for smart contract development

2.1) Node.JS, that’s the framework

We will need Node.JS installed so we can easily install npm packages.

2.2) Geth, to create our local blockchain node

Geth is basically a CLI (Command Line Interface), implemented in GO, that allows you to run a ethereum node on your computer.

Follow installs steps according to your OS. In Linux run the commands:

$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install ethereum

2.3) Ganache, to allow us managing our test blockchain via RPC

In order to test our smart contract, we will need a local, personal, blockchain, into which we can create and test it.

For the purpose of this tutorial we will be using Ganache. It calls it self as One-Click-Blockchain, and it definitely does the job. You can easily setup Ganache and getting it running with one command:

$ npm install -g ganache-cli

Once you have it installed, run the command to start it and leave it running background, we will come back to it later.

$ ganache-cli — defaultBalanceEther=10000

This will start our node, automatically create and display 10 accounts, and it’s private keys, the security words sequence and will keep it running and listening on port 8545 of your localhost, and what will be very hand, each account has 10k Ethers in it’s balance. The default is 100 Ethers, few free to setup any amount here.

You can start the same service provider, using geth. Geth allows you to easily connect with the non private network with Rinkeby (we will see more of this later in the Deployment Section), but if you want to give it a try:

$ geth — rpc — rinkeby — rpcapi=”db,eth,net,web3,personal,web3"

2.4) Truffle, compiler & unit-test framework for our smart contract

Ok, so now we have a blockchain in test mode.

We will start our test and development environment. Truffle helps us to do this job. Running it’s initialiser will create the structure and migrations you will need

$ truffle init

Notice that this will create a folder structure for us. And we will place our smart contracts in the “/contracts” folder.

Important: “truffle version” will give you the version of the solidity compiler (solc) that you must use in the pragma declaration, down below in your SmartContract file. It should be some thing like:

truffle version
Truffle v4.1.3 (core: 4.1.3)
Solidity v0.4.19 (solc-js)

Truffle now allows you to compile your contracts as well as run tests written in Solidity or in Javascript.

2.5) OpenZeppelin, helpers library for smart contract development

Nobody likes reinventing the well. And thanks to open-zeppelin, we don’t need to do so on smart contracts.

It is a library to help you to start developing smart-contracts for the Ethereum blockchain.

Several of its helpers are must-have and used everywhere, also securing you from most common mistakes in smart contract development, so it’s greatly recommended.

Run the command bellow to install it in your project folder:

$ npm install -E zeppelin-solidity

You will notice a few import in the code further ahead, and it makes use of the package installed by npm in your project.

3) Contract Creation and Deployment, Step-by-Step

Ok, now that we have our environment setup, we can finally start the development of the smart contract itself. In a nutshell, the process is:

  1. Token Smart-Contract
  2. Crowdsale Smart-Contract
  3. Metamask
  4. Deploy
  5. Mist Ethereum Wallet

3.1) Token Smart Contract

The OpenZeppelin, provides a couple of examples, such as a token contract and a crowdsale contract. You will find few examples at “example/node_modules/zeppelin-solidity/contracts”

Hint on project structure, for what it seems to be the most common over the web:
- /contracts
- /lib
* File extensions: .sol
Visual Studio Code offers a good extension to play with it.

Our simple token contract will look like this:

pragma solidity ^0.4.19;import "zeppelin-solidity/contracts/token/ERC20/MintableToken.sol";/**
* @title SampleCrowdsaleToken
* @dev Very simple ERC20 Token that can be minted.
* It is meant to be used in a crowdsale contract.
*/
contract SimpleCrowdsaleToken is MintableToken {
string public constant name = "Sample Crowdsale Token";
string public constant symbol = "SCT";
uint8 public constant decimals = 18;
}

Token contracts must have this three properties, such as name, symbol and decimals.

MintableToken, means that numbers of tokens will auto-increase accordingly to the investments as it arrives. The term “mint” is related to the money-printing industry, where the money that has been minted has been made official.

Decimals are how many divisions (in small parts) your crypto currency will be possibly divided. They are commonly 18 decimals. Something to bear in mind while developing your contract is the scale of decimals valid for the ETHER, for example:

1 ETHER is equals to:
1000000000000000000 Wei
1000000000000000 Kwei, Ada, Femtoether
1000000000000 Mwei, Babbage, Picoether
1000000000 Gwei, Shannon, Nanoether, Nano
1000000 Szabo, Microether,Micro
1000 Finney, Milliether,Milli
0.001 Kether, Grand,Einstein
0.000001 Mether
0.000000001 Gether
0.000000000001 Tether

3.2) Crowdsale Smart Contract

A crowdsale contract is nonetheless how you will threat the Ethers that will arrive. The contract has some particularities, to understand it, here is a few keywords to help you get going:

  1. msg.sender — it is who is calling, which wallet address or contract address is calling the function/contract. All functions in a smart contract has a msg.sender.
  2. msg.value — it is the amount of ether that has been sent to the contract.
  3. payable — is a function modifier, it makes the function accepts the Ether sent to it. More about function modifiers can be found at SolidityDocs.
  4. event — a event is used to create a log in the transaction, once the event is called, a log will be set to the transaction (a transaction can has none or n logs)

OpenZeppeling provides also a crowdsale contract:

This is an example of a fully fledged crowdsale.
The way to add new features to a base crowdsale is by multiple inheritance.
In this example we are providing following extensions:
CappedCrowdsale — sets a max boundary for raised funds
RefundableCrowdsale — set a min goal to be reached and returns funds if it’s not met
After adding multiple features it’s good practice to run integration tests
to ensure that subcontracts works together as intended.

pragma solidity ^0.4.19;import "zeppelin-solidity/contracts/token/ERC20/MintableToken.sol";
import "zeppelin-solidity/contracts/crowdsale/validation/CappedCrowdsale.sol";
import "zeppelin-solidity/contracts/crowdsale/distribution/RefundableCrowdsale.sol";
import "./SimpleCrowdsaleToken.sol";
contract SampleCrowdsaleContract is CappedCrowdsale, RefundableCrowdsale {function SampleCrowdsaleContract(uint256 _rate, address _wallet, uint256 _cap, uint256 _goal) public

CappedCrowdsale(_cap)
FinalizableCrowdsale()RefundableCrowdsale(_goal)Crowdsale(_rate, _wallet, createTokenContract()) {
require(_goal <= _cap);
}
function createTokenContract() internal returns (MintableToken) {
return new SimpleCrowdsaleToken();
}

}

Now you can create your settings, write your tests and run it with truffle.

Tests can be written in the javascript way, all you need is to create a instance of the contract you are willing to test.

Example “test/crowdsale.js”

contract('Crowdsale', accounts => {
before(async () => {
ico = await SimpleCrowdsaleContract.new()
})
it("should investment of 1 ETH receives 4500 SCT ", async () => {
await ico.sendTransaction(
{ value: web3.toWei(1, "ether") }
)
assert.equal(
web3.eth.getBalance(ico.address).toNumber(),
web3.toWei(1, "ether")
)
})
});

Example “test/token.js”

contract('Token', accounts => {
before(async () => {
token = await SimpleCrowdsaleToken.new()
})
it("Should token name be SampleCrowdsaleToken", async () => {
let actual = await token.name.call()
assert.equal(actual, "SampleCrowdsaleToken")
})
});

Run tests with :

$ truffle test

3.3) Metamask

A great javascript injection tool to help you submit, accept, reject transactions. It’s largely used in the main chain to approve transactions, and it’s very easy and handy to switch between networks.

Metamask allows you to run Ethereum dApps right in your browser without running a full Ethereum node.

Why do we need it? To deploy the contract on the network (test or main network) we will need an sender, to send the contract and fix it in the blockchain, creating the transaction.

For our test, we will be using Rinkeby. It’s is a blockchain that runs exactly like the Main Ethereum Network, it’s mined, it’s shared, and anyone can use it.

It’s provided the same EtherScan as the main network.

To send a transaction we will need Gas.

Gas is the internal pricing for running a transaction or contract in Ethereum

ok, and how do we get Ether in a test network?

Rinkeby created a platform where you can request Ether for free and assign it to your wallet: https://faucet.rinkeby.io/

  1. In Metamask create a account/wallet in the Rinkeby Network
  2. Copy the address of your wallet and post it according to the instructions on the rinkeby.io. You can choose to receive 3/7.5/18.75 Ethers, that will be transferred to your account in the test network.
  3. Wait it to be mined and you should see it in your Metamask wallet

3.4) Deploy your contract

To deploy your contract, you will need a to compile and send it to the blockchain. One way of doing it, it to use Ethereum Remix.

You can even use Remix IDE to develop your contract. It has the compiler, transaction debugger and what we going to use now, the deployment tool.

Environment — It reads the Rinkeby set in Metamask.

Account — It also reads from the account selected in Metamask.

SelectBox — Select the main contract that you want to deploy, in our case: SampleCrowdSale.

TextBox — Next to the create button, fill in the params set in the contract constructor.

That’s it. Once you create your contract, Metamask will ask for confirmation and your contract will be deployed. And as soon as it has been mined, you can share the contract address, and people can transfer Ether to the project and in return you will transfer them tokens. Etherscan also reads Rinkeby network, where you can visualize all transactions happening real-time.

Here’s how your contract will look like, either in Rinkeby Testnet or in the Main Chain

3.5) Mist Ethereum Wallet

Now that we have our token and our crowdsale contract deployed in the Rinkeby Test blockchain, let’s pretend you are an investor from the other side of the world, and you believe in it’s projects future.

Download the Mist Ethereum Wallet at their page on GitHub.

MistWallet also allows your to connect to the main network as well as to Rinkeby network. Have it installed, you will need some Ether to play with. You can either request from Rinkeby or send from the previously created account in Metamask wallet.

An Example of a couple of accounts created, on Rinkeby, to start testing your contract manually

Now that you have your accounts created, you can transfer from an account to your contract address, and the contract flow should work according to the rules you’ve set.

4) What else is good to know?

When you buy a ERC-20 Token you need to tell your wallet it’s configuration, so your wallet can locate and display the token your address has obtained.

On the tab Contracts of your Mist Wallet, you can start watching the token you have created.

  1. Click on “Watch Token”
  2. Type the token address that we had previously deployed
  3. If it doesn’t load automatically add:
    - Name
    - Symbol
    - Decimals

As soon as you click OK, it will show how many tokens you’ve got in your wallet.

What can you do now?

Now you have:
A) your token,
B) your contract that interacts with the blockchain receiving Ether and sending the tokens you’ve created.

You are ready to be funded by those who believe in your project and believe in YOU!

--

--