如何使用web3部署以太坊智能合约

5,039 阅读5分钟

0x00 起始

大多数人在初学智能合约开发的时候,都是选择使用 remix进行合约的开发以及部署。  remix是集  Solidity的编辑器,编译器,部署于一身的集成开发工具,非常方便,也非常好用。之前一直使用  Remix或者  truffle,最近使用  web3进行智能合约的部署,分享下。

0x01 准备工作

在使用 web3进行合约的部署,一般需要使用准备以下几个库:

1、 solc

solc 是以太坊官方出的一款Solidity语言开发的智能合约的编译工具,可以通过  solc 获得部署合约时所要使用的  bytecode 和  abi

2、web3.js

web3.js是以太坊官方实现的一个使用  javascript与以太坊客户端进行交互的js库,  web3 .js可以与任何暴露RPC层的以太坊节点协同工作。

0x02 使用solidity编写智能合约代码

本文主要讨论web3的智能合约部署,不涉及solidity语言的讨论,所以我们使用一个非常简单的智能合约来学习下面的部署,将自己的名字写入区块链中:

  1. pragma solidity ^0.4.16;

  2. contract Name {

  3.    string public name;

  4.    // 构造函数 合约部署时执行

  5.    function Name(string _name) public {

  6.        name = _name;

  7.    }

  8.    // 获取名字

  9.    function getName() view public returns(string) {

  10.        return name;

  11.    }

  12. }

0x03 使用solcjs编译智能合约

如果想要使用web3来部署合约,需要先获得合约的bytecode以及合约的abi,而编译可以使用solcjs进行。

  1. npm install -g solc

安装成功后,我们可以通过命令行编译代码,获得code以及abi。

  1. # 获得code

  2. solcjs --bin name.sol

  3. # 获的abi

  4. solcjs --abi name.sol

0x04 部署前web3注入

1、引入web3.js

引入 web3.js有两种方法,一种使用nodejs,一种直接使用浏览器引擎。

nodejs
  1. npm install web3

Browser module
  1. # 项目中直接引入 `web3.min.js`

  2. bower install web3

2、如何使用web3

其实 web3就是对以太坊的  json -rpc接口使用  javascript进行了一次封装,既然是  rpc,我们在使用时,必须连接一个服务器,也就是以太坊的支持  json -rpc的节点。在这里,我们一般把连接  json -rpc节点称为注入以太坊节点。注入节点有两种方式。

- 注入自有节点或者开放节点

这种方式的注入,我们需要搭建一个自己的节点,通过自己的节点与以太坊网络进行交互,代码如下:

  1. web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

其中的 http://localhost:8545就是你自己的节点的地址,但是因为以太坊全节点的数据量越来越大导致同步一个全节点数据需要非常长的时间以及很大的硬盘容量,这对于普通用户是非常头疼的。

目前有一些开放的提供全节点和测试网络节点的服务商,其实比较好用,可以避免自己去同步整个以太坊网络,而只需要专心去开发自己的应用即可,提供一个节点服务。多链科技旗下的多链节点就是提供这个服务的。

  1. // 多链节点

  2. https://node.duolian.io/

- 使用MetaMask等浏览器插件

MetaMask是一个以太坊钱包的浏览器插件,该插件提供自己的web3实例,当用户在浏览器中安装了MetaMask,MetaMask会自动注入一段js,然后将自己的web3实例注入到了浏览器中,所以可以直接使用该web3实例。代码如下:

  1. web3 = new Web3(web3.currentProvider);

注入web3代码

当浏览器中已经拥有了web3实例,那么我们就直接使用已存在的实例,如果不存在,再去连接我们自己的web3实例。

  1. if (typeof web3 !== 'undefined') {

  2.  web3 = new Web3(web3.currentProvider);

  3. } else {

  4.  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

  5. }

0x05 通过web3部署合约

通过solcjs获取了合约的code以及abi,浏览器中也成功注入了web3,此时我们只需要通过web3去进行合约的部署了。

  1. var _name = /* var of type string here */ ;

  2. var nameContract = web3.eth.contract("使用solcjs编译获得的abi");

  3. var name = nameContract.new(

  4.   _name,

  5.   {

  6.     from: web3.eth.accounts[0],

  7.     data: '使用solc编译获得的code',

  8.     gas: '4700000'

  9.   }, function (e, contract){

  10.    console.log(e, contract);

  11.    if (typeof contract.address !== 'undefined') {

  12.         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);

  13.    }

  14. })

0x06 最终代码

因为本文在部署时,使用MetaMask的web3实例,因为MetaMask的web3不支持同步调用,所以在实例化web3时,代码有所区别,相关js代码如下:

  1. var Web3 = require('web3');

  2. getWeb3 = new Promise(function(resolve) {

  3.    window.addEventListener('load', function() {

  4.        var results;

  5.        var web3 = window.web3;

  6.        if (typeof web3 !== 'undefined') {

  7.            // Use Mist/MetaMask's provider.

  8.            web3 = new Web3(web3.currentProvider);

  9.            results = {

  10.                web3: web3

  11.            };

  12.            console.log('Injected web3 detected.');

  13.            resolve(results);

  14.        } else {

  15.            alert('请安装MetaMask插件并解锁您的以太坊账户');

  16.        }

  17.    })

  18. });

  19. var web3;

  20. getWeb3.then(function(results) {

  21.    web3 = results.web3;

  22. });

  23. // 部署的方法

  24. function deploy()

  25. {

  26.    var _name = "二话区块链" ;

  27.    var nameContract = web3.eth.contract(使用solc编译获得的abi);

  28.    var name = nameContract.new(

  29.        _name,

  30.        {

  31.            from: web3.eth.accounts[0],

  32.            data: '使用solc编译获得的code',

  33.            gas: '288628',

  34.            gasPrice: 4

  35.        }, function (e, contract){

  36.            console.log(e, contract);

  37.            if (e !== 'undefined') {

  38.                if (typeof contract.address !== 'undefined') {

  39.                    console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);

  40.                } else {

  41.                    console.log('Contract mined! transactionHash: ' + contract.transactionHash);

  42.                }

  43.            }

  44.        });

  45. }

谢谢大家的支持,如果觉得不错,欢迎转发~

如果喜欢,别说话,扫我~