zoukankan      html  css  js  c++  java
  • 以太坊私有链下智能合约部署

    上一篇文章实现了搭建私有链,以下进行智能合约的部署

    一、 编写合约

    简单的乘法例子:

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

    二、 编译合约

    推荐网站:here

    得到:Interface 和 Bytecode 和 Web3 deploy

    Bytecode: 6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a723058206f9974e7f2c8329cbc09530d06d001018bfeca369c7cd8f9d565298adbdd2a9c0029
    
    Interface: [{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]
    
    Web3 deploy:
    var browser_ballot_sol_testContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]);
    var browser_ballot_sol_test = browser_ballot_sol_testContract.new(
       {
         from: web3.eth.accounts[0], 
         data: '0x6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a723058206f9974e7f2c8329cbc09530d06d001018bfeca369c7cd8f9d565298adbdd2a9c0029', 
         gas: '4300000'
       }, function (e, contract){
        console.log(e, contract);
        if (typeof contract.address !== 'undefined') {
             console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
        }
     })
    

    三、 部署合约

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

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

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

    //创建账户
    personal.newAccount('密码')
    
    //挖矿,获得ether
    miner.start()
    miner.stop()
    
    //账户解锁
    personal.unlockAccount("第一个账户地址", "密码")

    第一步: 获取abi信息,即上述编译得到的interface

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

    得到结果:

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

    第二步:

    multiplyContract = web3.eth.contract(abi)

    得到结果:

    {
      abi: [{
          constant: false,
          inputs: [{...}],
          name: "multiply",
          outputs: [{...}],
          payable: false,
          stateMutability: "nonpayable",
          type: "function"
      }],
      eth: {
        accounts: ["0xbe98c12f918275591c9a43ec3c7bc44cfca50d2f"],
        blockNumber: 7,
        coinbase: "0xbe98c12f918275591c9a43ec3c7bc44cfca50d2f",
        compile: {
          lll: function(),
          serpent: function(),
          solidity: function()
        },
        defaultAccount: undefined,
        defaultBlock: "latest",
        gasPrice: 18000000000,
        hashrate: 0,
        mining: false,
        pendingTransactions: [],
        protocolVersion: "0x3f",
        syncing: false,
        call: function(),
        ... (一堆function)
    }

    第三步: 复制 Web3 deploy 到命令行

    multiply = multiplyContract.new(
       {
         from: web3.eth.accounts[0], 
         data: '0x6060604052341561000f57600080fd5b5b60ab8061001e6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa114603d575b600080fd5b3415604757600080fd5b605b60048080359060200190919050506071565b6040518082815260200191505060405180910390f35b60006007820290505b9190505600a165627a7a723058206f9974e7f2c8329cbc09530d06d001018bfeca369c7cd8f9d565298adbdd2a9c0029', 
         gas: '4300000'  //改为300000
       }, function (e, contract){
        console.log(e, contract);
        if (typeof contract.address !== 'undefined') {
             console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
        }
     })

    得到结果

    {
      abi: [{
          constant: false,
          inputs: [{...}],
          name: "multiply",
          outputs: [{...}],
          payable: false,
          stateMutability: "nonpayable",
          type: "function"
      }],
      address: undefined,
      transactionHash: "0x87400471a0e32edcfa9e1ca621d08a318e9abb85299d280deb8bc199e118427f"
    }

    ==> 在这一步,可能你会得到一条错误信息:

    invalid sender undefined
    

    解决方法: 在genesis.json文件中,chainId 不能设置为0。 如果你完全按照github上给的官方配置文件,就会产生这个错误

    ==> 在这一步,可能你会得到一条错误信息:

    Error: authentication needed: password or unlock undefined
    

    解决方法:先解锁账户啦

    personal.unlockAccount("第一个账户地址", "密码")
    

    ==> 在这一步,可能你还会遇到这个问题:

    Error: exceeds block gas limit undefined
    The contract code couldn't be stored, please check your gas amount. undefined
    

    解决方法:把gas改为300000。直接从那个网站的Web3 deploy 复制可能是4300000,然后改成300000,就没问题了。

    猜测原因:

    eth.getBlock("pending").gasLimit
    web3.eth.estimateGas({data: bytecode})
    
    可以先输入这两条来预判一下范围,取中间值。
    

    第四步:然后我们需要挖矿确认

    miner.start()
    
    等待一会,你会得到一条信息:
    Contract mined! address: 0xdb385bc97ed9fbac62920102d5edc7c4bf993c79 transactionHash: 0x87400471a0e32edcfa9e1ca621d08a318e9abb85299d280deb8bc199e118427f
    ==> 就代表部署成功啦。
    
    miner.stop()

    四、合约交互

    第一步:获取合约对象

    MyContract = eth.contract(abi)

    得到结果:

    {
      abi: [{
          constant: false,
          inputs: [{...}],
          name: "multiply",
          outputs: [{...}],
          payable: false,
          stateMutability: "nonpayable",
          type: "function"
      }],
      eth: {
        accounts: ["0xd88ad6d115ed640b69f01e24ff1433f75d5c8f87"],
        blockNumber: 4,
        coinbase: "0xd88ad6d115ed640b69f01e24ff1433f75d5c8f87",
        compile: {
          lll: function(),
          serpent: function(),
          solidity: function()
        },
        defaultAccount: undefined,
        defaultBlock: "latest",
        gasPrice: 18000000000,
        hashrate: 612,
        mining: false,
        pendingTransactions: [],
    
        ...(一堆function)
    }
    

    第二步:实例化合约

    myContract = MyContract.at(multiply.address)

    得到结果:

    {
      abi: [{
          constant: false,
          inputs: [{...}],
          name: "multiply",
          outputs: [{...}],
          payable: false,
          stateMutability: "nonpayable",
          type: "function"
      }],
      address: "0xdb385bc97ed9fbac62920102d5edc7c4bf993c79",
      transactionHash: null,
      allEvents: function(),
      multiply: function()
    }

    第三步:调用合约

    myContract.multiply.call(5)

    得到结果:

    35

    五、在电脑B调用该合约

    确定两台电脑已成功连接。电脑B上新建账户,并解锁。

    1. abi = [{constant:false,inputs:[{name:'a',type:'uint256'}],name:'multiply',outputs:[{name:'d',type:'uint256'}],type:'function'}]  //合约的abi
    2. address = 0xdb385bc97ed9fbac62920102d5edc7c4bf993c79  // 合约地址
    3. myContract = web3.eth.contract(abi).at(address)
    
    ==> 然后就可以调用使用了 myContract.multiply.call(5)
    得到结果:35
  • 相关阅读:
    DP——背包问题(三)
    堆——练习题
    DP——背包问题(二)
    二叉树的后序遍历(暴力版) 小白菜oj 1034
    树状数组2模板 Luogu 3368
    树状数组1模板 Luogu 3374
    DP——最长上升子序列(n^2与n log n)
    线段树(区间修改)模板题 Luogu 2357 守墓人
    c语言学习摘录
    python 学习摘录
  • 原文地址:https://www.cnblogs.com/beyang/p/8469311.html
Copyright © 2011-2022 走看看