Truffle

Jumping into Truffle and Rinkeby

This tutorial was made with truffle v3.4.9 (core: 3.4.8) and solidity v0.4.15.

Truffle setup

Windows

If you’re a Windows user, we recommend installing and using Truffle via Windows PowerShell or Git BASH. These two shells provide features far beyond the standard Command Prompt, and will make your life on the command line much easier.

Non-windows

lets install testrpc.

Testrpc is a Node.js based Ethereum client for testing and development. It uses ethereumjs to simulate full client behavior and make developing Ethereum applications much faster. It also includes all popular RPC functions and features (like events) and can be run deterministically to make development a breeze. https://github.com/ethereumjs/testrpc

Alt text

Now while testrpc is running in a brand new terminal we can go ahead and install truffle, initialize and app and run it.

Here we are using a shortcut truffle unbox react which does an initialization and adds the necessary modules for react. If you want to have a pure instalation you should instead run truffle init inside of the folder you created.

Go into your truffle folder.

Compile and migrate and deploying the default solidity contracts to the testrpc. Your default app should look like this.

Alt text

Solidity

lets mess around with the solidity contract. We are going to be making a contract called MySale. truftest/contracts/MySale.sol

$ truffle create contract MySale

Now we have to add a migration file for deploying this contract to the evm. Create a file called truftest/migrations/3_add_Sale.js

Note that the filename is prefixed with a number and is suffixed by a description. The numbered prefix is required in order to record whether the migration ran successfully. The suffix is purely for human readability and comprehension.

Ok lets fill out the migration.

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

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

Now you will be provided with a solidity file with no functions. I went ahead and filled it in with 3 rudimentary functions. truftest/contracts/MySale.sol

pragma solidity ^0.4.4;

contract MySale {
  mapping(address => uint) balance;
  uint total_coins = 1;

  function printCoin(uint howMuch) public{
  	balance[msg.sender] += howMuch;
  	total_coins += howMuch;
  }

  function allCoins() constant public returns(uint){
  	return total_coins;
  }
  
  function myCoin() constant public returns(uint){
   return balance[msg.sender];
  }
}

Now lets go ahead and make our app have a touch event to trigger both a get and a set function from that contract.

Go to truftest/src/App.js and add this.

import React, { Component } from 'react'
import MySale from '../build/contracts/MySale.json'
import getWeb3 from './utils/getWeb3'

import './css/oswald.css'
import './css/open-sans.css'
import './css/pure-min.css'
import './App.css'

const contract = require('truffle-contract')
const mySale = contract(MySale)

class App extends Component {
  constructor(props) {
    super(props)

    this.state = {
      storageValue: 0,
      web3: null
    }
  }

  componentWillMount() {
    getWeb3
    .then(results => {
      this.setState({
        web3: results.web3
      })
    })
    .catch(() => {
      console.log('Error finding web3.')
    })
  }

  coinCount(){
    mySale.setProvider(this.state.web3.currentProvider)
    var mySaleInstance

    console.log("...getting data");
    this.state.web3.eth.getAccounts((error, accounts) => {
      mySale.deployed().then((instance) => {
        mySaleInstance = instance
        return mySaleInstance.allCoins.call({from: accounts[0]})
      }).then((result) => {
        console.log("result", result);
      })
    })

  }

  printCoin(){
    mySale.setProvider(this.state.web3.currentProvider)
    var mySaleInstance
    console.log("...setting data");
    this.state.web3.eth.getAccounts((error, accounts) => {
      mySale.deployed().then((instance) => {
        mySaleInstance = instance
        return mySaleInstance.printCoin(4, {from: accounts[0]})
      }).then((result) => {
        console.log("result", result);
      })
    })
  }


  render() {
    return (
      <div>
        <div id="get" onClick={this.coinCount.bind(this)}></div>
        <div id="set" onClick={this.printCoin.bind(this)}></div>
      </div>
    );
  }
}

export default App

I added some css to #get and #set so I can see those div’s. You can find this in truftest/src/App.css

#set{
  height:50px;
  width:50px;
  background-color:red;
  float:left;
  margin: 20px;
  cursor: pointer;
}
#get{
  height:50px;
  width:50px;
  background-color:blue;
  float:left;
  margin: 20px;
  cursor: pointer;
}

What we get is two boxes that when clicked execute our contract and console.log the result. But what if we didn’t want to run the app inside of testrpc? For that we will need mist and rinkeby. Rinkeby is the test evm. rinkeby.io. Lets go a head and get setup for that next.

Dependencies

$ curl https://install.meteor.com/ | sh
$ curl -o- -L https://yarnpkg.com/install.sh | bash
$ yarn global add electron@1.4.15
$ yarn global add gulp

Mist setup

 $ cd ~/Desktop
 $ mkdir mist_test && cd mist_test
 $ git clone https://github.com/ethereum/mist.git
 $ cd mist
 $ yarn
 $ cd interface && meteor --no-release-check

Now you’re ready to initialize Mist for development:

While meteor is running open another terminal window and go back to the folder you created /Desktop/mist_test/mist

Now lets run electron for the first time:

$ cd ~/Desktop/mist_test/mist
$ yarn dev:electron

Alt text

Rinkeby download

Were done with mist!

If you want to read more about mist you can do so here. For now close both terminals. The one running meteor and the one running mist/electron.

Free Rinkeby ether

In order to use the test network we have to have test ether which we cant just print out.

Connecting to Rinkeby

Make sure to close the terminal.

First, start geth with Rinkeby and make sure that the correct APIs for Truffle are enabled.

$ geth --rinkeby --rpc --rpcapi db,eth,net,web3,personal --unlock="0x6a6401AEb4a3beb93820904E761b0d86364bb39E" --rpccorsdomain http://localhost:3000

Please dont forget to replace my wallet with the wallet you got from mist/electron.

This will ask you for the password you gave mist/electron.

Next, we need to add Rinkeby to our truffle config file. If we open truffle.js in our contract code we’ll see something like:

module.exports = {
  rpc: {
    host: 'localhost',
    port: '8545'
 },
  networks: {
    development: {
      host: "localhost",
      port: 8545,
      network_id: "*" // Match any network id
    },
    rinkeby: {
      host: "localhost", // Connect to geth on the specified
      port: 8545,
      from: "0x6a6401AEb4a3beb93820904E761b0d86364bb39E", // default address to use for any transaction Truffle makes during migrations
      network_id: 4,
      gas: 4612388 // Gas limit used for deploys
    }
  },
};

Please dont forget to replace the from section in this file to your ethereum address you scored from mist/electron.

Now we just have to migrate the contract onto rinkeby. This is going to ask for the password you gave mist/electron.

$ truffle migrate --network rinkeby

If you want to view the current state of your contracts on rinkeby test network go to this url.

(Replace my wallet with yours. My address’s transactions. )

https://rinkeby.etherscan.io/address/YOUR-WALLET-HERE

Congratulations we set it up!!