Ethereum: Deploy Ethereum Smart Contract with Truffle

Let get started by creating a node.js application

mkdir ~/Training/GreetingsTruffle
cd ~/Training/GreetingsTruffle

The purpose of this tutorial is to demonstrate the use of Ganache and Truffle, so we only build a simple Greetings smart contracts.

Please go to Truffle’s website to install your version of Truffle. In this tutorial, I’m using Mac. But the result is the same because we are using command line.

Let’s check your Truffle version in command line

> truffle version
Truffle v4.1.8 (core: 4.1.8)
Solidity v0.4.23 (solc-js)

 

Project initilazation

Let’s initiate a project

truffle init

File structure

Please open your project and this is the file structure.

contract is where you write your solidity contract. We will use the

Greetings.sol from the previous lecture.

migrations you will only have 1_initial_migration.js, 2_deploy_contracts.js is what we will be writing.

test folder is where you write your test script using Mocha and Chai

truffle.js is where you set your connection to Ganache

truffle-config.js is where you put your custom configuration file, but since we are using command line and command line will take precedence over the config you set here. So in order to prevent conflict, it is better to delete this file if you are not sure what you are doing.

[panel style=”panel-default”]
[panel-header]
Note
[/panel-header]
[panel-content]
Please open 1_initial_migration.js  and Migration.sol and take a look. They are paired files and they should always be executed first as they migrate our script to Ganache for deployment.
[/panel-content]
[/panel]Please keep the migration script. This is to track which script has been run.

 

truffle.js

truffle.js  is left empty because it is using it’s own in-memory Ganache core to run Truffle on its’s own.

 

Greetings.sol

pragma solidity ^0.4.23;

contract Greetings{
    string message;

    function Greetings() public {
        message = "i'm ready!";    
    }

    function setGreetings(string _message) public {
        message = _message;
    }

    function getGreetings() public view returns (string) {
        return message;
    }
}

 

2_deploy_contracts.js

This is to deploy your Greetings.sol int o Ganache. This file’s content is very similar to 1_initial_migration.js

var Greetings = artifacts.require("./Greetings.sol");

module.exports = function(deployer) {
    deployer.deploy(Greetings);
};

 

execute away

Open your command line in your project root direct. key intruffle develop and you can see the accounts you have in Ganache.

Truffle Develop started at http://127.0.0.1:9545/

Accounts:
(0) 0x627306090abab3a6e14445bc60c78a8bef57
(1) 0xf17f52151ebef6c7445704d77216b732
(2) 0xc5fdf4076b8f3a5357c440b5b54098fef


Private Keys:
(0) c87509a1c067bbde78beb7446382a4c0241e5e4a9ec0a0f44dc0d3
(1) ae6ae8e5ccbfb04590405997ee2d54430726137b875053c36d94e974d162f
(2) 0dbbe8e4ae425a6d2687f1a443636790f1b8ad91193c05875ef1


Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

⚠️  Important ⚠️  : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.

This will also expose a javascript connection to this truffle. We will talk about it later.

Now open another command line window at your project root directory because we want our output to appear in another place. Remember to keep your original console running, do not close it.

truffle develop --log

then you will see

Connected to existing Truffle Develop session at http://127.0.0.1:9545/

Migration

You will use this command to rebuild everything, otherwise truffle will not do anything even there is a text change in your file.

truffle(develop)> migrate --compile-all --reset

You will see the following output

Compiling ./contracts/Greetings.sol...
Compiling ./contracts/Migrations.sol...

Writing artifacts to ./build/contracts

Using network 'develop'.

Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0xccace61379dd87b50a0721d58ee5e61e58368330c318e09d0f79f5965931acbf
  Migrations: 0x8f0483125fcb9aaaefa9209d8e9d7b9c8b9fb90f
Saving successful migration to network...
  ... 0x2e369ab2d57c20d6f0be342da05a0e340a8e85de0aef12b3199e44de9005d26c
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Replacing Greetings...
  ... 0x9d47f23c31796697045409c9f73518f5c543bc2312ea265761631bf6c8c985ad
  Greetings: 0x2c2b9c9a4a25e24b174f26114e8926a9f2128fe4
