Writing your first Ethereum Smart Contract and Dapp with Solidity

Narek Hovsepyan
5 min readFeb 7, 2018

In my second post about blockchain related development, we are starting to exploring the world of Ethereum and Solidity. If you are not familiar with Ethereum, or you don’t know what is smart contract, I am recommending to skim this article from Ethereum team. In this tutorial I will assume you already know about what is blockchain, and what is smart contract in general.

In this article we will create a first smart contract, using Solidity deploy to a test virtual network, running locally, using ganache-cli, and itneract with it from javascript using web3.js. Although there are fremeworks like truffle or embark, we will do everything from scratch, to have better understanding of what’s going on under the hood. For frontend we will use jQuery, to focus on Ethereum, not on single page application development. Also we will skip private/public keys authentication and deployment on a real blockchain. This will be my next tutorials.

Decentralised Public MessageBoard

We are going to build a public MessageBoard application, where everyone can post a new message. This is simplest application we can build. In this tutorial there will not be a paying transaction involved.

Enter Ganache

Ganache is a tool which simulates virtual, in memory blockchain, in order to develop and test our smart contracts. To install just run:

npm install -g ganache-cli

Then let’s run ganache with default configuration

ganache-cli

This will simulate a blockchain, with 10 test accounts, each loaded 100 fake ethers. Usually it will run on localhost:8545

Output of ganache-cli command

Writing our first contract

For better understanding the smart contract development, think like contract is a class in terms of OOP. Now let’s model our application. We will need a contract Chat, which will contain list of users with nicknames, as well as the messages, methods for adding messages and a struct Message, which will contain the text and the user’s nickname+address.

Bellow is the code of our smart contract

Compile, Deploy, Call

Now we are ready to compile and deploy, then make calls to our smart contract. Let’s install dependencies.

npm install --save solc
npm install --save web3@1.0.0-beta.29

Now let’s setup web3 inside node REPL

> Web3 = require('web3')
> web3 = new Web3(new Web3.providers.WebsocketProvider("ws://localhost:8545"));

Now we have web3 instance ready to use. As we are building a chat application, which will be subscribed to events sent from smart contract, we will use WebSocket provider. If you will only call/send data to smart contract, you can use Web3.providers.HttpProvider.

Let’s compile the contract and deploy to our blockchain

> var solc = require('solc')
> var fs = require('fs')
> var code = fs.readFileSync('messageboard.sol').toString()
> var compiledCode = solc.compile(code)

We can see the contracts in compiledCode.contracts object. We can access a specific contract by compiledCode.contracts[':CONTRACT_NAME'] , in our case we can access MessageBoard contract by ':MessageBoard' key. The compiled byte code will be incompiledCode.contracts[':MessageBoard'].bytecode , while the ABI incompiledCode.contracts[':MessageBoard'].interface . ABI is the interface of Smart Contract, which will be used to make calls to Smart Contract from javascript. Learn more about ABI here.

After compiling, we are ready to deploy now.

> var ABI = JSON.parse(compiledCode.contracts[':MessageBoard'].interface)
> var byteCode = compiledCode.contracts[':MessageBoard'].bytecode
> var MessageBoardContract = new web3.eth.Contract(ABI, {
from: address,
gas: 4700000
})
> deployedContract = MessageBoardContract.deploy({data: byteCode})
> address = '0xf3d31153795b5bf4072bc638eb088a794ab18538'
> deployedContract.send({
from: address,
gas: 4700000
}).then((newContractInstance)=> {
console.log(newContractInstance.options.address)
return newContractInstance.methods.setUsername("NarekUser").send()
}).then((x) => console.log(x))

We have address variable, which is the address of an account, which can be taken from output of ganache-cli we run previously. Gas is describing amount of resource needed from miners to acomplish their task. Read more about it here. The deployedContract.send method will return a promise, which will resolve to a ready to use contract instance. With newContractInstance you can interact with out Smart Contract. Please copy/paste the address of deployed smart contract (newContractInstance.options.address), as it will be needed for building the UI in the next section.

Before moving to next section, let’s unlock an ethereum ganache-cli account

> web3.eth.personal.unlockAccount(address)

UI for our Smart Contract

We are going to create a UI for our smart contract using html and jQuery. Take a look to the code bellow, look to the comments and everything will be self explaining. Do NOT Copy paste the code, write line by line, and change the variable values when it will be required.

You may need to include web3.js. You can download web3.js from here.

Note that events are stored in the blockchain, and we can fetch all previous evetns, that’s why instead of keeping array of messages, we just relay on events history.

Now just open index.html file inside your favorite browser and we have now a working Message Board.

Our app is asking username first.
The messages are displayed one by one.

Wrap Up

This was a tutorial for creating really basic Smart Contract with a basic UI. For this tutorial we have skip private/public keys authentication and deploying on a real blockchain. This will be in my next tutorials.

If you understood the material in this tutorial, I’ve made for you four exercises you can try to accomplish.

  1. Modify index.js and index.html to display the user’s name alongside with the message.
  2. Modify index.js file to get provider and addresses from MetaMask. You can install MetaMask from Chrome Store.
  3. Modify index.js and messageboard.sol files, that the UI will not ask username if a user with this address already exists.
  4. Modify index.js and messageboard.sol so it will require for username to be unique for each user.

Thank you!

Thank you for reading the tutorial, feel free to ask any question in comments, I will respond within a day. Follow me if you want to support these tutorials. Also look to my other tutorials/posts. Thanks!

--

--