Write A Simple Contract On Top Of Ethereum

In this article, I am going to show you how to create a smart contract on top of Ethereum. Smart contract is a program on top of Ethereum. Some people say the smart contract is an unstoppable application. We are going to use a web application in https://remix.ethereum.org to build a smart contract. It is an online editor for learning how to build a simple smart contract. In this web application, we use Solidity programming language. Solidity is a programming language commonly used to write a smart contract. You will be greeted with a smart contract sample of voting application.

A default page in Remix.Ethereum.org

Let’s write our first contract. You can wipe out the entire content of browser/ballot.sol. Or you can create a new file by clicking a button on the top left corner.

Add new file button
Giving a new file name

Give it ‘auction.sol’ name.

Now we are ready to write a smart contract. The first line you are going to write is:

pragma solidity ^0.4.19;

This is the directive to tell which compiler that can compile this code. The version 0.4.18 and lower are forbidden. The version 0.5 is forbidden as well. The version 0.4.20, 0.4.21 are okay. The latest version as can be seen in https://github.com/ethereum/solc-js/releases is 0.4.23 as the time this article is written. The Solidity compiler used in the web application is the latest version. You can see the information if you click the Settings tab. You will be greeted with Solidity compiler used in the web application.

Settings tab
Solidity compiler

Then you’ll type:

contract Auction {
}

This is our skeleton contract. The closest thing in other mainstream programmings like Python, Java would be a ‘class’ keyword. It is a code block that represents a contract. Like a class in other programming languages, it has variables and functions (methods) that represent the state of the contract itself.

In other programming languages, you have a class and an object. A class is a template for an object. Contract is just like that. The source code of the contract is the template. If in other programming languages you create an object out of the template, here you deploy a contract. In other words, deploying a contract is basically a synonym of creating an object of the class.

In Remix editor, it is easy to do that. Go to Run tab, then make sure you use JavaScript VM environment before clicking Create button.

Creating a smart contract
Contract created

Here, we deploy the contract to local JavaScript virtual machine. But you can deploy it to Ethereum main network but you need to pay for it. I mean, in the JavaScript VM you still have to pay the fee. But in JavaScript VM, they give 100 ethers for free for each account (fake ethers; these ethers will not be accepted in Ethereum main network). If you notice, the account does not have 100 ether anymore, but 99.999999 ether. The small amount needs to be paid to deploy the contract. The smart contract does not do anything at this point.

Let’s write some variables for this smart contract. We are going to write a smart contract that can be an auction house. We have a manager that represents the auction house whose the purpose is solely to deploy the contract and finish the auction. And there is a seller who wants to auction items. There are bidders to bid the item.

 address public manager;
address public seller;
uint public latestBid;
address public latestBidder;

Solidity is like other programming languages. It has integer type of variable. Uint here means unsigned integer (can not hold negative value). It has string, array, and other data type that you can expect from a decent programming language. But there is a peculiar data type called address which is quite unique. Address here is not like a pointer in C programming language. Don’t think it as an address in memory. Address here means where the smart contract lives, or your account lives. Address is something like 0xca35b7d915458ef540ade6068dfe2f44e8fa733c.

If you notice, once you modify the contract, the accounts’ ether are reseted again. It is better to remove the contract and redeploy the contract again to see your changes’ effect.

Deleting the contract

After variables, we need to write the constructor. It is optional. This constructor is a special function that is run initially when the contract is deployed.

 constructor() public {
manager = msg.sender;
}

The () means this function does not accept any argument. Public keyword means this function can be called from outside. Inside the constructor, as we can see, there is a special variable msg. We never declared msg variable. Where does it come from? When you call the function externally (in this case it is called implicitly when you create a smart contract), the msg variable represents the address that run that function. In this case, the property sender of the msg variable is the address of ‘someone’ who run this function. There are other properties as well (we’ll look into that later).

After the constructor, we can write the function to set the initial amount of bid.

 function auction(uint bid) public {
latestBid = bid * 1 ether; //1 ether is 1000000000000000000;
seller = msg.sender;
}

