Contract Deployment – How to Deploy the Greeter Contract via Geth CLI on Private Blockchain

contract-deploymentgo-ethereumgreeterprivate-blockchain

I am running a local private Ethereum blockchain using:

geth --networkid 60098 --genesis CustomGenesis.json --nodiscover --maxpeers 0 --rpc --rpccorsdomain "http://localhost:3000" --datadir "./data" console

It runs fine. I can mine some coins to fill the coinbase account and see a balance in it.

My problem is that my contract deployment transaction does not record into the blockchain. I tried the Greeter tutorial from the docs at GitHub wiki.

Relevant statements that I ran from that article are:

var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }'

var greeterCompiled = web3.eth.compile.solidity(greeterSource)

Compiles fine, and then I used this command to deploy the contract:

var _greeting = "Hello World!" 

var greeterContract = web3.eth.contract(greeterCompiled.greeter.info.abiDefinition);

var practice_acct = '0x0ff4e0dfc7f4b94b4ab6a83e922fe1ac9ac1a625'; //verified to have sufficient coins

var greeter = greeterContract.new(_greeting,{from: practice_acct, data: greeterCompiled.greeter.code, gas: 4000000}, 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);     }    } })

Then I get this back after entering my passphrase and trying to output the greeter:

Unlock account 85b1a00f429811eed0f56ceff9ae19de047ab9fe
Passphrase:
undefined
greeter
{
address: undefined
}

I even tried directly pasting the ‘Web3 deploy’ code from the online Solidity compiler using the tutorial source. Still no address returning.

Any ideas where my problem might be?

Best Answer

Update Apr 23 2017

geth 1.6.0 has a breaking change to remove access to the Solidity compiler from within geth.

The workaround is detailed in How to compile Solidity contracts within geth with the v1.6.0 **BREAKING CHANGE**?



Update Feb 04 2017

Solidity 0.4.9 has a breaking change. The workaround is detailed in Unable to define greeterContract in the Greeter tutorial. Breaking change in Solidity 0.4.9! where you have to use refer to variable like greeterCompiled.<stdin>:greeter with greeterCompiled["<stdin>:greeter"].



Here's a step-by-step guide to get this contract deployed to a dev blockchain.

Create A Coinbase Account

user@Kumquat:~/ESE/Deploy$ geth --datadir "./data" --dev account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 
Repeat Passphrase: 
Address: {730b87e78b07fb2bf1b1e8b127b3353d08d72706}



Window #1 - Run Geth Mining Instance With Unlocked Account

This geth instance will mine the blockchain. We will unlock the coinbase account so this instance will be able to execute transactions, and run the mining on one CPU thread. Enter your password created in the previous step at the Passphrase: prompt.

user@Kumquat:~/ESE/Deploy$ geth --datadir "./data" --dev --unlock 0 --mine --minerthreads 1
I0409 01:02:10.427513   32675 database.go:71] Alloted 16MB cache to data/chaindata
I0409 01:02:10.429602   32675 database.go:71] Alloted 16MB cache to data/dapp
I0409 01:02:10.431573   32675 backend.go:314] Protocol Versions: [63 62 61], Network Id: 1
I0409 01:02:10.431686   32675 backend.go:362] Blockchain DB Version: 3
I0409 01:02:10.432078   32675 blockchain.go:214] Last header: #0 [e5be9214…] TD=131072
I0409 01:02:10.432118   32675 blockchain.go:215] Last block: #0 [e5be9214…] TD=131072
I0409 01:02:10.432153   32675 blockchain.go:216] Fast block: #0 [e5be9214…] TD=131072
I0409 01:02:10.439890   32675 cmd.go:115] Starting Geth/v1.3.6/linux/go1.5.1
I0409 01:02:10.440240   32675 server.go:311] Starting Server
I0409 01:02:12.543810   32675 udp.go:212] Listening, enode://ef1eb6acad7a816bcc8debe0b078e0d8433225ca5d57622687aea13fee389e2ef064e7f01b5f8bf1d003d4722032597f2688917ca13133bd872fb90ba6872bce@[::]:30303
I0409 01:02:12.544021   32675 backend.go:526] Server started
Unlocking account 0 | Attempt 1/3
I0409 01:02:12.544151   32675 backend.go:584] Automatic pregeneration of ethash DAG ON (ethash dir: /home/user/.ethash)
I0409 01:02:12.544180   32675 server.go:552] Listening on [::]:30303
I0409 01:02:12.544217   32675 backend.go:591] checking DAG (ethash dir: /home/user/.ethash)
Passphrase: 
Account '0' (0x730b87e78b07fb2bf1b1e8b127b3353d08d72706) unlocked.
I0409 01:02:18.255806   32675 miner.go:119] Starting mining operation (CPU=1 TOT=1)
I0409 01:02:18.255950   32675 ipc.go:112] IPC service started (data/geth.ipc)
I0409 01:02:18.256684   32675 worker.go:569] commit new work on block 1 with 0 txs & 0 uncles. Took 829.143µs
I0409 01:02:18.256853   32675 ethash.go:220] Generating DAG for epoch 0 (size 1073739904) (0000000000000000000000000000000000000000000000000000000000000000)
I0409 01:02:19.852771   32675 ethash.go:237] Done generating DAG for epoch 0, it took 1.595912996s
I0409 01:02:34.225955   32675 worker.go:348] 🔨  Mined block (#1 / bf23cf06). Wait 5 blocks for confirmation
I0409 01:02:34.226385   32675 worker.go:569] commit new work on block 2 with 0 txs & 0 uncles. Took 357.68µs
I0409 01:02:34.226734   32675 worker.go:569] commit new work on block 2 with 0 txs & 0 uncles. Took 286.72µs



