大多數人在初學智能合約開發的時候,都是選擇使用remix
進行合約的開發以及部署。remix
是集Solidity
的編輯器,編譯器,部署於一身的集成開發工具,很是方便,也很是好用。以前一直使用Remix
或者truffle
,最近使用web3
進行智能合約的部署,分享下。javascript
在使用web3
進行合約的部署,通常須要使用準備如下幾個庫:java
solc
是以太坊官方出的一款Solidity語言開發的智能合約的編譯工具,能夠經過solc
得到部署合約時所要使用的 bytecode
和 abi
。node
web3.js
是以太坊官方實現的一個使用javascript
與以太坊客戶端進行交互的js庫,web3.js
能夠與任何暴露RPC層的以太坊節點協同工做。web
本文主要討論web3的智能合約部署,不涉及solidity語言的討論,因此咱們使用一個很是簡單的智能合約來學習下面的部署,將本身的名字寫入區塊鏈中:shell
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; } }
若是想要使用web3來部署合約,須要先得到合約的bytecode以及合約的abi,而編譯能夠使用solcjs進行。npm
npm install -g solc
安裝成功後,咱們能夠經過命令行編譯代碼,得到code以及abi。json
# 得到code solcjs --bin name.sol # 獲的abi solcjs --abi name.sol
引入web3.js
有兩種方法,一種使用nodejs,一種直接使用瀏覽器引擎。瀏覽器
npm install web3
# 項目中直接引入 `web3.min.js` bower install 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是一個以太坊錢包的瀏覽器插件,該插件提供本身的web3實例,當用戶在瀏覽器中安裝了MetaMask,MetaMask會自動注入一段js,而後將本身的web3實例注入到了瀏覽器中,因此能夠直接使用該web3實例。代碼以下:
web3 = new Web3(web3.currentProvider);
當瀏覽器中已經擁有了web3實例,那麼咱們就直接使用已存在的實例,若是不存在,再去鏈接咱們本身的web3實例。
if (typeof web3 !== 'undefined') { web3 = new Web3(web3.currentProvider); } else { web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")); }
經過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); } })
由於本文在部署時,使用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); } } }); }
謝謝你們的支持,若是以爲不錯,歡迎轉發~
若是喜歡,別說話,掃我~