美文网首页
使用Nodejs部署智能合约

使用Nodejs部署智能合约

作者: wade_van | 来源:发表于2017-07-18 11:30 被阅读2093次

    使用nodejs部署智能合约

    实现智能合约的方式很多种,可以用truffle框架来实现,编译,部署。
    这里介绍一种简单的使用nodejs来实现,编译,部署的方法。
    创建一个nodejs项目,实现一个简单的智能合约。

    mkdir sm && cd sm
    npm init
    mkdir contracts && cd contracts
    vi BaseToken.sol
    
    //BaseToken.sol
    contract Token{
        address public owner;
        mapping (address => uint) public balances;
        event Sent(address from, address to, uint amount)
        function Token(){
            owner = msg.sender;
            balances[owner] = 100000000;
        }
        function send(address receiver, uint amount){
            if (balances[msg.sender] < amount) return;
            balances[msg.sender] -= amount;
            balances[receiver] += amount;
            Sent(msg.sender, receiver, amount);
        }
    }
    

    这个合约实现了一个造币和转币的逻辑。
    我们的合约是运行在evm上面的字节码,solidity是静态语言,需要通过编译器生成evm的字节码。

    
    vi compile.js
    
    // compile.js
    const fs = require('fs')
    const solc = require('solc')
    //编译合约
    let source = fs.readFileSync("./contracts/BaseToken.sol", 'utf8')
    console.log('compiling contract...');
    let compiledContract = solc.compile(source);
    console.log('done');
    
    for (let contractName in compiledContract.contracts) {
        var bytecode = compiledContract.contracts[contractName].bytecode;
        var abi = JSON.parse(compiledContract.contracts[contractName].interface);
    }
    console.log(bytecode)
    
    

    调用node compile.js,对BaseToken进行编译,生成字节码。web3中提供了一个部署合约的接口,使用如下,

    let gasEstimate = web3.eth.estimateGas({data: '0x' + bytecode});
    console.log('gasEstimate: ' + gasEstimate)
    
    
    let MyContract = web3.eth.contract(abi);
    
    console.log('deploying contract...');
    
    
    let myContractReturned = MyContract.new([], {
      from: address,
      data: '0x' + bytecode,
      gas: gasEstimate+50000
    }, function(err, myContract){
      if(!err){
        if(!myContract.address){
          console.log(`myContract.transactionHash = ${myContract.transactionHash}`);
        }else{
          console.log(`myContract.address = ${myContract.address}`); // the contract address
          global.contractAddress = myContract.address;
        }
    }else{
        console.log(err);
    }
    });
    

    利用编译生成的abi和bytecode,创建一个合约对象,然后进行发布,等待着异步执行的方法输出合约地址contractAddress,这样就完成了部署。不过这种方式有一个问题,就是在发布合约时,你的私钥处于联网状态,
    处于安全策略,我们需要尽量避免私钥在联网状态。

    以太坊上部署合约是向空地址发送一个附有字节码的签名交易,其中发送者就是这个合约的拥有者。因此我们只需要将合约构建成一笔交易,我们在无网状态下对这笔交易进行签名,然后将签名发送到以太坊网络中。这样能够降低我们私钥被泄漏的风险。
    对合约的签名方法如下:

    var Tx = require('ethereumjs-tx')
    const rawTx = {
        nonce: '0x6', //这个是你的地址的交易次数+1,0开始
        gasPrice: '0x12a05f200',
        gasLimit: '0x493e0',
        data: bytecode,
        from: address,
        to: ""
    };
    const tx = new Tx(rawTx);
    tx.sign(privateKey);
    const serializedTx = tx.serialize();
    console.log(serializedTx.toString('hex'))
    

    以上对一个合约签名,这里需要注意的问题是,to的地址需要是,空地址。
    完成签名之后,我们把这笔交易发送出去就好,最简单的方法就是使用etherscan的发送Tx的方式,一旦发送完成,部署完成,就可以看到合约地址。

    相关文章

      网友评论

          本文标题:使用Nodejs部署智能合约

          本文链接:https://www.haomeiwen.com/subject/vqnckxtx.html