Build your first Ethereum smart contract during lunch break

This tutorial promised to guide you through your first smart contract in 25 minutes. Sit tight and let’s begin.

Lunch break plays a crucial role in the daily life of many of us, so as Blockchain and the Bitcoin, who went viral on the globe in recent years. You could nearly tell the movement of Bitcoin price, by the peculiar look gave from the person you bumped into on street. Not long ago, the emergence of Ethereum brought the preciosity of blockchain technology back to community. Each of us, you and me, now have the pen to sign off a contract.

3 steps in total

  1. Get what you need
  2. Swift guide through the code
  3. Deploy and try it out

Step 1 >>> What you need

  1. solidity (https://solidity.readthedocs.io/en/develop/)
  2. truffle (http://truffleframework.com/)
  3. testrpc (https://github.com/ethereumjs/testrpc)

# Note: If you came across difficulties in downloading these tools, please leave your words down there, so I would help you with that. :)


Step 2 >>> Let’s code

Story: Today, you and your friends wanna organize a lunch gathering with the other friends, but you are not sure who will attend, and who will not. You have reserved a group lunch with given price and limited seats in a nice Taiwanese restaurant, and you hope to split the cost with the attendees eventually. How could the smart contract help you?

I. Create Project

Kick off your terminal and type in:

mkdir lunch-contract    // This will be the root of your project
cd lunch-contract
truffle init // Let truffle does everything for you

open the directory in your favorite editor, and you now have:

- contracts/
- migrations/
- test/
- truffle.js

# Note: Luckily, we only need to play with contracts/ and migrations/ in this tutorial. You could delve in the documentation of truffle for sure.

II. Launch a Testnet

Cool, let’s run up an Ethereum test net in your computer. Please start off the other terminal in the lunch-contract/ directory, and type in:

testrpc

That is astonishing, you’ve launched your first test net!

# Note: More excitingly, in the loggings, there are 10 accounts already registered for you, for FREE lol.

III. Create the Contract

Create a new file under contracts/ directory named Lunch.sol. Inside Lunch.sol, put in the skeleton of contract:

contract Lunch {
    // Your code goes here later
}

IV. Initialize the Variables

Right below the line contract Lunch, initialize your variables as such:

address public organizer;
mapping (address => bool) public attendeeJoined;
uint public numOfAttendee;
uint public limit;
uint public totalCost;

<Tips>:

  1. address: A special variable type in solidity, who represents an account.
  2. public: Let everyone outside of this contract can still access this variable.
  3. mapping: A special variable type as well, which maps every given address to a Boolean value, in this case.
  4. uint: Unsigned integer that saves storage space better.

V. Set up a Constructor

Under all the initialization, please do:

function Lunch() {
organizer = msg.sender;
limit = 10;
numOfAttendee = 0;
totalCost = 100;
}

<Tips>:

  1. msg: Every call of the method of this contract will happen along with a msg object, whose sender is the address of caller.

VI. Method 1: Change the total cost:

Let’s insert this function under the constructor.

function changeTotalCost(uint newTotalCost) public {
if (msg.sender != organizer) { return; }
totalCost = newTotalCost;
}

<Tips>:

  1. Method arguments: For this method, the only argument is newTotalCost as uint type.
  2. Access control: The if-statement prevents anyone, other than the organizer, to change the total cost.

VII. Method 2: Attend the lunch:

This is probably the most complicated part of this tutorial. How could your friend attend? Place the attend method in.

function attend() public payable returns (bool) {
if (numOfAttendee >= limit) { return false; }
attendeeJoined[msg.sender] = true;
numOfAttendee++;
return true;
}

<Tips>:

  1. payable: Allows this contract to be transferred REAL MONEY, namely ether, which will then be stored at this contract’s address. We don’t practically require it here, but it serves as a demonstration.
  2. return: The type of returned value is necessary to be specified as a Boolean, in this case. Be reminded this syntax is quite different from Javascript.

VIII. Method 3: How many available seats left:

function getAvailable() public returns (uint) {
return limit - numOfAttendee;
}

VIIII. Method 4: Check attendance:

function checkAttendance(address people) public returns (bool) {
return attendeeJoined[people];
}

X. Method 5: Split cost:

function splitCost() public returns (uint) {
return totalCost / numOfAttendee;
}

# Note: Since both the types of totalCost and numOfAttendee are uint, the return value will then be converted to uint.

XI. Kill method:

function kill() {
if (msg.sender == organizer) {
suicide(organizer);
}
}

# Note: It is a good thing to kill or commit suicide in Solidity, in so doing that all the REAL MONEY(ether) stored at this contract, will be transferred back to the creator of this contract. Yet, in this tutorial we don’t have ether transferal.


Step 3>>> Deploy the contract and try out

Go to migration/ and open 2_deploy_contracts.js, comment out all the lines and change it to:

var Lunch = artifacts.require("./Lunch.sol");
module.exports = function(deployer) {
deployer.deploy(Lunch);
};

All the code-writings are done here! Congrats! In your console, type in:

truffle console

Now we open a window toward your Ethereum test net, anything we do here can impact the test net directly. To deploy your contract:

deploy

Your Lunch contract is now successfully deployed on the test net. Let’s get the accounts you’ve created.

accounts = web3.eth.accounts

Instantiate a Lunch contract and assign to lunch, and then we can interact with lunch:

Lunch.new().then(obj => lunch = obj)

Congratulation and Bon Appétit!

Incredible! You have just completed and deployed your first contract on Ethereum with a whole lot of cool methods! Why not buy yourself a decent meal first, and then we talk later?

Play Around

Everything is ready now! There are some testing examples provided for you, but are not limited.

(1) Check the limit of the number of attendee:

lunch.limit.call()
// Or lunch.limit.call().then(obj=>obj.c[0])

(2) Change total cost to 500, and check it:

lunch.changeTotalCost.sendTransaction(500, {from: accounts[0]})
lunch.totalCost.call()
// Or lunch.totalCost.call().then(obj=>obj.c[0])

(3) Let two of your friends attend, accounts[1] & accounts[2]

lunch.attend.sendTransaction({from:accounts[1]})
lunch.attend.sendTransaction({from:accounts[2]})

(4) Check the seats left, and check the attendance of accounts[1] and accounts[3]

lunch.getAvailable.call()
// or lunch.getAvailable.call().then(obj=>obj.c[0])
lunch.checkAttendance.call(accounts[1], {from:accounts[0]})
lunch.checkAttendance.call(accounts[3], {from:accounts[0]})

(5) Finally, split the costs

lunch.splitCost.call()
// Or lunch.splitCost.call().then(obj=>obj.c[0])

Thanks for your time~

Please feel free to leave any guidance or thought in the comment, if you like this tutorial or anything you found me wrong. :)

All the codes can be found here.

Please also read the great tutorial from ConsenSys, here, who enlightened me as well as granted me the chance to unashamedly write up this tutorial. The skeleton of my tutorial is based on theirs for sure.