0x00 起始
大多数人在初学智能合约开发的时候, 都是选择使用 remix 进行合约的开发以及部署 remix 是集 Solidity 的编辑器, 编译器, 部署于一身的集成开发工具, 非常方便, 也非常好用之前一直使用 Remix 或者 truffle, 最近使用 web3 进行智能合约的部署, 分享下
0x01 准备工作
在使用 web3 进行合约的部署, 一般需要使用准备以下几个库:
1 solc
solc 是以太坊官方出的一款 Solidity 语言开发的智能合约的编译工具, 可以通过 solc 获得部署合约时所要使用的 bytecode 和 abi
2web3.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);
- }
- }
- });
- }
谢谢大家的支持, 如果觉得不错, 欢迎转发~
如果喜欢, 别说话, 扫我~
来源: https://segmentfault.com/a/1190000013841167