以太坊开发(十九)使用Geth建立私链 ,编译以及部署合约

创建一个文件夹来存储你的私链数据

yuyangdeMacBook-Pro:~ yuyang$ mkdir privatechain
yuyangdeMacBook-Pro:~ yuyang$ cd privatechain

使用geth开启

yuyangdeMacBook-Pro:privatechain yuyang$ geth --networkid 123 --dev --datadir data1

如果你切换到data1文件夹里面,你会看到geth, geth.ipc, 和 keystore

yuyangdeMacBook-Pro:data1 yuyang$ ls
geth        geth.ipc    keystore

保持节点的运行,不要关闭终端,重新打开一个终端,使用geth attach连接节点,并且打开geth console

yuyangdeMacBook-Pro:~ yuyang$ geth attach ipc:/Users/yuyang/privatechain/data1/geth.ipc 
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.1-stable/darwin-amd64/go1.10
coinbase: 0x12c7be0d310a9851317b4cd8b976cf33d5456bf1
at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
 datadir: /Users/yuyang/privatechain/data1
 modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0

准备智能合约代码,字节码,ABI

pragma solidity ^0.4.4;

contract test { 
    
    function multiply(uint a) returns(uint d){
        
        return a * 7;
    }
}

代码拷贝到https://remix.ethereum.org,编译,然后拷贝字节码和ABI(编译后点击Publish on Swarm,然后点击 Details,字节码和ABI都在其中)。

  • 字节码
6060604052341561000f57600080fd5b60b18061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006007820290509190505600a165627a7a723058208b4b34b5adf7ee471715fd019a96a400495b0aa026580c670af16bb6eee1f2290029
  • ABI
[
    {
        "constant": false,
        "inputs": [
            {
                "name": "a",
                "type": "uint256"
            }
        ],
        "name": "multiply",
        "outputs": [
            {
                "name": "d",
                "type": "uint256"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    }
]

在bejson中转义成字符串
http://www.bejson.com/jsonviewernew/

[{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"multiply\",\"outputs\":[{\"name\":\"d\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]

通过abi创建合约对象

> var abi = JSON.parse('[{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"multiply\",\"outputs\":[{\"name\":\"d\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]')
undefined
> myContract = web3.eth.contract(abi)
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }],
  eth: {
    accounts: ["0x12c7be0d310a9851317b4cd8b976cf33d5456bf1"],
    blockNumber: 0,
    coinbase: "0x12c7be0d310a9851317b4cd8b976cf33d5456bf1",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 1,
    hashrate: 0,
    mining: true,
    pendingTransactions: [],
    protocolVersion: "0x3f",
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(options, callback, filterCreationErrorCallback),
    getAccounts: function(callback),
    getBalance: function(),
    getBlock: function(),
    getBlockNumber: function(callback),
    getBlockTransactionCount: function(),
    getBlockUncleCount: function(),
    getCode: function(),
    getCoinbase: function(callback),
    getCompilers: function(),
    getGasPrice: function(callback),
    getHashrate: function(callback),
    getMining: function(callback),
    getPendingTransactions: function(callback),
    getProtocolVersion: function(callback),
    getRawTransaction: function(),
    getRawTransactionFromBlock: function(),
    getStorageAt: function(),
    getSyncing: function(callback),
    getTransaction: function(),
    getTransactionCount: function(),
    getTransactionFromBlock: function(),
    getTransactionReceipt: function(),
    getUncle: function(),
    getWork: function(),
    iban: function(iban),
    icapNamereg: function(),
    isSyncing: function(callback),
    namereg: function(),
    resend: function(),
    sendIBANTransaction: function(),
    sendRawTransaction: function(),
    sendTransaction: function(),
    sign: function(),
    signTransaction: function(),
    submitTransaction: function(),
    submitWork: function()
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}

预估手续费

> bytecode = "0x6060604052341561000f57600080fd5b60b18061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006007820290509190505600a165627a7a723058208b4b34b5adf7ee471715fd019a96a400495b0aa026580c670af16bb6eee1f2290029"
"0x6060604052341561000f57600080fd5b60b18061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006007820290509190505600a165627a7a723058208b4b34b5adf7ee471715fd019a96a400495b0aa026580c670af16bb6eee1f2290029"
> web3.eth.estimateGas({data: bytecode})
99866

备注:字节码前面需要添加0x。手续费大概为99866gas。

部署合约

创建一个账号

> personal.newAccount('123456') 
"0xb12334742271e17c50d49cf04a2bccc0bd693b7b"

查看余额

> web3.eth.getBalance("0xb12334742271e17c50d49cf04a2bccc0bd693b7b")
0

查看该账号是否是矿工账号

> web3.eth.coinbase
"0x12c7be0d310a9851317b4cd8b976cf33d5456bf1"

发现不是,将我们新建的账号设置为挖矿账号

> miner.setEtherbase(eth.accounts[1])
true
> eth.coinbase 
"0xb12334742271e17c50d49cf04a2bccc0bd693b7b"

开启挖矿,以便可以支付部署费用

> miner.start()

或者直接从另一个账号转账

> eth.sendTransaction({from:"0x12c7be0d310a9851317b4cd8b976cf33d5456bf1",to:"0xb12334742271e17c50d49cf04a2bccc0bd693b7b",value:web3.toWei(3,"ether")})
"0x489e219ef97ae1fda3e1ff0f17774c655f6dac88cf5c27e615c0aceceddebf27"
> web3.eth.getBalance("0xb12334742271e17c50d49cf04a2bccc0bd693b7b")
3000000000000000000

解锁账号

> personal.unlockAccount("0xb12334742271e17c50d49cf04a2bccc0bd693b7b", '123456') 
true

部署合约,为了方便理解,设置一个回调函数

> contractInstance = myContract.new({data: bytecode, gas: 1000000, from: "0xb12334742271e17c50d49cf04a2bccc0bd693b7b"}, function(e, contract){
......   if(!e){
.........     if(!contract.address){
............       console.log("Contract transaction send: Transaction Hash: "+contract.transactionHash+" waiting to be mined...");
............     }else{
............       console.log("Contract mined! Address: "+contract.address);
............       console.log(contract);
............     }
.........   }else{
.........     console.log(e)
.........   }
...... })
Contract transaction send: Transaction Hash: 0x8b38f4a3f2c3829b179b3b9c2a69e82deccf56b03d5af17e9f2c781bc0dd7587 waiting to be mined...
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }],
  address: undefined,
  transactionHash: "0x8b38f4a3f2c3829b179b3b9c2a69e82deccf56b03d5af17e9f2c781bc0dd7587"
}

挖矿以便写入区块:

> miner.start()
null
> Contract mined! Address: 0x9eeda351114088044715e6e4c0e09e02e97d26b3
[object Object]

查看是否部署成功:

> eth.getCode(contractInstance.address)
"0x606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60006007820290509190505600a165627a7a723058208b4b34b5adf7ee471715fd019a96a400495b0aa026580c670af16bb6eee1f2290029"

调用合约方法:

> contractInstance.multiply(6)
42
> 

参考:以太坊(Ethereum)私链建立 、合约编译、部署完全教程(1)
作者:黎跃春

你可能感兴趣的:(以太坊开发(十九)使用Geth建立私链 ,编译以及部署合约)