目錄
一、前言
終於到了這裏了,之前我們講的solidity教程只是基礎的合約編寫,但是我們並不能像普通程序一樣運行,因爲我們還需要自己搭建運行環境。這確實要比比普通的編程語言難得多。
而我們要做的就是知難而上。
今天我們要講的是Web3.js,這是針對以太坊的JavaScript庫,讓我們走進今天的內容來了解一下吧。
二、Web3.js
1、引入
我們都知道,以太坊是由很多結點組成的,每個結點都有區塊鏈的備份,如果我們想要調用一份合約的某個方法,我們需要告訴結點:
1.合約地址
2.方法及其傳入參數
以太坊結點只能識別一種叫做JSON-RPC的語言。這種語言不是那麼太容易讀懂,如果我們想調用一個合約,我們需要發送的查詢語句如下:
// 哈……祝你寫所有這樣的函數調用的時候都一次通過
// 往右邊拉…… ==>
{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155","to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","gas":"0x76c0","gasPrice":"0x9184e72a000","value":"0x9184e72a","data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}],"id":1}
看不明白?我們換種方式展示:
{
"jsonrpc":"2.0",
"method":"eth_sendTransaction",
"params":[{
"from":"0xb60e8dd61c5d32be8058bb8eb970870f07233155",
"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"gas":"0x76c0",
"gasPrice":"0x9184e72a000",
"value":"0x9184e72a",
"data":"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
}],
"id":1
}
這樣確實太麻煩了!
2、Web3.js怎麼解決
在Web3.js中,把這些複雜的查詢語句隱藏起來,我們只需要和JavaScript進行交互即可,方式也非常簡單:
CryptoZombies.methods.createRandomZombie("Vitalik Nakamoto 🤔")
.send({ from: "0xb60e8dd61c5d32be8058bb8eb970870f07233155", gas: "3000000" })
後續,我們還會更加詳細講解。
3、Web3.js環境搭建
我們想要使用Web3.js,就需要搭建好環境
搭建方式有很多種,如:
// 用 NPM
npm install web3
// 用 Yarn
yarn add web3
// 用 Bower
bower install web3
// ...或者其他。
又如:
<script language="javascript" type="text/javascript" src="web3.min.js"></script>
對於後面的方式,我們需要從GitHub上面下載壓縮後的.js文件,然後包含到我們的項目中。
4、實戰
1.要求
在下面的HTML項目中使用script標籤添加js文件。
JS文件爲:
web3.min.js
2.代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CryptoZombies front-end</title>
<script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="web3.min.js"></script>
</head>
<body>
</body>
</html>
三、Web3 Provider
1、引入
上面我們搭建好了Web3.js環境(雖然真的很簡單,但是我們確實是完成了),然後我們就需要通過環境和區塊鏈進行交互了。
在 Web3.js 裏設置 Web3 的 Provider(提供者) 告訴我們的代碼應該和 哪個節點 交互來處理我們的讀寫。我們可以運行自己的結點作爲提供者。
但這樣不是很方便!
因爲如果我們用自己的結點作爲提供者,那我們爲其他用戶提供DAPP服務的時候,我們還需要同步維護一個以太坊結點。所以,如果能有一個第三方服務爲我們提供相關功能,這個問題就解決了。
2、Infura
Infura 是一個服務,它維護了很多以太坊節點並提供了一個緩存層來實現高速讀取。我們可以用他們的 API 來免費訪問這個服務。 用 Infura 作爲節點提供者,我們無需自己運營節點就能很可靠地向以太坊發送、接收信息。
使用方法如下:
var web3 = new Web3(new Web3.providers.WebsocketProvider("wss://mainnet.infura.io/ws"));
當然,在DAPP中,除了讀信息,還會有用戶寫信息,所以我們需要一個方法,可以讓用戶用自己的私鑰給事務簽名。
這些需要涉及到密碼學的知識。在這裏給大家簡單說明一下,在區塊鏈中,每個用戶都會有自己的公私鑰對錶明自己的身份,從而實現匿名性。用戶自己保存私鑰,公鑰可以公開。用戶使用自己的私鑰對數據進行簽名,其他用戶可以利用公鑰去驗證。但是其他用戶不會知道該用戶的私鑰(理想狀態下,比如一個惡意用戶,用酒把這個人的私鑰灌出來也說不準)。一旦用戶自己的私鑰丟失,他所擁有的以太幣(或比特幣)就全部永久損失了,除非他能將私鑰找回。
3、MetaMask
公私鑰密碼學真的是比較繁瑣複雜的,對於一些只想做應用的人來說,他們不需要把密碼學理解的太透徹,可能他們只是想挖礦賺個錢而已。
所以我們就需要一個工具來幫我們管理我們的公私鑰。
最常用的就是MetaMask:
這是一個瀏覽器擴展插件,我們可以使用谷歌或者火狐瀏覽器安裝並使用。它能讓用戶安全地維護他們的以太坊賬戶和私鑰, 並用他們的賬戶和使用 Web3.js 的網站互動。
上面圖中的以太幣是我做測試使用的,這個幣沒有實際的價值,只是用於測試。任何人都可以註冊一個結點,獲得免費的測試以太幣。
我們用Metamask作用web3的提供者。具體做法如下:
1.MetaMask 將其 web3 提供者注入到瀏覽器的全局 JavaScript 對象 web3 中。
2.應用檢查 web3 是否存在。若存在就使用 web3.currentProvider 作爲其提供者。
舉個例子,如:
window.addEventListener('load', function() {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== 'undefined') {
// Use Mist/MetaMask's provider
web3js = new Web3(web3.currentProvider);
} else {
// Handle the case where the user doesn't have web3. Probably
// show them a message telling them to install Metamask in
// order to use our app.
}
// Now you can start your app & access web3js freely:
startApp()
})
我們可以使用類似的代碼在我們的應用中,用以檢查用戶是否安裝MetaMask及提供用戶安裝。
4、實戰
1.要求
我們在HTML文件中的 </body> 標籤前面放置了一個空的 script 標籤。可以把這節課的 JavaScript 代碼寫在裏面。
1.
把上面用來檢測 MetaMask 是否安裝的模板代碼粘貼進來。請粘貼到以 window.addEventListener 開頭的代碼塊中。
2.代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CryptoZombies front-end</title>
<script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="web3.min.js"></script>
</head>
<body>
<script>
// Start here
window.addEventListener('load', function() {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== 'undefined') {
// Use Mist/MetaMask's provider
web3js = new Web3(web3.currentProvider);
} else {
// Handle the case where the user doesn't have web3. Probably
// show them a message telling them to install Metamask in
// order to use our app.
}
// Now you can start your app & access web3js freely:
startApp()
})
</script>
</body>
</html>