Scout App for monitoring

Today we will set up our local Ethereum environment for development, debugging and deployment.

We will use the Truffle framework. It’s available as an npm package, so let’s install it.

Install Truffle

npm install -g truffle

Initialize empty project
mkdir truffle-dev

cd truffle-dev

truffle unbox metacoin

We are using the unbox function to initialize a boilerplate project that will set up an example Metacoin smart contract for us and a good overall project structure.

After the unbox command you should see the following project structure in your folder.

image alt text

contracts/ - directory for your Solidity Smart Contracts.

migrations/ - directory for deployment files, similar but not exactly the same to Django’s migrations folder. These migrations are used for keeping track of the changes to your smart contracts.

test/ - directory with tests, for testing our Smart Contracts.

truffle.js - configuration file for our local blockchain network.

Inside the contracts/ folder are three smart contracts. Let’s look at those; reading good code is also an effective way to learn.

Smart Contract Library ConvertLib

pragma solidity ^0.4.4;

library ConvertLib{
    function convert(uint amount,uint conversionRate) returns (uint convertedAmount)
    {
        return amount * conversionRate;
    }
}

This smart contract is defined with library instead of contract; this makes it a library smart contract that can be easily imported into other smart contracts. Library smart contracts are useful for containing functions you want to use in multiple other contracts, just like normal programming libraries.

It also makes economic sense to keep reusable functions in one place instead of repeating them in multiple smart contracts. When deploying to the main Ethereum blockchain we are charged by the letter, so the longer a Smart Contract is, the more expensive it is to deploy. We’ll cover the whole deployment pipeline later; let’s move on to MetaCoin.sol.

Smart Contract MetaCoin

pragma solidity ^0.4.4;

import "./ConvertLib.sol";