Window #2 - Run Second Geth Instance Attaching To The First

EDIT 30/05/2016 - Updated command as IPC path behaviour has changed between geth v1.3.6 and 1.4.5-stable.

Open a second terminal and run a second geth instance that attaches to the first geth instance. Checking the balance of the coinbase account (eth.accounts[0]) will show an increasing balance as the first geth instance continues mining.

user@Kumquat:~/ESE/Deploy$ geth --datadir "./data" --dev attach ipc:data/geth.ipc
instance: Geth/v1.4.5-stable/linux/go1.5.1
 datadir: data
coinbase: 0x730b87e78b07fb2bf1b1e8b127b3353d08d72706
at block: 71 (Sat, 09 Apr 2016 01:07:42 AEST)
modules: admin:1.0 db:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 shh:1.0 txpool:1.0 web3:1.0
> web3.fromWei(eth.getBalance(eth.accounts[0]).toNumber(), "ether")
"360"
> web3.fromWei(eth.getBalance(eth.accounts[0]).toNumber(), "ether")
"390"
> 

Compile the code in the question and display the compiled code.

> var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }'
undefined
> var greeterCompiled = web3.eth.compile.solidity(greeterSource)
undefined
> greeterCompiled
{
  greeter: {
    code: "0x606060405260405161023e38038061023e8339810160405280510160008054600160a060020a031916331790558060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10609f57805160ff19168380011785555b50608e9291505b8082111560cc57600081558301607d565b50505061016e806100d06000396000f35b828001600101855582156076579182015b82811115607657825182600050559160200191906001019060b0565b509056606060405260e060020a600035046341c0e1b58114610026578063cfae321714610068575b005b6100246000543373ffffffffffffffffffffffffffffffffffffffff908116911614156101375760005473ffffffffffffffffffffffffffffffffffffffff16ff5b6100c9600060609081526001805460a06020601f6002600019610100868816150201909416939093049283018190040281016040526080828152929190828280156101645780601f1061013957610100808354040283529160200191610164565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101295780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b565b820191906000526020600020905b81548152906001019060200180831161014757829003601f168201915b505050505090509056",
    info: {
      abiDefinition: [{...}, {...}, {...}],
      compilerOptions: "--bin --abi --userdoc --devdoc --add-std --optimize -o /tmp/solc163112865",
      compilerVersion: "0.3.1",
      developerDoc: {
        methods: {}
      },
      language: "Solidity",
      languageVersion: "0.3.1",
      source: "contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }",
      userDoc: {
        methods: {}
      }
    }
  },
  mortal: {
    code: "0x606060405260008054600160a060020a03191633179055605c8060226000396000f3606060405260e060020a600035046341c0e1b58114601a575b005b60186000543373ffffffffffffffffffffffffffffffffffffffff90811691161415605a5760005473ffffffffffffffffffffffffffffffffffffffff16ff5b56",
    info: {
      abiDefinition: [{...}, {...}],
      compilerOptions: "--bin --abi --userdoc --devdoc --add-std --optimize -o /tmp/solc163112865",
      compilerVersion: "0.3.1",
      developerDoc: {
        methods: {}
      },
      language: "Solidity",
      languageVersion: "0.3.1",
      source: "contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }",
      userDoc: {
        methods: {}
      }
    }
  }
}
> 

