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

0x00 起始

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

0x01 准备工作

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

1、 solc

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

2、web3.js

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

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

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

pragma solidity ^0.4.16;

contract Name {
    string public name;
    
    // 构造函数 合约部署时执行
    function Name(string _name) public {
        name = _name;
    }
    
    // 获取名字
    function getName() view public returns(string) {
        return name;
    }
}

0x03 使用solcjs编译智能合约

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

npm install -g solc

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

# 获得code
solcjs --bin name.sol

# 获的abi
solcjs --abi name.sol

0x04 部署前web3注入

1、引入web3.js

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

nodejs
npm install web3
Browser module
# 项目中直接引入 `web3.min.js`
bower install web3

2、如何使用web3

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

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

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

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

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

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

// 多链节点
https://node.duolian.io/

2018-03-19_2.18.23.png

- 使用MetaMask等浏览器插件

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

web3 = new Web3(web3.currentProvider);
注入web3代码

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

if (typeof web3 !== 'undefined') {
  web3 = new Web3(web3.currentProvider);
} else {
  web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

0x05 通过web3部署合约

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

var _name = /* var of type string here */ ;
var nameContract = web3.eth.contract("使用solcjs编译获得的abi");
var name = nameContract.new(
   _name,
   {
     from: web3.eth.accounts[0], 
     data: '使用solc编译获得的code', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

0x06 最终代码

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

var Web3 = require('web3');
getWeb3 = new Promise(function(resolve) {
    window.addEventListener('load', function() {
        var results;
        var web3 = window.web3;
        if (typeof web3 !== 'undefined') {
            // Use Mist/MetaMask's provider.
            web3 = new Web3(web3.currentProvider);
            results = {
                web3: web3
            };
            console.log('Injected web3 detected.');
            resolve(results);
        } else {
            alert('请安装MetaMask插件并解锁您的以太坊账户');
        }
    })
});
var web3;
getWeb3.then(function(results) {
    web3 = results.web3;
});

// 部署的方法
function deploy()
{
    var _name = "二话区块链" ;
    var nameContract = web3.eth.contract(使用solc编译获得的abi);
    var name = nameContract.new(
        _name,
        {
            from: web3.eth.accounts[0],
            data: '使用solc编译获得的code',
            gas: '288628',
            gasPrice: 4
        }, function (e, contract){
            console.log(e, contract);
            if (e !== 'undefined') {
                if (typeof contract.address !== 'undefined') {
                    console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
                } else {
                    console.log('Contract mined! transactionHash: ' + contract.transactionHash);
                }
            }
        });
}

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

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

qrcode_for_gh_0f12fe5ef5fd_258.jpg


二话区块链
区块链使我快乐。

哈哈哈

2.5k 声望
52 粉丝
0 条评论
推荐阅读
以太坊标准令牌系列之同质化令牌ERC20
众所周知,以太坊在现阶段最大的应用就是令牌发行,而在以太坊中有很多类型的令牌,最著名的当属ERC20了,但是对于其他几种令牌类型,可能还有一些朋友不知道,所以最近规划了一个系列,就是以太坊标准令牌系列。

我才是二亮1阅读 3.4k

WalletConnect钱包落地
DApp 可以让用户更加自由地管理他们的资产,同时也让开发者更加容易地构建去中心化应用。然而,DApp 在与区块链交互时,往往需要使用钱包进行支付、签名等操作,这就需要 DApp 和钱包之间进行通信。

米花儿团儿1阅读 690

参照Metamask,钱包端实现简易的Dapp浏览器
以react-native@0.71.7环境为例,开发Android应用。MetaMask一键登录示例Demo {代码...} Demo演示流程分析:借助react-native-webview加载Dapp Web;绑定webviewRef实例,便于后续通信;在injectedJavaScriptBefor...

米花儿团儿阅读 652

Hyperledger Fabric 使用 CouchDB 和复杂智能合约开发
在上个实验中,我们已经实现了简单智能合约实现及客户端开发,但该实验中智能合约只有基础的增删改查功能,且其中的数据管理功能与传统 MySQL 比相差甚远。本文将在前面实验的基础上,将 Hyperledger Fabric 的默...

风色幻想阅读 642

智能合约安全之整型溢出
整型溢出是智能合约中常见的漏洞之一。以太坊虚拟机对整数使用固定大小的数据类型,一个整数变量仅能表示一个固定范围的数值,比如uint8类型只能保存[0, 255]。当把超过某个数据类型范围的数值保存到这个变量时,...

悖论阅读 580

封面图
零知识证明:应用和具体用例
零知识证明(Zero-Knowledge Proofs,ZKPs)是应用密码学中令人兴奋的突破,将在各个行业中解锁新的用例,从 Web3 到供应链再到物联网。通过在不揭示信息的情况下验证其真实性,ZKPs 可以增强数字系统的隐私、安...

Chainlink阅读 579

智能合约安全之重入攻击
重入攻击(Reentrancy Attack)是一种常见的智能合约安全漏洞,指黑客利用合约中存在的逻辑漏洞,在调用合约函数时,利用合约逻辑漏洞,反复调用合约的函数,并利用这种递归调用的机制,以欺骗合约的计算,从而使...

悖论阅读 567

封面图

哈哈哈

2.5k 声望
52 粉丝
宣传栏