Introduction to Ethereum development, part 2

Johannes Bertens
oneupcompany
Published in
8 min readFeb 1, 2018

This is part two of the “Introduction to Ethereum development” series. In this series you will install the essential tools, and compile, run and interact with a smart contract! Starting your blockchain development career with a 💥.

This post was first published on Github (you can find it here). It has been re-formatted for Medium, but the content is the same.

Photo by André Sanano on Unsplash, representing the deep-dive nature of this post ;-)

Part 1 of this series, in case you missed it, takes you through installing the required tooling and creating your first blockchain project using Truffle.

Part 2, the part you are now reading, introduces all the elements of this project, gives an in-depth explanation on what is in a smart contract, and shows you how to compile and run the contract.

In part 3 of this series, we will interact with this contract, first from the console and then from a webpage.

Structure of Truffle projects

What do we have now? Well, we have the following folders and files within our MetaCoin folder:

.
├── contracts
│ ├── ConvertLib.sol
│ ├── MetaCoin.sol
│ └── Migrations.sol
├── migrations
│ ├── 1_initial_migration.js
│ └── 2_deploy_contracts.js
├── test
│ ├── TestMetacoin.sol
│ └── metacoin.js
├── truffle-config.js
└── truffle.js
3 directories, 9 files

(I created this ascii tree, with the tree command. It's a nice tool, read more about this tool here: https://www.cyberciti.biz/faq/linux-show-directory-structure-command-line/)

So, there are 2 configuration files in the main folder — both empty, save for an export and some comments, 3 .solfiles in the contracts folder: the MetaCoin itself, a simple library and a utility contract used by truffle, 2 migration javascript scripts in the migrations folder (we will come back to this later) and 2 different types of tests in the test folder (we will also touch upon these tests later).

There are also a few “.placeholder” files, which you can either ignore or delete. I’m deleting them.

For now, the most important parts are the .sol files, let's take a look at them next.

Anatomy of a Solidity (.sol) file

There are 3 different .sol files in the contracts folder, and one in the test folder. We will take a look at the MetaCoin.sol file inside the contracts folder first:

pragma solidity ^0.4.18;import "./ConvertLib.sol";// This is just a simple example of a coin-like contract.
// It is not standards compatible and cannot be expected to talk to other
// coin/token contracts. If you want to create a standards-compliant
// token, see: https://github.com/ConsenSys/Tokens. Cheers!
contract MetaCoin {
mapping (address => uint) balances;
event Transfer(address indexed _from, address indexed _to, uint256 _value);function MetaCoin() public {
balances[tx.origin] = 10000;
}
function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Transfer(msg.sender, receiver, amount);
return true;
}
function getBalanceInEth(address addr) public view returns(uint){
return ConvertLib.convert(getBalance(addr),2);
}
function getBalance(address addr) public view returns(uint) {
return balances[addr];
}
}

For those familiar with Javascript, this should be quite readable. There are some significant differences between Solidity and Javascript, but the general structure is the same.

It starts off with declaring the version of Solidity by using the pragma keyword, in this case the file is declared to be written with version 0.4.18 in mind. The ^ sign in front of the version advises the compiler with a higher version (for example, version 0.5.0) to not compile this source file. The logic used here is the same as used in the NPM package manager, a great blog post explaining this can be found here: http://gunnariauvinen.com/what-do-the-and-mean-in-package-json/

The next command imports the library ConvertLib.sol from the same source folder. We will look into this library later, it is used in the getBalanceInEth function.

Then the contract itself is declared with the contract keyword. This is comparable to the class keyword in other languages, but here denotes a specific Ethereum smart contract.

Inside the contract, we have:

  • a mapping,
  • an event , and,
  • 4 function declarations.

Mappings are almost equal to hash tables or dictionaries in other languages, with the big difference being that there is no concept of a key being stored. They are (virtually) initialized with the value for all possible keys set to 0. Mappings can also be set to public, where Solidity will create a getter to access the data (more on this later). Detailed information on mappings can be found in the Solidity documentation: http://solidity.readthedocs.io/en/develop/types.html#mappings.

The private mapping declared in this contract keeps track of the amount of coins per address.

Events are used to write info to the blockchain logs, the event declared in this contract writes all transactions to the log. Included in the log are the sender (_from), the receiver (_to), and the amount of coins (_value). This event is called from the sendCoin function, at which point the information is written to the log.

From the 4 functions in the contract, the first function has the same name as the contract itself. This is called a constructor. The constructor is optional, but there can be only one constructor per contract. In this constructor (which is called once, when the contract is created), the balance for the creator of the contract (tx.origin) is set to 10000.

The sendCoin function is the heart of the MetaCoin smart contract, which transfers coins from one user to the other. First it checks if the balance of the sender's account has enough coins to transfer. If this is not the case, the functions returns false. If the account does have enough coins, the coins are first removed from the sender's account and added to the receiver's account. Then the event (created earlier) is called before returning true.

Before this gets too boring, let’s compile and run this contract. We will visit the other functions, the library, and tests later on.

Compiling the MetaCoin 🚀

Before you can interact or even run a smart contract, you need to compile it. Luckily this is easy with the Truffle framework, just execute the following command: truffle compile in the terminal. This should give the following output:

Compiling ./contracts/ConvertLib.sol...
Compiling ./contracts/MetaCoin.sol...
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts

There should be no errors (yet) 😄

The next step is to deploy or “migrate” your newly compiled smart contract. This can be done by executing the following command: truffle migrate (unsurprising). This, however, gives the following error:

Error: No network specified. Cannot determine current network.
at Object.detect (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:41338:23)
at /usr/local/lib/node_modules/truffle/build/cli.bundled.js:202239:19
(...)

This is because we need an Ethereum network to deploy our smart contracts to and we need to add this network to the configuration file. Let’s go set that up now!

Photo by NASA on Unsplash, showing a different kind of global network.

Truffle built-in blockchain

We will be using the internal Ethereum test server embedded in truffle, which by default listens on port 9545. To start this server, open up a new console window and navigate to the location of your MetaCoin project (for me, this is /user/johannes/projects/MetaCoin - you can see your full path with the pwd command). In this new window, execute the truffle develop command, this should give you the following output (or something close to it):

Truffle Develop started at http://localhost:9545/Accounts:
(0) 0x627306090abab3a6e1400e9345bc60c78a8bef57
(1) 0xf17f52151ebef6c7334fad080c5704d77216b732
(2) (...)
Private Keys:
(0) c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3
(1) (...)
Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

So, the Truffle development network is now running and listening on port 9545 for commands. Let’s add it to our configuration.

Why are there two configuration files? That’s because the truffle.js file gives conflicts on Windows systems, which is why on windows systems the truffle-config.js is used. We will be using truffle.js.

Replace the content of truffle.js with:

module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 9545,
network_id: "*" // Match any network id
}
}
};

Time to switch back to your first terminal and run the migrate command again (truffle migrate). This should now work and give the following output:

Using network 'development'.Running migration: 1_initial_migration.js
Deploying Migrations...
... 0xd5c14cbf54e24515c0950af100e22949ddccacd0dedf8698c50f405ec8e147dd
Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0
Saving successful migration to network...
... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying ConvertLib...
... 0x417c0187ed5f036675e6e663c05f63a24d263c47b38c7b505a68a1a02fc18ffc
ConvertLib: 0x345ca3e014aaf5dca488057592ee47305d9b3e10
Linking ConvertLib to MetaCoin
Deploying MetaCoin...
... 0x1419c3ca0d263c39a925c7300ddcd68e51be70bb292e06fa0e89edfe815fda0d
MetaCoin: 0xf25186b5081ff5ce73482ad761db0eb0d25abfbf
Saving successful migration to network...
... 0x059cf1bbc372b9348ce487de910358801bbbd1c89182853439bec0afaee6c7db
Saving artifacts...

Congratulations — your contract is now live. 🍻 On your local development network, at least. 😄

Now let’s see how we can interact with it from the command line!

Hello world from MetaCoin

So, what can we do with a live smart contract? Good question! A smart contract is somewhat comparable with a database in this regard, the interaction with it is often through a driver or API. Often, for example with MySQL, there is also a client application to make your life easier. These applications also exist for Ethereum, but we will not be using them (yet). We are going to use the Truffle console. Fire it up using truffle console now.

Your prompt should show: truffle(development)>. Copy-paste the following command into it: MetaCoin.deployed().then(function(instance) {console.log(instance);});

This should give you a lot of output, starting with:

TruffleContract {
constructor:
{ [Function: TruffleContract]
_static_methods:
{ setProvider: [Function: setProvider],
(...)

And somewhere in the middle some unreadable mumble-jumble which represents the bytecode of the contract, ending with:

Transfer: { [Function: bound ] 'address,address,uint256': [Function: bound ] },
sendTransaction: [Function],
send: [Function],
allEvents: [Function: bound ],
address: '0xf25186b5081ff5ce73482ad761db0eb0d25abfbf',
transactionHash: null }
undefined

As you can see there are some functions visible from your smart contract, but also some unknown methods (for example: setProvider - we will explain this in the next part). This is the full printout of the Javascript object provided by Truffle for interacting from within a Javascript environment (like a webpage or Node console app).

Now, let’s look up the balance of our first account (recall the address from starting up our local blockchain) by copy-pasting the following line into the truffle console:

MetaCoin.deployed().then(function(instance) {return instance.getBalance.call("0x627306090abab3a6e1400e9345bc60c78a8bef57")});

(Note: This address only works if you are using truffle develop, as it uses the same addresses every time you start it. If you are using a different ethereum blockchain development framework, fill in your first address - address 0 - here.)

Here we first grab the deployed instance of the MetaCoin contract (called instance) and call the getBalance function with the address of the first account on the blockchain. The truffle migrate command deploys the defined projects under this address, which is why there should be 10000 coins in this account!

Your output should look like the following:

BigNumber { s: 1, e: 4, c: [ 10000 ] }

Notice the 1000 at the end there: great success! 👍

In the next part of this series, we will see how to unpack the BigNumber type, interact with the contract from the console and from a webpage.

Extra: If you are into blockchain development, don’t forget to check out https://blockchain.company

--

--