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

待补充。
很多朋友照着教程部署合约会遇到一些问题,我觉得主要是在获取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网页编译
EVM code和ABI
上图中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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值