Send the transaction to insert the contract code into the blockchain. You will see that the contract transaction has been successfully mined.

> var _greeting = "Hello World!" 
undefined
> var greeterContract = web3.eth.contract(greeterCompiled.greeter.info.abiDefinition);
undefined
> var greeter = greeterContract.new(_greeting, {from: eth.accounts[0], data: greeterCompiled.greeter.code, gas: 4000000}, 
  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);
      }
    } 
  })
Contract transaction send: TransactionHash: 0x90d201388971770036898a7a22ab252cb0bf3c556f988a7b87583315cdaf58bc waiting to be mined...
undefined
> Contract mined! Address: 0x083628160c1cf218d14f2f0998c7a8dc72aec180
[object Object]

You will see in window #1 the following message that shows the transaction being included into a mined block #352. Your greeter contract is now in the blockchain:

I0409 01:22:16.060791   32675 worker.go:447] 🔨 🔗  Mined 5 blocks back: block #345
I0409 01:22:16.061344   32675 worker.go:569] commit new work on block 351 with 0 txs & 0 uncles. Took 437.176µs
I0409 01:22:17.021781   32675 xeth.go:1026] Tx(0x90d201388971770036898a7a22ab252cb0bf3c556f988a7b87583315cdaf58bc) created: 0x083628160c1cf218d14f2f0998c7a8dc72aec180
I0409 01:22:25.759727   32675 worker.go:348] 🔨  Mined block (#351 / 6d35d834). Wait 5 blocks for confirmation
I0409 01:22:25.763740   32675 worker.go:569] commit new work on block 352 with 1 txs & 0 uncles. Took 3.937696ms
I0409 01:22:25.763820   32675 worker.go:447] 🔨 🔗  Mined 5 blocks back: block #346
I0409 01:22:25.764723   32675 worker.go:569] commit new work on block 352 with 1 txs & 0 uncles. Took 816.878µs
I0409 01:22:27.864884   32675 worker.go:348] 🔨  Mined block (#352 / f44a6a52). Wait 5 blocks for confirmation
I0409 01:22:27.865448   32675 worker.go:569] commit new work on block 353 with 0 txs & 0 uncles. Took 485.587µs

In window #2, call the greeter.greet() method that will extract the message from the blockchain and display it:

> greeter.greet();
"Hello World!"
> 

If you exit from your window #2 geth instance and want to re-run the contract inserted in the steps above, start up the geth instance again (window #2 attach version) and run the following commands. Replace the address at the at(...) function with your contract address:

> var greeter2 = eth.contract([{constant:false,inputs:[],name:'kill',outputs:[],type:'function'},{constant:true,inputs:[],name:'greet',outputs:[{name:'',type:'string'}],type:'function'},{inputs:[{name:'_greeting',type:'string'}],type:'constructor'}]).at('0x083628160c1cf218d14f2f0998c7a8dc72aec180');
undefined
> greeter2
{
  address: "0x083628160c1cf218d14f2f0998c7a8dc72aec180",
  allEvents: function(),
  greet: function(),
  kill: function()
}
> greeter2.greet()
"Hello World!"
> 



EDIT 30/05/2016

If You Are Not Getting The Results Above

  1. Don't worry about setting up Window #2
  2. Run all the commands from the Window #2 sections above beginning with var greeterSource = 'contract mortal { address ow... to greeter2.greet() in Window #1.
  3. If you are not getting the Contract mined! Address: 0x083628160c1... message:

    a. Check that geth is mining successfully. You should see the message 🔨 Mined block (#... in your Window #1.

    b. If you are not getting the 🔨 Mined block (#... message, try running the command miner.start(1). This will start the CPU mining on one thread.

    c. Check your account balance using web3.fromWei(eth.getBalance(eth.accounts[0]).toNumber(), "ether") as you will need some ethers to send the transaction.

    d. If all fails, try setting debug.verbosity(4) and see if you can work out what is happening. You can try 5 or 6 as well, but there will be more message flashing past your screen.