Saving successful migration to network...
  ... 0xd7245d7b1c0a7eb5a5198754f7edd7abdae3b806605b54ecc4716f9b4b05de61
Saving artifacts...

If you check your console log, you will see a lot of output appearing on your console.

....
  develop:testrpc eth_newBlockFilter +2ms
  develop:testrpc eth_getFilterChanges +3ms
  develop:testrpc eth_getTransactionReceipt +7ms
  develop:testrpc eth_getCode +4ms
  develop:testrpc eth_uninstallFilter +12ms
  develop:testrpc eth_sendTransaction +1ms
  develop:testrpc  +26ms
  develop:testrpc   Transaction: 0xd7245d7b1c0a7eb5a5198754f7edd7abdae3b806605b54ecc4716f9b4b05de61 +1ms
  develop:testrpc   Gas usage: 27008 +0ms
  develop:testrpc   Block Number: 8 +0ms
  develop:testrpc   Block Time: Wed May 09 2018 10:25:56 GMT+0800 (CST) +0ms
  develop:testrpc  +0ms

 

Greeting Instance running

Now we have an contract factory. let’s do some manipulation

truffle(develop)> Greetings.address
'0xf204a4ef082f5c04bb89f7d5e6568b796096735a'

Please look at your build file Greetings.json and you will find that many information are stored there. For example our Ganache network setting.

   ...
    "5777": {
      "events": {},
      "links": {},
      "address": "0xdeaba33a65a20616487322772303687ba905ee51",
      "transactionHash": "0x771cb6647b51873606f23d47f76e1901f7cf3658301e966aa1cabde146de634d"
    }

 

Whatever you did in the previous lecture note, you can also do it here. For example

truffle(develop)> web3.eth.accounts

Then you can get your accounts in Ganache.

Now we want to set up an instance and use it

Greetings.deployed().then(function(instance){app = instance;});

Now let’s look at our app

truffle(develop)> app

Output:

TruffleContract {
  constructor:
   { [Function: TruffleContract]
     _static_methods:
      { setProvider: [Function: setProvider],
        new: [Function: new],
        at: [Function: at],.....
    setGreetings:
      { [Function: bound ]
        request: [Function: bound ],
        call: [Function: bound ],
        sendTransaction: [Function: bound ],
        estimateGas: [Function: bound ],
        getData: [Function: bound ],
        string: [Circular] },
     getGreetings:
      { [Function: bound ]
        request: [Function: bound ],
        call: [Function: bound ],
        sendTransaction: [Function: bound ],
        estimateGas: [Function: bound ],
        getData: [Function: bound ],
        '': [Circular] },
        
        
        ....
      }
   }
}<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1">​</span>

 

let’s do more

app.getGreetings();
app.setGreetings("what the duck", { from: web3.eth.accounts[0] });
app.getGreetings();

 

Migrate to Ganache

We were actually doing our job in the truffle network, now let’s migrate to Ganache and see the visual result.

We modify truffle.js to connect to Ganache we are running in our computer by using following setting.

module.exports = {
  // See <http://truffleframework.com/docs/advanced/configuration>
  // to customize your Truffle configuration!
  networks: {
    ganache:{
      host: "localhost",
      port: 7545,
      network_id: "*"
    }
  }
};

Let’s deploy to Ganache

remember to exit your existing truffle command by issuing

.exit

Let’s truffle!

// deploy to new network ganache for visual testing
truffle migrate --compile--all --reset --network ganache

you will see output

....
Using network 'ganache'.
....

Please go to Ganache and you will see what you just did! not bad!!

And take note that your balance decreased, so you are indeed using Ganache.

Interact with our contact deployed to Ganache

truffle console --network ganache

then it is all the same as above

Greetings.address
Greetings.deployed().then(function(instance){app = instance;});

// then you can use app use call getGreetings and setGreetings
app.getGreetings();
app.setGreetings("what the duck", { from: web3.eth.accounts[0] });

app.getGreeting();

 

Using Ganache is more visually appearing, so I prefer this way. You can try out other command line to see how it’s going.

Leave a Reply

Your email address will not be published. Required fields are marked *