Deploying Smart Contracts - cogeorg/teaching GitHub Wiki

There are multiple ways to compile and deploy smart contracts. Here we will go through four methods: the geth JavaScript console, web3.py, the Ethereum Wallet, and Truffle.

Before you can continue, you need to make sure you have a compiler installed.

NB Make sure to unlock the account being used prior to attempting to deploy a contract. Using

personal.unlockAccount(address, password, 0)

will unlock the account indefinitely until the geth instance stops running. Please note that this is not advised when using the main network.

For the purposes of illustration, we will be using the AIFMRMCoin contract described below

pragma solidity ^0.4.0;

contract AIFMRMCoin {


    address public minter;

    mapping (address => uint) public balances;

    event Sent(address from, address to, uint amount);

    function AIFMRMCoin() {
        minter = msg.sender;
    }

    function mint(address receiver, uint amount) {
        if (msg.sender != minter) return;
        balances[receiver] += amount;
    }

    function send(address receiver, uint amount) {
        if (balances[msg.sender] < amount) return;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Sent(msg.sender, receiver, amount);
    }
} 

JavaSript Console

Compilation

To deploy this contract, it needs to be saved in the JSON format and assigned to a JavaScript variable, that will be sent to an output file. In a terminal execute the following

echo var AIFMRMCoinCompiled=`solc --optimize --combined-json abi,bin,interface --overwrite /path/to/containing/folder/AIFMRMCoin.sol` > /path/to/output/folder/AIFMRMCoinCompiled.js
cat /path/to/output/folder/AIFMRMCoinCompiled.js

This command compiles the contract and saves the output to a script that will be loaded into your Geth console by typing

loadScript('/path/to/output/folder/AIFMRMCoinCompiled.js')

The loaded compiled contract is saved to the variable AIFMRMCoinCompiled. To deploy this contract, the following variables need to be declared:

var AIFMRMCoinContractAbi = AIFMRMCoinCompiled.contracts['/path/to/containing/folder/AIFMRMCoin.sol:AIFMRMCoin'].abi
var AIFMRMCoinContract = eth.contract(JSON.parse(AIFMRMCoinContractAbi))
var AIFMRMCoinBinCode = "0x" + AIFMRMCoinCompiled.contracts['/path/to/containing/folder//AIFMRMCoin.sol:AIFMRMCoin'].bin

AIFMRMCoinContractAbi contains byte code represented as a sequence of hex numbers, which will actually be executed by the EVM. AIFMRMCoinBinCode contains the contract's Application Binary Interface. This is a json file that describes the contract’s methods and arguments. It is needed to call the contract methods once deployed since the byte code does not hold this information.

Deployment

In order to successfully deploy a contract, the deployment transaction must be mined. Thus, the node you are running needs to be mining. The command eth.mining can be used to check the mining status of the node. If required, mining can be started with the command miner.start(2) in the geth console. Remember to make sure that the account being used to deploy the contract is unlocked. To deploy the contract

var deployTransationObject = { from: eth.accounts[0], data: AIFMRMCoinBinCode, gas: 1000000 }
var AIFMRMCoinInstance = AIFMRMCoinContract.new(deployTransationObject, function(e, contract){
	    if(!e) {
	      if(!contract.address) {
	        console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
	      } else {
	        console.log("Contract mined! Address: " + contract.address);
	        console.log(contract);
	      }
	    }
	}) 

Once the deploying transaction has been sent, a web3 contract object is returned with a missing address, as the transaction is yet to be mined. Only once the transaction has been mined will the contract obtain an address. The callback function used in AIFMRMCoinInstance is an optional argument used to keep track of whether the contract has been successfully deployed. If the deploying transaction is successfully executed and is waiting to be mined, the following message containing the transaction hash will be displayed in the console "Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...". Once it has been successfully mined, the console will display "Contract mined! Address: " + contract.address in the console.

Interacting with the contract

In order to interact with the contract, we need to retrieve its address from the transaction receipt

var AIFMRMCoinAddress = eth.getTransactionReceipt(AIFMRMCoinInstance.transactionHash).contractAddress
var AIFMRMCoin = AIFMRMCoinContract.at(AIFMRMCoinAddress)

Now we can interact with the contract functions

// Mint 500 coins and check balance
AIFMRMCoin.mint(eth.accounts[0],500)
AIFMRMCoin.balances(eth.accounts[0])

web3.py

This python library can be used to compile and deploy smart contracts in a similar fashion to the JavaScript console. The script below will deploy the AIFMRMCoin contract. This method requires a node to be running .

from web3 import Web3, HTTPProvider, IPCProvider
from solc import compile_source, compile_files

# web3.py HTTP/IPC instance

# web3 = Web3(HTTPProvider('http://localhost:8545'))
web3 = Web3(IPCProvider())

# Solidity source code
source = "/Users/admin/Documents/Geth/Contracts/AIFMRMCoin.sol"
source_code = open(source, "r").read()

# Compile contract
compiled_sol = compile_source(source_code)
contract_interface = compiled_sol['<stdin>:AIFMRMCoin']

# Instantiate and deploy contract
AIFMRMCoin = web3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])
web3.personal.unlockAccount(web3.eth.accounts[0], 'password', 0)

# Get transaction hash from deployed contract
tx_hash = AIFMRMCoin.deploy(transaction={'from': web3.eth.accounts[0], 'gas': 1000000})

# Get tx receipt to get contract address
tx_receipt = web3.eth.getTransactionReceipt(tx_hash)
contract_address = tx_receipt['contractAddress']

# Mint 500 coins and check balance
AIFMRMCoin.transact(transaction={'from': web3.eth.accounts[0], 'gas': 1000000, 'to': contract_address}).mint(web3.eth.accounts[0], 500)
AIFMRMCoin.call(transaction={'from': web3.eth.accounts[0], 'gas': 1000000, 'to': contract_address}).balances(web3.eth.accounts[0])

Using the online compiler

Remix is a useful online IDE for smart contracts development. Instead of manually compiling the contract code as we did above, Remix can be used to generate all the required inputs. This can then be copied into the console for deployment. Alternatively, Remix can be connected to a local node, allowing the contract to be deployed directly from the IDE. Remix also has the advantage of having a interactive UI which can be used to interact with the contract and test its functionality.

Using Ethereum wallet

The Ethereum wallet UI also gives users the ability to compile and deploy smart contracts. After setting up a node, launching the application will automatically connect it to the running node. The smart contracts tab contains instructions on how it can be used to deploy smart contracts.

Truffle

Truffle is a development environment, testing framework and asset pipeline for Ethereum. For more information on the framework, check out this wiki page.

To deploy the AIFMRMCoin smart contract, create a new file AIFMRMCoin.sol file in the contracts directory and paste the code provided above. Next, create a file called 2_deploy_contracts.js in the migrations folder. This file will contain instructions to retrieve and deploy the contract to the target network. It should include the following

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

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

It is exactly the same as in 1_initial_migration.js except that we exchanged the name of the smart contract.

To deploy the contract, start a node

$ truffle develop

and migrate your contract

> migrate --compile-all --reset

This command will (re-)compile and (re-)deploy your contract.

⚠️ **GitHub.com Fallback** ⚠️