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语言的讨论,所以我们使用一个非常简单的智能合约来学习下面的部署,将自己的名字写入区块链中:
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/
- 使用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);
}
}
});
}
谢谢大家的支持,如果觉得不错,欢迎转发~
如果喜欢,别说话,扫我~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。