zoukankan      html  css  js  c++  java
  • nodejs部署智能合约的方法-web3 0.20版本

    参考:https://www.jianshu.com/p/7e541cd67be2

    部署智能合约的方法有很多,比如使用truffle框架,使用remix-ide等,在这里的部署方法是使用nodejs一步步编译部署实现的:

    const Web3 = require('web3');
    const web3 = new Web3();//使用web3来进行区块链接口的调用
    
    //通过rpc连接区块链,这里连接的是本地私有链
    web3.setProvider(new Web3.providers.HttpProvider(‘http://127.0.0.1:7545'));
    const fs = require("fs");
    const solc = require("solc");
    let source = fs.readFileSync(“token.sol",'utf8');//读取sol智能合约文件
    //对智能合约进行编译,第二个参数设置为1可以激活优化器optimiser
    let compiledContract = solc.compile(source,1);
    
    for (let contractName in compiledContract.contracts) {
        var bytecode = compiledContract.contracts[contractName].bytecode;//获得编译后合约的bytecode
        var abi = JSON.parse(compiledContract.contracts[contractName].interface); //获得编译后合约的abi并写成json形式
    }
    
    let gasEstimate = web3.eth.estimateGas({data:’0x’+bytecode});//获得这个合约部署大概所需的gas
    let MyContract = web3.eth.contract(abi);

    //上面是编译生成了Abi的方法,之后就有两种进行使用的情况:
    (1)
    //当从来没有部署过时,这里的gas例子上是gas:gasEstimate,但是我发现有些时候好像过小而不能成功,所以我每次为了保证能够绝对地成功,都设为一个很大的数,反正用不完会返回来的,你也可以设置为gas:gasEstimate,但是如果后面有发现有错误,很有可能是这里的问题

        var instance = MyContract.new(50,{from:user1,data:'0x'+bytecode,gas:47000000},function(e,contract){
                 if(typeof contract.address !== 'undefined'){
                    console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
                }
        });


    然后后面就可以使用instance来调用智能合约中的函数等信息了

    (2)

    //当已经在私有链上部署过时,里面的地址即为上面的方法得到的contract.address

    let instance = MyContract.at('0x86757c9bdea10815e7d75a1577b6d9d2825dae0a');//可改

    不过这种方式有一个问题,就是在发布合约时,你的私钥处于联网状态,
    处于安全策略,我们需要尽量避免私钥在联网状态。

    以太坊上部署合约是向空地址发送一个附有字节码的签名交易,其中发送者就是这个合约的拥有者。

    因此我们只需要将合约构建成一笔交易,我们在无网状态下对这笔交易进行签名,然后将签名发送到以太坊网络中。这样能够降低我们私钥被泄漏的风险。
    在这里要使用方法进行合约部署,参考:https://my.oschina.net/u/3794778/blog/1801897

    web3.eth.sendRawTransaction(signedTransactionData [, callback])
    
    参数:
    
        signedTransacionData: String - 16进制格式的签名交易数据。
        callback: Function - 回调函数,用于支持异步的方式执行7。
    
    返回值:
    
        String - 32字节的16进制格式的交易哈希串。
    
    示例:
    
    var Tx = require('ethereumjs-tx');//ethereumjs-tx 提供了私钥到公钥的转换方法
    //你自己的私钥
    var privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex'); //构造的交易中,是不需要包含 from 的,因为这个交易是通过私钥签名的,而私钥生成的签名是可以还原出公钥地址的,所以交易本身不需要冗余存储发送方信息。 var rawTx = {
    //这个字段需要取你的发送账号所发起的交易的计数器,可以通过 eth_getTransactionCount 来获取当前的 nonce,直接用,不用加1 nonce:
    '0x00', gasPrice: '0x09184e72a000', gasLimit: '0x2710', to: '0x0000000000000000000000000000000000000000', //to到空地址 value: '0x00', //可以省略 data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057'//就是之前生成的'0x'+bytecode } var tx = new Tx(rawTx); tx.sign(privateKey); var serializedTx = tx.serialize();
    //这里得到的值就是需要的16进制格式的签名交易数据
    //console.log(serializedTx.toString('hex')); //0xf889808609184e72a00082271094000000000000000000000000000000000000000080a47f74657374320000000000000000000000000000000000000000000000000000006000571ca08a8bbf888cfa37bbf0bb965423625641fc956967b81d12e23709cead01446075a01ce999b56a8a88504be365442ea61239198e23d1fce7d00fcfc5cd3b44b7215f web3.eth.sendRawTransaction(serializedTx.toString('hex'), function(err, hash) { if (!err) console.log(hash); // "0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385"这里得到的就是交易成功返回的交易hash });

    最后,生成的字节码可以直接到第三方,比如 https://etherscan.io/pushTx 来广播你的交易,如果广播失败,可以直接看到错误提示信息

    下面这个网址是对etherscan这个工具的解释解释得很好,可以看看
    http://8btc.com/thread-75748-1-7.html



  • 相关阅读:
    DDL、DML和DCL的区别与理解
    oracle中游标详细用法
    委托与事件
    c#中的引用类型和值类型
    DevExpress控件给数据列表中特殊行数据设置颜色
    windows下redis的安装
    python操作数据库
    python操作excel
    iMessage, Facetime 解决办法
    iOS 静态库,动态库与 Framework
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/9505886.html
Copyright © 2011-2022 走看看