• 以太坊私有链下智能合约部署


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

    一、 编写合约

    简单的乘法例子:

    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
  • 相关阅读:
    WCF 第四章 绑定 在多个绑定上暴露一个服务契约
    WCF 第五章 行为 事务跨操作事务流
    WCF 第五章 导出并发布元数据(服务行为)
    WCF 第五章 行为 通过配置文件暴露一个服务行为
    WCF 第五章 不支持会话的绑定的默认并发和实例
    WCF 第五章 并发和实例(服务行为)
    WCF 第五章 行为 总结
    WCF 第四章 绑定 绑定元素
    WCF 第五章 行为 事务之选择一个事务协议OleTx 或者WSAT
    WCF 第四章 绑定 比较各种绑定的性能和可扩展性
  • 原文地址:https://www.cnblogs.com/beyang/p/8469311.html
Copyright © 2020-2023  润新知