contract MetaCoin {

    mapping (address => uint) balances;
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    function MetaCoin() {
        balances[tx.origin] = 10000;
    }

Immediately we notice the import of our library ConvertLib.sol which indicates we’ll be using the convert function somewhere down the line.

Then for the first time we see the mapping data structure. Mapping is the analog of a hash in Java and C# or a dictionary in Python. (NOTE: Mapping allows direct access to its values by their keys, but it has limitations. You cannot iterate its keys or its values. You can always do it manually.) In this case it’s a mapping between type address and type uint (unsigned int).

We saw the address type yesterday in the Greeting example. It represents a personal address or smart contract address. This mapping maps addresses to numbers; more specifically, it keeps a record of the balances of MetaCoin coins each user has.

Next we notice an event called Transfer:

event Transfer(address indexed _from, address indexed _to, uint256 _value);

Events are used for generating notifications across the blockchain network to notify anyone that’s listening of events happening in this smart contract. They accept arguments which are later part of the generated notification.

This is extremely useful because events take away the burden of having to process the whole blockchain when an application is interested in only a few events.

For example, this event creates a notification that represents a transfer of Metacoins. It contains the address of both sender and receiver, along with the value that was transferred. By listening to this event only, an application can keep track of all MetaCoin transactions that occur without having to process the whole Ethereum blockchain where millions of transactions are created every day.

Lastly, we have the constructor where we set the a balance of 1000 MetaCoin to the address of tx.origin. Just like msg was, tx is a special global variable that represents the current transaction. Any action that alters the data on the blockchain, like deploying a smart contract or executing a function that changes data, is a transaction.

Tx.origin represents the origin or creator of the transaction; it’s similar to msg.sender but not quite the same. [Tx.origin](https://ethereum.stackexchange.com/a/1892) can never be a smart contract address, while [msg.sender](https://ethereum.stackexchange.com/a/1892) can.

In this call chain A->B->C->D; inside smart contract D msg.sender will be C, but tx.origin will be A.

However Vitalik recommends avoiding [tx.origin](https://ethereum.stackexchange.com/a/200).

Send coins

    function sendCoin(address receiver, uint amount) returns(bool sufficient) {
        if (balances[msg.sender] < amount) return false;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Transfer(msg.sender, receiver, amount);
        return true;
    }

The sendCoin function is used for transferring coins from one address to another. It returns a boolean value which indicates the success of the transfer.

In the parameters we see only the receiver’s address and the amount. Only the sender can call the method; in short, only you can spend your coins.

If the sender’s balance is less than the amount to be sent, then we return false.

Otherwise the sender’s balance is decreased by the sending amount and the receiver’s balance is increased by the same amount.

Then we create a Transfer event to notify anyone who is interested in these events.

For example, wallet applications need to listen for events with your address so they can notify you of any funds you receive.

In the end, we return true for successful transfers.

Methods for checking balance

function getBalanceInEth(address addr) returns(uint){
        return ConvertLib.convert(getBalance(addr),2);
    }

function getBalance(address addr) returns(uint) {
        return balances[addr];
    }

The getBalance method simply checks the balances, mapping for the balance of the given address.

The getBalanceInEth method also gets the balance but then converts it into Ether. In this case the number 2 is used as a conversion rate.

Compiling Smart Contracts

The truffle command for compiling is:

truffle compile

On first run it compiles all smart contracts in the contracts directory. On any subsequent runs it will only compile the ones that have changed. The compiled Smart Contracts are placed inside the new build directory in the subfolder contracts. There is one JSON file for each smart contract. We will come back to these files later. Next we need to set up our truffle.js file with our local network ip, port and network id. We’ll use the default configuration from their documentation.

Truffle.js

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

Now let’s finally deploy these smart contracts to our local blockchain.

Open a second terminal and run:

> truffle develop

This will bring up a new local blockchain out of the blue. By default the local blockchain runs on localhost:9545. Make sure this matches the port in your truffle.js file.

Now back in the first terminal run:

> truffle migrate

In the output of the migrate command; you’ll get this:

Running migration: 1_initial_migration.js

  Deploying Migrations...

  ... 0x6b8a72c8e0144badd61583118b8853b93046869820975084e5186b0bc60acc00

  Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0

Saving successful migration to network...

  ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956

Saving artifacts...

Running migration: 2_deploy_contracts.js

  Deploying ConvertLib...

  ... 0xb4107a708879fe5fb68af71e9c161da5f40a5fe8cbb941f9b28c53702ffd555b

  ConvertLib: 0x345ca3e014aaf5dca488057592ee47305d9b3e10

  Linking ConvertLib to MetaCoin

  Deploying MetaCoin...

  ... 0x4937dc8520e9fce002a383af6be0bb25be050e11c70edd1741a85aa06df391e0

  MetaCoin: 0xf25186b5081ff5ce73482ad761db0eb0d25abfbf

Saving successful migration to network...

  ... 0x059cf1bbc372b9348ce487de910358801bbbd1c89182853439bec0afaee6c7db

Saving artifacts...

Notice these lines:

Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0

ConvertLib: 0x345ca3e014aaf5dca488057592ee47305d9b3e10

MetaCoin: 0xf25186b5081ff5ce73482ad761db0eb0d25abfbf

These are the addresses where each Smart Contract is deployed.

Interacting with Smart Contracts

The Ethereum Blockchain makes a distinction between writing data to the blockchain and reading data from it. This distinction plays an important role in how you write your application that interacts with the blockchain DApp.

Writing data is called a transaction while reading data is called a call. Transactions and calls are processed very differently.

Transactions

Transactions change the state of the blockchain. A transaction can be as simple as sending Ether to another account, or as complicated as executing a contract function or deploying a new contract to the blockchain. The main characteristic of a transaction is that it writes, or changes, data. That is why transactions cost Ether, known as "gas," to run, and they take time to process. When you execute contract’s function you create a transaction; you cannot receive that function’s return value because the transaction isn’t processed immediately. These functions will return a transaction ID instead.

We can use this transaction ID later on to check the status of the transaction on the blockchain and see if it has executed yet or not. This is why events are so useful. They allow your application to listen passively for events to happen, instead of actively checking the transaction status on the blockchain.

In summary, the most important properties of transactions are:

Calls

Calls are almost the exact opposite of transactions. They can be used to execute code on the blockchain, but no data will be permanently changed. They are free to run, and their defining characteristic is they read data.

If we execute a contract function that is a call, we receive the return value straight away, or synchronously.

In summary, important properties of calls are:

In short, the choice between a transaction and a call becomes a choice to either read or write data.

Interacting with Smart Contracts

After the migration is complete, we now have available JavaScript objects for every smart contract we deployed. Write the following code in the second terminal where we ran > truffle develop.

trufle(develop)> var instance = MetaCoin.at("0xf25186b5081ff5ce73482ad761db0eb0d25abfbf");

truffle(develop)> instance

This will print out the full deployed instance of the MetaCoin contract.

Check balance

Let’s make our first interaction by checking the balance of the owner’s address. You can see the default owner account called coinbase by typing in the truffle console:

> web3.eth.coinbase

To see all accounts in the local blockchain run:

> web3.eth.accounts

The address of the default account or the coinbase is the address that we get when we run tx.origin or msg.sender in our smart contracts.

This means that all 10000 MetaCoin tokens should be in the balance of this coinbase account. Let’s check its balance:

instance.getBalance.call(web3.eth.coinbase)

That prints out 10000.

We call the getBalance function as getBalance.call**; this represents a call, not a transaction. That is why we got the result straight away.

Send coins

Let’s make our first blockchain transaction by making a transfer. We will use the sendCoin function to transfer 9 coins from the coinbase account to some of the other accounts on the Blockchain.

var source = web3.eth.coinbase;
var target = web3.eth.accounts[1];
instance.sendCoin(target, 9, {from: source});

We passed three arguments to the sendCoin function, even though it expects only two in the definition. The last argument, passed as object, allows us to alter special properties of the transaction itself. In this case we set the origin of the transaction to be the coinbase account, since that is where all the coins are.

As a result we see the full transaction object:

 tx: '0x77a36e5186987d75252b15d1c2e0d09d56ad6e3893a0a90b549dd0a21f1e70b0',
  receipt:
   { transactionHash: '0x77a36e5186987d75252b15d1c2e0d09d56ad6e3893a0a90b549dd0a21f1e70b0',
     transactionIndex: 0,
     blockHash: '0x57b9bd35b9db12b3264d500c13447e4fda27ef5446d5ebdd4196afcf420908a1',
     blockNumber: 6,
     gasUsed: 50960,
     cumulativeGasUsed: 50960,
     contractAddress: null,
     logs: [ [Object] ],
     status: '0x01',
     logsBloom: '0x00000000000000000000000000000000010000000000000000000010000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000008000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000010000000000000000000010000000000000000000000000000000000000000010000000002000000000000000000000000000000000000002000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' },
  logs:
   [ { logIndex: 0,
       transactionIndex: 0,
       transactionHash: '0x77a36e5186987d75252b15d1c2e0d09d56ad6e3893a0a90b549dd0a21f1e70b0',
       blockHash: '0x57b9bd35b9db12b3264d500c13447e4fda27ef5446d5ebdd4196afcf420908a1',
       blockNumber: 6,
       address: '0xf25186b5081ff5ce73482ad761db0eb0d25abfbf',
       type: 'mined',
       event: 'Transfer',
       args: [Object] } ] }

If you look closely you’ll notice the status: 0x01 value in the transaction response. Status 1 means the transaction is processed, while 0 means it is unprocessed.

Let’s check the balance of the target and coinbase accounts.

>instance.getBalance.call(source);

>instance.getBalance.call(target);

The source has 9991 left while the target account has 9.

Summary:

Today we covered a lot. First we installed Truffle and set up our local blockchain network. Then we looked at two more smart contracts. The first one was a library and the second one a pseudo coin. We learned the key differences between a call and a transaction. In the end we made some interactions with the smart contract simulating the actions an application would perform.

Resources:

Decentralized Applications (DApps)

Make your DApp Serenity proof.

Truffle framework

Difference between tx.origin and msg.sender

Iterate a mapping

Scout App for monitoring

Darko Kolev

Student of life, people, software development and business. Currently Lead Software Engineer at BitcoinAverage

  1. Comments for Setting Up A Local Ethereum Dev Environment

You must login to comment

You May Also Like