Friday, August 4, 2017

Hello World Ethereum Smart Contract with VS Code and Solidity


In my previous blog we have created our first Hello world app using Remix Solidity IDE.

In this blog, I will go over how to use Visual Studio Code to compile the Hello World contract and deploy the contract on a private chain and Rinkeby chain. Please refer to my other related blogs for setting up Visual Studio Code, Private Chain and connecting to Rinkeby Testnet.

Let’s start by opening Visual Studio Code and open a folder in VS Code. If required create the folder. The folder is required because VS code compiles the code and creates the abi and bytecode here.

Create a new file in this folder called HelloWorld.sol with the below code:
pragma solidity ^0.4.11;

contract HelloWorld {

    function greet() public constant returns (string) {
        return "Hello World!";
    }
}

Compile this smart contract by pressing F5 key. This creates a bin folder with abi and bin (bytecode). Here are the contents of the abi and bin file:
abi:
[{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"}]

bin(bytecode):
6060604052341561000c57fe5b5b6101498061001c6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663cfae3217811461003a575bfe5b341561004257fe5b61004a6100ca565b604080516020808252835181830152835191928392908301918501908083838215610090575b80518252602083111561009057601f199092019160209182019101610070565b505050905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100d261010b565b5060408051808201909152600c81527f48656c6c6f20576f726c6421000000000000000000000000000000000000000060208201525b90565b604080516020810190915260008152905600a165627a7a723058205168b085c257b42e405c11a8e900935fd85bd351767a3ed78211b54b7c6df2e10029

Now let’s start the private chain as mentioned in my blog Ethereum Dev Chain - Private Chain

Here are the steps to be followed in the JavaScript console to deploy the contract:
  • Unlock the account so that Ether can be used for gas
> personal.unlockAccount(eth.accounts[0], "password")
true
In the above command I am using the first account. If required you can specify any other account
  • Define the abi & bytecode variables. Prefix the bytecode with “0x”
var abi = [{ abi generated by the compiler }]
var bytecode = “0x<bytecode generated by compiler>”
  • Deploy the contract
> var contract = eth.contract(abi)
  • Find the gas estimate for deploying the contract
eth.estimateGas({ data: bytecode} )
This gives the gas required to deploy the contract. Currently it’s value is 138902. Specify this value in the next step while creating an instance of this contract
  • Now create an instance of this contract.
> var instance = contract.new({
......    from:eth.accounts[0],
......    data:bytecode,
......    gas:138902}, function(err, contractInstance){
......     if(!err) {
.........        if(!contractInstance.address) {
............            console.log("Tx Hash: " + contractInstance.transactionHash) // The hash of the transaction
............        } else {
............            console.log("Address: " + contractInstance.address) // the contract address
............        }
.........     }
...... else {
......... console.log(err)
......... }
...... });
Tx Hash: 0x57228ccd8013aa17b134c3f76147a1c5a74f40f98c7bc352e484f42581e30355
undefined
> Address: 0x44408814564648d05d4cfcf12397151cfee0af52
The contract creation is an asynchronous function. Once the contract is mined, the call back function returns the transaction hash and address at which the contract is deployed.
  • Wait till the contract is mined and address is shown in the console
  • Now invoke the greet function
> instance.greet()
"Hello World!"

With above steps we successfully deployed the contract onto a private chain and invoked it. Here is the complete JavaScript console code:
personal.unlockAccount(eth.accounts[0], "password")
var abi = [{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"}]
var bytecode = "0x6060604052341561000c57fe5b5b6101498061001c6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663cfae3217811461003a575bfe5b341561004257fe5b61004a6100ca565b604080516020808252835181830152835191928392908301918501908083838215610090575b80518252602083111561009057601f199092019160209182019101610070565b505050905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100d261010b565b5060408051808201909152600c81527f48656c6c6f20576f726c6421000000000000000000000000000000000000000060208201525b90565b604080516020810190915260008152905600a165627a7a723058205168b085c257b42e405c11a8e900935fd85bd351767a3ed78211b54b7c6df2e10029"

var contract = eth.contract(abi)
var gas = eth.estimateGas({ data: bytecode} )

var instance = contract.new({
   from:eth.accounts[0],
   data:bytecode,
   gas:gas}, function(err, contractInstance){
    if(!err) {
       if(!contractInstance.address) {
           console.log("Tx Hash: "+ contractInstance.transactionHash) // The hash of the transaction
       } else {
           console.log("Address: "+ contractInstance.address) // the contract address
       }
    }
    else {
        console.log(err)
    }
});

//wait for the mining to be completed
instance.greet()

I generally use Rinkeby during the UAT environment. Let’s run the above script in the Rinkeby environment and check it. Please refer to my other blog on how to connect to Rinkeby chain, Setting up Ethereum Rinkeby Testnet

I deployed the contract on Rinkeby network and here is the screenshot of this contract:


1 comment:

  1. Ethereum or Litecoin. Which one is technically better prepared for the future?

    I'm not asking about which coin value you think it will increase more as I'm aware more value doesn't necesarilly means it's a better cryptocurrency.

    I ask this question because I'm a newbiew so despite I have been reading a lot I still can't understand all the concepts perfectly

    ReplyDelete