以太坊私有链环境下智能合约部署流程

待补充。
很多朋友照着教程部署合约会遇到一些问题,我觉得主要是在获取abi这一步。

var Multiply7 = eth.contract(contract.info.abiDefinition);

所以这里记录一下用browser-solidity编译。

一、初始化私有链

首先需要准备一个创世区块信息用于初始化私有链,其中difficulty为挖矿难度,建议设置低一点方便挖矿测试,保存为init.json。

{
    "nonce": "0×0000000000000042",
    "mixhash": "0×0000000000000000000000000000000000000000000000000000000000000000",
    "difficulty": "0×20000",
    "alloc": {},
    "coinbase": "0×0000000000000000000000000000000000000000",
    "timestamp": "0×00",
    "parentHash": "0×0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "blossom",
    "gasLimit": "0xffffffff" }

进入终端,创建私有链。命令中--datadir后的参数根据你放置init.json的路径自行更改。

geth  --datadir "/home/swb/test" init init.json

进入私有链console。--identity--datadir需要根据你的需要而定。

geth --identity "blossom" --rpc --rpccorsdomain "*" --datadir "/home/swb/test" --port 30303 --rpcapi "db,eth,net,web3" --networkid 123456 console 2>> /home/swb/test/geth.log

二、码合约

这一步不多说,具体的合约代码自己编写。以下是Solidity的官方文档:链接
本文以一个简单的加法合约为例介绍部署步骤。
还可以参考wiki中给的教程案例:Contracts and Transactions

pragma solidity ^0.4.0;
contract test {
   /// @notice Will multiply `a` by 7.
   function multiply(uint a) returns(uint d) {
       return a * 7;
   }
}

三,编译合约

如前文中提到的,想要部署合约需要得到合约代码的ABI和EVM code。很多朋友看教程是在geth控制台里编译合约的,但是有一个问题是:

MyContract = eth.contract(contract.info.abiDefinition)

无法获得contract的abi。导致接下来的步骤出错。所以这里推荐使用browser-solidity网页编译。
以太坊私有链环境下智能合约部署流程_第1张图片
上图中Bytecode和interface就是我们需要的结果。

四、部署合约

在部署合约前,我们要明确需要以下几项条件:

  1. 一个有Ether的账户;
  2. 该账户已解锁;
  3. 编译合约得到的abi和code。

所以首先需要做以下工作:

//创建账户
personal.newAccount('密码')
//挖矿获取Ether。其中miner.start(4)应该是CPU数,admin.sleepBlock()可以指定挖的区块数
miner.start(4);admin.sleepBlocks(10);miner.stop();
//账户解锁
personal.unlockAccount(eth.coinbase,'密码',10000)

之后可以进行部署了。

//获取abi信息,即上述编译得到的interface
> abi = [{constant:false,inputs:[{name:'a',type:'uint256'}],name:'multiply',outputs:[{name:'d',type:'uint256'}],type:'function'}]

[{
    constant: false,
    inputs: [{
        name: "a",
        type: "uint256"
    }],
    name: "multiply",
    outputs: [{
        name: "d",
        type: "uint256"
    }],
    type: "function"
}]
//创建合约。
> multiplyContract = web3.eth.contract(abi)
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      type: "function"
  }],
  eth: {
    accounts: ["0xae5a780f8d162b7687869f9f6d4bdbda5056832d"],
    blockNumber: 10,
    coinbase: "0xae5a780f8d162b7687869f9f6d4bdbda5056832d",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 20000000000,
    hashrate: 0,
    mining: false,
    pendingTransactions: [],
    protocolVersion: "0x3f",
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(fil, callback),
    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()
}
//解锁账户
> personal.unlockAccount(eth.coinbase, '111', 10000)
true
//部署合约。data为上述编译得到的Bytecode
> multiply = multiplyContract.new({from: eth.coinbase, data: "0x60606040523415600b57fe5b5b60788061001a6000396000f300606060405263ffffffff60e060020a600035041663c6888fa181146020575bfe5b3415602757fe5b60306004356042565b60408051918252519081900360200190f35b600781025b9190505600a165627a7a7230582007a6259ba3d57941abda2e261e9a67958a3eda78b779d9dd8d42518791fddd590029"})
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      type: "function"
  }],
  address: undefined,
  transactionHash: "0x2c61f267d9578d312dd0b0455db97ff615bb0c052c2b0f7ca3ea5946d57e210b"
}
//我们知道部署合约的过程实际也是由创建合约的账户发送的一笔交易(即eth.coinbase账户)。需要挖矿进行确认。
> miner.start(4);admin.sleepBlocks(2);miner.stop();
true

至此合约已经存在于区块链中,可以查看区块信息获取合约的地址和交易hash。

五、与合约交互

//获取合约对象
> MyContract = eth.contract(abi)
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      type: "function"
  }],
  eth: {
    accounts: ["0xae5a780f8d162b7687869f9f6d4bdbda5056832d"],
    blockNumber: 15,
    coinbase: "0xae5a780f8d162b7687869f9f6d4bdbda5056832d",
    compile: {
      lll: function(),
      serpent: function(),
      solidity: function()
    },
    defaultAccount: undefined,
    defaultBlock: "latest",
    gasPrice: 20000000000,
    hashrate: 0,
    mining: false,
    pendingTransactions: [],
    protocolVersion: "0x3f",
    syncing: false,
    call: function(),
    contract: function(abi),
    estimateGas: function(),
    filter: function(fil, callback),
    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()
}

//实例化合约
> myContract = MyContract.at(multiply.address)
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "multiply",
      outputs: [{...}],
      type: "function"
  }],
  address: "0xe6c436f2964bd57692a7c3929e5451916a491401",
  transactionHash: null,
  allEvents: function(),
  multiply: function()
}

//调用合约
> myContract.multiply.call(5)
35

你可能感兴趣的:(以太坊)