By the end of this article, you’re going to know how to write simple Ethereum smart contracts using the Remix — Solidity IDE


What IS Ethereum?

In 2009, someone, under the alias of Satoshi Nakamoto, introduced the concept of Bitcoin, the most successful digital currency to date. It popularized the idea of a truly decentralized monetary systems that every transaction is stored in the blockchain. Ethereum attempts to do further than that, by combining the power of decentralized transactions with a Turing-complete programming language (which essentially means you can write programs that can solve any reasonable computational problem).

If you want to get your feet wet with your first smart contracts, a popular language at the moment is Solidity. This guide will walk you step-by-step in learning Solidity by creating an Ethereum Smart contract.


Your first smart contract

To start with, we will be building a voting smart contract that allows users to propose a new proposal – vote for or against the existing ones and quickly query the winning proposal. The idea of this originates from CarbonVote, a web-page with the feature that the voting conducted did not require coins to leave voters’ wallets. The votes are computed at any instant by looking at the amount of ETH in each address that either votes yes or no. The proposer also needs to stake some ETH (5 ETH in this example) behind the proposal which they can get back when they cancel/close the proposal.

Getting started with Remix

If you’re new to developing for Ethereum, it can be a daunting task! To make things easier, I’ll keep this article as simple as possible for the first-timer! For that purpose, I’ll use a zero-install, in-browser IDE The Remix Solidity Editor.

 

Use the (+) button at the top-left corner to create a new file and name it Voting.sol

Code skeleton

Solidity version

First, let’s start off the contract by declaring the solidity version we support:

The contract is written to support the Solidity compiler version 0.4.15 or later but not on a compiler starting from version 0.5.0 (this second condition is added by using ^)

Structs

2 types of struct in the contract

We created 2 structs in this contract: the Voter and the Proposal. The Voter struct contains a Dictionary which maps the index of the proposal with True/False to indicate whether the voter already voted for proposal $index.Every proposal contains these information: the content of the proposal, number of vote for/against, block number when the proposal was propose, the proposer’s address and its canceled status (true if it’s canceled by the proposer, false otherwise)

Events

The contract emits events upon voting for a proposal(VoteFor or VoteAgainst), adding/canceling a new proposal (ProposalAdded/ProposalCanceled) and refunding the staked Ether back to the proposer (Refund). Each event contains the necessary information to track what happens when the voting is conducted.

Modifiers

From the Solidity docs, modifiers:

can automatically check a condition prior to executing the function. Modifiers are inheritable properties of contracts and may be overridden by derived contracts.

In this contract, notEnded modifier was used to make sure the voting is still running. checkValue will make sure the proposer stakes in sufficient Ether for every proposal and refund the excess amount back.

Constructions

Deploying the contract will call the constructor — which is called exactly once and cannot be called again. It initializes the value of initial number of proposal and the status of the voting.

Propose a proposal

Whenever a user propose a new proposal, it’s added to the proposals array the event is logged. The number of proposals and the staked ether of the proposers are also incremented.

Note: We can apply multiple modifiers to a function by specifying them in a whitespace-separted list of the function header. They will be evaluated in the order presented.. In the above code snippet, we added 2 modifiers notEnded and checkValue to make sure the voting is still up and the proposer sends in the appropriate amount to the contract.

Cancel a proposal and refund

When a proposal is canceled by its’ owner, it’s marked as canceled and the Ether staked in the proposal is refunded back. The send method will send the amount of ether specified back to the proposer. It will return true/false indicating whether the refund is succesful.

Warning: Always remember to deduct the balance before calling send to prevent reentrancy exploit (e.g: The attacker can spam the refund function. The send method may not finish before the attacker make another call to the refund and end up calling send multiple times before decreasing the proposer’s balance)

Vote

When a user votes, he/she either votes for or against a proposal. We want to check if the proposalIndex is valid and it’s not canceled before proceeding. We also want to prevent a user from voting a proposal twice by checking the dictionary votedProposals of each voter. Then we increment the vote count of the proposal by the balance of ether (in wei unit) of the voter. An event is also logged to mark a vote event

Query all information of a proposal

Calling this function with appropriate index will give you all the information (the content, the number of vote for/against, proposer’s address and block number proposed) of the proposal. It returns a tuple of values that you can extract further in a web application.

Query the winning proposal

When this function is called, it will return the index of the proposal with the highest (voteFor-vote Against).

Deployment and testing

Deploy the contract

Deploying

On the right panel, use these selection:

  • Environment: Javascript VM
  • Gas Limit: 300000
  • Gas Price: 0
  • Value: 0
  • Create: <keep blank>

and click Create. The contract will be deployed to the test blockchain.

Interacting with the contract

Yay! It worked.

 

Type in the proposal you want to add in addNewProposal box and the value you will send to the contract in the value box. In this demonstraion, we sent 30 ETH with the proposal “Build a voting contract” to the function addNewProposal.

Even though we sent 30 ETH with the proposal, you can see that only 5 ETH were deducted from the account. Our modifier checkValue() has checked for excess amount and send back the unnecessary ETH amount.

Querying the proposal using the index (e.g: 0 in the demonstraion) shows all the information about proposal (content, number of votes for and against, sender and block number)

 

You can interact more with smart contracts by adding more proposals, switching between multiple account, vote yes or no for the proposals and query the winning one.

What’s next?

Where to go after here you ask?

You could test this code on the Ethereum testnet, or you could create a web app that would allow users to interact with the Voting contract

There are a ton of tutorials on Solidity out there, but a some that we find the most helpful:

This is a very first step in learning Solidity and Ethereum smart contracts. We are curious to know what you will be coding from here.


If you’re excited about the intersection of robotics, smart contracts, and blockchain, join our Telegram channel and checkout our website

If you have questions, concerns, or feedback — let us know in the comments.

Authored by Khoa Ho, Software Engineer @ Kambria

Join Kambria Newsletter

Author

A lucky guy was born in the Age of Cryptocurrency Boom.

Write A Comment