
Ethereum, tokens & smart contracts.
Notes on getting started Part 5. Smarter Contracts
Previous notes in case you are just joining us:
Part 1. Setting up.
Part 2. Web3.js/node.
Part 3. Solidity.
Part 4. Smart Contracts
It feels like we are halfway up the Ethereum mountain, in this part I would like to go a bit deeper into contracts with slightly more advance features we will need later.
Constructors
A constructor (which is common in other languages) simply initializes a contract with some value,operation or set of operations, let’s say we want to store the address of the contract originator ( that’s us), we would do something like this:
FILE: constructorContract.solpragma solidity ^0.4.0;contract constructorContract {address father;function constructorContract() {
father = msg.sender;
}function whosyourfather() constant returns (address) {
return father;
}}
A little extra explanation is in order:
- function constructorContract() is a our constructor function and will only run once in the life of the contract.
- We first define a new type of storage: Address Type, and then we initialize the contract with msg.sender which is the address of the first sender or creator, let’s deploy and then call this contract :
Readout only, deployed using our trusty compiler from past notes:Setting up...
Reading contract Source...
Compiling...
saving ABI
ABI Saved
gasEstimate: 110760 + 50000
gasPrice: 20000000000
unlocking Coinbase account
Deploying contract...
txHash:0x077ef8e4e3e6eb9dcfee00d6bacf45e8da612921209d8476ebf46b74eafc3dc9
Successfully deployed Contract with address: 0xc80ef52d06866cbdebb2a709d075d2508ea0c5d5
And so, if everything went well, we should be able to call our whosyourfather() function and get the creators address:
FILE: callContract.jsconsole.log('Setting up...');
const solc = require ('solc');
const Web3 = require ('web3');
console.log('Reading abi');
const contractABI = require("./constructorContract.json");console.log('Connecting');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));console.log('Creating contract instance');
const contract = web3.eth.contract(contractABI);
var contractInstance = contract.at("0xc80ef52d06866cbdebb2a709d075d2508ea0c5d5");console.log ('calling contract');var returner = contractInstance.whosyourfather.call();
console.log('This contracts father is :' + returner);//This contracts father is :0x001301ad1556fd419cf8970b174fe9af34267eb8
The above address corresponds to the address I first created a few notes ago and will remain that way forever… contract I am your father.
Types
A lot of the functionality of smart contracts comes from the specific types solidity supports,which in essence allow contracts to go beyond simple storage and behavior, so let’s check out a few of the more interesting ones….
I Recommend you read the full Solidity Docs on Types, you will also be consulting it from time to time.
Value Types :
Passed by value, for instance the handy boolean:
// FILE: booleanContract.solpragma solidity ^0.4.0;contract booleanContract {bool switcher;function flipSwitch() constant returns (bool) {
switcher = !switcher;
return switcher;
}}
- Compiler Readout :
Welcome Good Sir to Compiler Mk2 Setting up...
Reading contract Source...
Compiling...
saving ABI
ABI Saved
gasEstimate: 96783
gasPrice: 21000000000
unlocking Coinbase account
Deploying contract...
txHash:0xaa0d82eb3228c52fb9f192b69c7a2983e390fefbf5a9bbb5fd14690959ff354d
Succesfully deployed Contract with address: 0xe10e9ec821c219ca483c3a48915c3530add08724
- Calling flipSwitch():
var switcher = contractInstance.flipSwitch.call();
console.log('switcher state : ' + switcher); // True
// switcher was originally false.Note: If you want to actually change the switcher boolean in the contracts storage, you would need to call flipSwitch in a transaction.
Enums:
Enums are useful when you have a variable that can take one of a series of predefined values ( see this answer, for java but same principles apply )
- Contract:
// FILE: enumContract.solpragma solidity ^0.4.0;contract enumContract {enum someThings { CHAIR, CAR, TREE, COFFEE }
someThings constant favoriteThing = someThings.COFFEE;function getFavoriteThing() returns (uint) {
return uint(favoriteThing);
}
}// Notice the lack of semicolon at the end of the enum values.
- Deploy (skipping full readout) :
Deploying contract...
txHash:0x97e9385d936774c044b7ed80499b52e3737e2eb01e191c6e2b7fede2366a0484
Succesfully deployed Contract with address: 0x5d9a2c9e85e6b46466abc42408ab80d46b61d17a
- Call function
FILE : callContract.js ( skipping the header section from now on, but it is the same file, just change the ABI and the contract address.
var favoriteThing = contractInstance.getFavoriteThing.call();
console.log('Favorite Thing: (0:CHAIR, 1:CAR, 2:TREE, 3: COFFEE ) : ' + favoriteThing);// Favorite Thing: (0:CHAIR, 1:CAR, 2:TREE, 3:COFFEE ) : 3// Notice that enum gives us a number not a string, so it is up to us to interpret it when reading it. It is also zero indexed.
Reference types :
Reference types (mainly arrays and structs) are more complex types which we’ll discuss next:
Arrays:
Ethereum implementation of the ubiquitous array data type is pretty straightforward with the caveat that one needs to pay attention to the way they are stored, as part of the state (in storage) or in memory ( non peristent), let’s do a simple array contract:
// FILE: arrayContract.sol
pragma solidity ^0.4.0;contract arrayContract {uint[] someNumbers = [10,13,14];function getArray() constant returns (uint) {
return someNumbers[1]; // should return 13
}}
- Deploying:
Deploying contract...
txHash:0x30a1cdc7742b57e6efda75a9214f7c78bef38bfa389228b19f21606fda706dd0
Succesfully deployed Contract with address: 0x97b9892deb69a94b428da3c590c7ca793341493c
- Calling:
var getArr = contractInstance.getArray.call();
console.log('getArray : ' + getArr);// getArray : 13
I won’t go too far into arrays for now as they become more complex to define when used as variable storage. Instead I’ll focus on 2 of the more useful types: structs and mapping which complement arrays:
Structs:
Structs can be considered as a grouping of variables ( Object literals without methods if you are coming from JS ) which in essence give you a new type, they make sense if a set of variables can describe another variable with multiple instances ,here’s an example:
// FILE: structContract.solpragma solidity ^0.4.0;contract structContract {struct Stuff {
address addr;
uint[] someNumbers;
}Stuff myStuff;
Stuff otherPeoplesStuff;function structContract(){
myStuff.addr = msg.sender;
myStuff.someNumbers = [20,30,40];
otherPeoplesStuff.addr = msg.sender;
otherPeoplesStuff.someNumbers = [22,33,44];
}function getMyStuff() returns (address, uint){
return (myStuff.addr, myStuff.someNumbers[1]);
}function getOthersStuff() returns (address, uint){
return (otherPeoplesStuff.addr, otherPeoplesStuff.someNumbers[0]);
}}
Explanation: struct Stuff defines a new Stuff type that has an address and an array with numbers, we then inititate 2 variables ( myStuff and otherPeoplesStuff ) using our newly created type . In our constructor (structContract()) we initiate these variables structs, and finally we can reference them with dot notation for our getter functions.
- Deploying:
Deploying contract...
txHash:0x234615b084288719dd20f05829ffc28e8ece866acf070049956fa76819780182
Succesfully deployed Contract with address: 0x8170478d82c63ddf1786157e7ab329e0925dc94f
- Calling:
var myStuff = contractInstance.getMyStuff.call();
console.log('myStuff : ' + myStuff);var othersStuff = contractInstance.getOthersStuff.call();
console.log('othersStuff : ' + othersStuff);// myStuff : 0x001301ad1556fd419cf8970b174fe9af34267eb8,30
// othersStuff : 0x001301ad1556fd419cf8970b174fe9af34267eb8,22
Mappings:
Mappings in solidity are roughly equivalent to hash tables ( or associative arrays in Javascript), mappings have this structure:
From the Docs:mapping(_KeyType => _ValueType) mapNameHere _KeyType can be almost any type except for a mapping, a dynamically sized array, a contract, an enum and a struct._ValueType can actually be any type, including mappings.Keys can be integers, strings, or addresses, values can be any other type.
Let’s write a contract with mappings:
// FILE mappingContract.solpragma solidity ^0.4.0;contract mappingContract {mapping(uint => uint[]) luckyNumbers;function mappingContract(){
luckyNumbers[1] = [10,20,30];
luckyNumbers[2] = [11,22,33];
}function getLucky(uint luckyKey) constant returns (uint[]){
return luckyNumbers[luckyKey];
}}
- Deploying:
Deploying contract...
txHash:0xac9b15597dbb2dc9e931c50fd8d55b8866c623f63d3d10a4e1e77ce4fbcdb737
Successfully deployed Contract with address: 0x1e5f7deadf846ae2f8402c2e3d1cc38ae556ef8e
- Calling:
var luckyNumbers1 = contractInstance.getLucky.call(1);
console.log('Lucky Numbers 1 : ' + luckyNumbers1);var luckyNumbers2 = contractInstance.getLucky.call(2);
console.log('Lucky Numbers 2 : ' + luckyNumbers2);// Lucky Numbers 1 : 10,20,30
// Lucky Numbers 2 : 11,22,33
This is by no means a complete guide or overview of types and the solidity language; there is still some ground to cover, yet I believe we have enough knowledge to tackle making our own crypto currency in the form of a token smart contract (finally !) , which will cover in next section (booo!) , for now let’s take a breather and recap:
- Notes Part 1 : Setting up : Getting a wallet/client , connecting to a test Ethereum blockchain and getting some test ether.
- Notes Part 2: web3.js/node : Interacting with the blockchain through web3.js and node for more convenience and ease of development.
- Notes Part 3: Solidity : Installing solidity (Ethereums contract writing language ) , Creating a very basic contract, compiling it, deploying it to the blockchain ( the test one) and interacting with it.
- Notes Part 4: Smart Contracts: We modified our simple contract so we could store and retrieve information (making it smart), in the process we also covered how to watch the blockchain and contracts and finally we took a look at gas and how to estimate it.
- Notes Part 5: Smarter Contracts ( This post ) : In order to allow contracts more complex behavior (make them smarter) , we need to delve a bit deeper into contract creation via constructors and a few more complex types which we will use in making a token contract.

Now in book form !If you are looking for an introduction to Ethereum, Solidity and Smart Contracts these notes were edited into a convenient book for you !Available in ebook and paperback here:https://www.amazon.com/dp/B078CQ8L7V
Cheers !
Keno
About the Author :
Born Eugenio Noyola Leon (Keno) I am a Designer,Web Developer/programmer, Artist and Inventor, currently living in Mexico City, you can find me at www.k3no.com