This function accepts an argument, an unsigned integer variable. Here, the function expects any unsigned integer that will be multiplied with ‘1 ether’ before being stored to the variable latestBid which is unsigned integer as well. We want to store the bid in wei currency. Ethereum has not just 1 currency. It is like Bitcoin which has bitcoin currency and satoshi currency. They all represents how many bitcoin you have. But 1 bitcoin is greater than 1 satoshi. We store the bid into the lowest currency. Wei to Ethereum is like satoshi to Bitcoin. 1 ether is 1000000000000000000 wei.

Then we store the address of ‘someone’ who runs this function into the seller variable. Remember the one who deploys the contract can be different than the one who call the auction function.

So how do we run the auction function?

First we redeploy the smart contract by clicking the Create button again. After doing that, you can check the manager variable value (you can check it because it is declared public). Notice it is the same as the address you use in the Account select box.

The manager variable can be inspected

To run the auction function we can click the auction button. Before doing that, let’s change the account select box to other account. We don’t want the manager and the seller to be the same person. By default the account select box got 5 accounts. Chose other than the one you have used. Then you type the value in the input field on the right side of auction button. In this case, we want to set the initial bid to be 2 ether. So type 2. Then click the auction button.

Execute the auction function

Then we need to create a bid function where people can raise their hand to bid the item.

function bid() public payable {
require(msg.value > latestBid);

if (latestBidder != 0x0) {
latestBidder.transfer(latestBid);
}
latestBidder = msg.sender;
latestBid = msg.value;
}

This function will be called many times by many people. We assume people want to outbid other people. So the first thing we do inside this function is to check whether the amount of money that they send along with this invocation of function is greater than the latestBid which if it is not initialized will have a 0 value. What?!! You can send an amount of money along with the invocation of function. I’ll show you how soon.

In this policy we have the policy that if we have the bigger bid, we return the previous bid which is lower to its bidder. We keep the latest bidder and its bid in variables. Here, you see there is other property of msg variable other than sender which is value. The value property is the amount of money you send along the invocation of the function. You type the money that you want to send (in this case just type 4) in the Value input field. But change the select box on the right side from wei to ether. Finally, hit the bid button. Make sure you use other account beside the manager and the seller accounts.

Send money along the invocation of the function

After running the bid function, you notice that the money from the account becomes 95.99999 ether. That’s because you send the money to the contract as much as 4 ether. You can check the latestBid and latestBidder to see the updated bid.

After bidding process

You can change the account and bid with higher amount of money. And you will notice the 4 ether will be returned to the previous bidder.

The last part will be finishing auction function. To make it simple, the policy of the smart contract auction process will be closed by the manager. This function can only be executed with manager address.

function finishAuction() restricted public {
seller.transfer(address(this).balance);
}

modifier restricted() {
require(msg.sender == manager);
_;
}

Here, you can see the modifier keyword. Inside the modifier function you could see that we check whether the one who executes this function is the manager or not. Then there is _ statement. This _ will pass the control back to the function which this modifier function applied to. In the finishAuction function, we use the address seller and execute its method transfer. The method transfer accept one argument, how much money you want to send. This refers to the smart contract and we cast it to the address type before calling its balance property. To put in a nutshell, address(this).balance refers to all money in the smart contract. If you execute this function, the seller account will increase its money. Make sure you execute the function as the manager. If you don’t, you will find the transaction fails.

Transaction fails

There are many improvements that can be made into this smart contract. We’ll explore that in the future articles. This is the full source code:

pragma solidity ^0.4.19;
contract Auction {
address public manager;
address public seller;
uint public latestBid;
address public latestBidder;

constructor() public {
manager = msg.sender;
}

function auction(uint bid) public {
latestBid = bid * 1 ether; //1000000000000000000;
seller = msg.sender;
}

function bid() public payable {
require(msg.value > latestBid);

if (latestBidder != 0x0) {
latestBidder.transfer(latestBid);
}
latestBidder = msg.sender;
latestBid = msg.value;
}

function finishAuction() restricted public {
seller.transfer(address(this).balance);
}

modifier restricted() {
require(msg.sender == manager);
_;
}
}

If you find this article helpful, you can donate Bitcoin to me in this Bitcoin address:

1KcLb8EbaRVobt4vb54fWTaqhrEAFLgP3T