在本教程中,我們將學習如何使用以太坊的Whisper協(xié)議創(chuàng)建簡單的聊天CLI。盡管本教程中的所有操作都在你的控制臺中進行,但是你應該能夠重新使用我們在你自己的應用程序中提供的JS,并對如何發(fā)送和顯示不同類型的消息有一個很好的了解,以及使用Whisper可以構(gòu)建什么。
我們了解到,沒有多少DAPP開發(fā)人員希望以狀態(tài)的方式使用Whisper(作為一個龐大的多用戶消息傳遞協(xié)議),而是將有關DAPP中與其交互的特定(通常是重要的)信息移動。本教程旨在為你提供所需的技能,以適應你的需要:你應該既知道足夠容易插入到任何狀態(tài)聊天,以及如何使用Whisper為你自己的工作到最后。許多其他團隊已經(jīng)開始這樣做了,例如,你可以在Bloom blog上找到更多關于如何將基本概念擴展到有趣系統(tǒng)的信息。
我們專門為本教程創(chuàng)建了這個存儲庫。如果你想幫助社區(qū),可以在不同的分支下添加額外的教程。不過,在克隆存儲庫之前,讓我們確保正確設置了所有依賴項,尤其是nodejs和go-ethereum。我們將使用最新版本的Geth、Whisper和EmochtJS來幫助你了解Whisper今天的樣子。
NodeJS 8.10+
node version
> 8.10+
如果需要更新節(jié)點,請 install nvm
并安裝/使用LTS版本。下面為你提供了macos/linux命令:
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
nvm install --lts
nvm use lts
Go-ethereum 1.8.17+
geth version
> 1.8.17+
如果你需要install geth
,你可以使用下面的MacOS命令:
brew tap ethereum/ethereum
brew install ethereum
/* Just to upgrade */
brew upgrade ethereum
如果你使用的是Linux發(fā)行版:
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get install ethereum
/* Just to upgrade */
sudo apt-get update ethereum
啟動geth節(jié)點
要使用Whisper,你需要一個正在運行的geth節(jié)點。可以執(zhí)行以下命令以使用所需的最小選項啟動節(jié)點:
geth --testnet --syncmode=light --ws --wsorigins=mychat --shh --wsapi=web3,shh,net
這里,我們連接到Ropsten,確保我們沒有驗證完整的塊(只有headers),確保websockets
使用特定的源(我們稍后將在JS中使用),確保啟用了Whisper,即shh
,并且web
、shh
和net
API對我們可用。
設置和瀏覽
現(xiàn)在我們已經(jīng)設置了所有的先決條件,我們需要克隆這個repo并安裝依賴項。
git clone https://github.com/status-im/whisper-tutorial.git
cd whisper-tutorial
npm install
安裝完所有依賴項后,可以執(zhí)行npm start
來查看教程的內(nèi)容。這非常簡單,只是一個cli界面,它允許你使用默認主題和一些其他設置發(fā)送悄悄消息。下面我們將介紹如何發(fā)送公共和私人消息。為了更好地理解我們?yōu)槭裁匆獔?zhí)行以下步驟并更詳細地了解我們引入的每個概念,請在完成此操作時閱讀上面的擴展功能部分。
你可以隨時使用ctrl+c
關閉應用程序。
對聊天客戶端進行編碼
文件src/index.js
中充滿了我們需要處理的todo
。以下各節(jié)詳細介紹了我們將如何以邏輯方式完成這些操作。在每個部分的末尾,可以執(zhí)行npm start
以查看進度。
TODO:Web3連接
為了通過Whisper進行交流,我們需要一個Web3連接。確保geth
正在運行后,我們可以使用以下代碼連接到節(jié)點:
// Web3 connection
const web3 = new Web3();
try {
web3.setProvider(new Web3.providers.WebsocketProvider("ws://localhost:8546", {headers: {Origin: "mychat"}}));
await web3.eth.net.isListening();
} catch(err) {
process.exit();
}
調(diào)用web3并告訴它將其provider
設置為正在運行的geth實例(使用上面的選項),將使cli能夠連接到我們的節(jié)點。它使用geth
命令的--wsorigins
標志中指定的源代碼mychat
。如果無法連接,聊天窗口將關閉。
TODO:生成密鑰對
我們需要生成一個密鑰對,用于對發(fā)送的消息進行簽名。我們將使用相同的密鑰對來接收和解密私有消息。這與調(diào)用通過shh
API公開的函數(shù)一樣簡單:
// Generate keypair
const keyPair = await web3.shh.newKeyPair();
TODO:生成對稱密鑰
Public
消息是使用對稱密鑰和主題加密的消息。它們不會針對特定的任何人,而是由在特定頻道中收聽的任何人接收。在聊天應用程序中,我們的頻道由一個共享對稱密鑰表示,該密鑰的password
就是我們將要使用和收聽的頻道:
// Generate a symmetric key
const channelSymKey = await web3.shh.generateSymKeyFromPassword(DEFAULT_CHANNEL);
TODO:獲取公鑰
我們需要為自己生成公鑰,以便能夠?qū)⒆约簶俗R為通過我們的通道發(fā)送和接收的作者消息。這是通過以下代碼完成的:
// Obtain public key
const pubKey = await web3.shh.getPublicKey(keyPair);
TODO:發(fā)送公共消息
一旦生成了對稱密鑰,就可以使用web3.shh.post
發(fā)送消息。我們將用密鑰對
簽署我們的消息,并將其發(fā)送到特定的主題。
// Send a public message
web3.shh.post({
symKeyID: channelSymKey,
sig: keyPair,
ttl: TTL,
topic: channelTopic,
payload: web3.utils.fromAscii(message),
powTime: POW_TIME,
powTarget: POW_TARGET
});
-
topic
,是一個4字節(jié)的十六進制字符串,可用于篩選消息。 -
TTL
,是以秒為單位的生存時間。 -
powtime
,是用于工作證明的最長時間(秒)。 -
pow target
,是此消息所需的最小pow目標。
TODO:訂閱公共聊天消息
你可能已經(jīng)注意到你發(fā)送的消息沒有顯示在屏幕上。為了在Whisper中看到消息,我們需要訂閱subscribe
對稱密鑰接收的消息。我們還可以使用相同的主題創(chuàng)建過濾器:
// Subscribe to public chat messages
web3.shh.subscribe("messages", {
minPow: POW_TARGET,
symKeyID: channelSymKey,
topics: [channelTopic]
}).on('data', (data) => {
// Display message in the UI
ui.addMessage(data.sig, web3.utils.toAscii(data.payload));
}).on('error', (err) => {
ui.addError("Couldn't decode message: " + err.message);
});
添加此代碼后,打開聊天應用程序的兩個實例并編寫一條消息。你將看到它如何在兩個窗口中顯示。唯一的問題是,任何收聽此頻道的人都可以看到你所寫的所有消息,所以讓我們通過添加私有消息來解決這個問題。
TODO:發(fā)送私人消息
為了發(fā)送私人消息,我們有一個類似于irc的命令:/msg 0xcontact_public_key message
。因此,如果你想發(fā)送消息,只需從chat cli復制聯(lián)系人的公鑰,然后編寫消息。
我們已經(jīng)將聯(lián)系人的公鑰分配給contactcode
變量,并將消息的正文分配給messagecontent
。向特定的非對稱公鑰發(fā)送消息與向?qū)ΨQ密鑰發(fā)送消息類似。區(qū)別在于,你需要指定pubkey
屬性而不是symkeyid
。
// Send private message
web3.shh.post({
pubKey: contactCode,
sig: keyPair,
ttl: TTL,
topic: channelTopic,
payload: web3.utils.fromAscii(messageContent),
powTime: POW_TIME,
powTarget: POW_TARGET
});
在Ubuntu中,你需要按
shift
并拖動鼠標以選擇聯(lián)系人的公鑰。
TODO:訂閱私人消息
與從公共通道接收消息類似,我們需要創(chuàng)建一個訂閱來接收私有消息,將其用作privatekeyid
我們的keypair
,以便訂閱接收發(fā)送到公共密鑰的消息。
// Subscribe to private messages
web3.shh.subscribe("messages", {
minPow: POW_TARGET,
privateKeyID: keyPair,
topics: [channelTopic]
}).on('data', (data) => {
ui.addMessage(data.sig, web3.utils.toAscii(data.payload), true);
}).on('error', (err) => {
ui.addError("Couldn't decode message: " + err.message);
});
添加此代碼后,繼續(xù)打開聊天應用程序的三個實例,在一個窗口中編寫一條公共消息,在另一個窗口中復制公共密鑰并向創(chuàng)建第一條消息的帳戶發(fā)送一條私有消息。第一個和第二個窗口將能夠看到消息,但第三個窗口將只接收到公共消息。
最后的想法
如你所見,使用Whisper進行去中心化通信非常容易,你可以利用該協(xié)議來傳遞加密安全的鏈外消息。布魯姆這樣做了,正如Project Khoka in South Africa等。
但是,目前沒有足夠的在線節(jié)點可以啟用低語(可能是因為缺乏運行此功能的激勵措施),因此,除非你像我們在狀態(tài)下這樣引導某些節(jié)點,否則消息可能無法傳遞。你可以通過在啟用了--shh
選項的情況下運行自己的節(jié)點來增加可用節(jié)點的數(shù)量。我們將永遠比你少3。
======================================================================
分享一些比特幣、以太坊、EOS、Fabric等區(qū)塊鏈相關的交互式在線編程實戰(zhàn)教程:
- java比特幣開發(fā)教程,本課程面向初學者,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Java代碼中集成比特幣支持功能,例如創(chuàng)建地址、管理錢包、構(gòu)造裸交易等,是Java工程師不可多得的比特幣開發(fā)學習課程。
- php比特幣開發(fā)教程,本課程面向初學者,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在Php代碼中集成比特幣支持功能,例如創(chuàng)建地址、管理錢包、構(gòu)造裸交易等,是Php工程師不可多得的比特幣開發(fā)學習課程。
- c#比特幣開發(fā)教程,本課程面向初學者,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲、去中心化共識機制、密鑰與腳本、交易與UTXO等,同時也詳細講解如何在C#代碼中集成比特幣支持功能,例如創(chuàng)建地址、管理錢包、構(gòu)造裸交易等,是C#工程師不可多得的比特幣開發(fā)學習課程。
- java以太坊開發(fā)教程,主要是針對java和android程序員進行區(qū)塊鏈以太坊開發(fā)的web3j詳解。
- python以太坊,主要是針對python工程師使用web3.py進行區(qū)塊鏈以太坊開發(fā)的詳解。
- php以太坊,主要是介紹使用php進行智能合約開發(fā)交互,進行賬號創(chuàng)建、交易、轉(zhuǎn)賬、代幣開發(fā)以及過濾器和交易等內(nèi)容。
- 以太坊入門教程,主要介紹智能合約與dapp應用開發(fā),適合入門。
- 以太坊開發(fā)進階教程,主要是介紹使用node.js、mongodb、區(qū)塊鏈、ipfs實現(xiàn)去中心化電商DApp實戰(zhàn),適合進階。
- ERC721以太坊通證實戰(zhàn),課程以一個數(shù)字藝術品創(chuàng)作與分享DApp的實戰(zhàn)開發(fā)為主線,深入講解以太坊非同質(zhì)化通證的概念、標準與開發(fā)方案。內(nèi)容包含ERC-721標準的自主實現(xiàn),講解OpenZeppelin合約代碼庫二次開發(fā),實戰(zhàn)項目采用Truffle,IPFS,實現(xiàn)了通證以及去中心化的通證交易所。
- C#以太坊,主要講解如何使用C#開發(fā)基于.Net的以太坊應用,包括賬戶管理、狀態(tài)與交易、智能合約開發(fā)與交互、過濾器和交易等。
- EOS入門教程,本課程幫助你快速入門EOS區(qū)塊鏈去中心化應用的開發(fā),內(nèi)容涵蓋EOS工具鏈、賬戶與錢包、發(fā)行代幣、智能合約開發(fā)與部署、使用代碼與智能合約交互等核心知識點,最后綜合運用各知識點完成一個便簽DApp的開發(fā)。
- 深入淺出玩轉(zhuǎn)EOS錢包開發(fā),本課程以手機EOS錢包的完整開發(fā)過程為主線,深入學習EOS區(qū)塊鏈應用開發(fā),課程內(nèi)容即涵蓋賬戶、計算資源、智能合約、動作與交易等EOS區(qū)塊鏈的核心概念,同時也講解如何使用eosjs和eosjs-ecc開發(fā)包訪問EOS區(qū)塊鏈,以及如何在React前端應用中集成對EOS區(qū)塊鏈的支持。課程內(nèi)容深入淺出,非常適合前端工程師深入學習EOS區(qū)塊鏈應用開發(fā)。
- Hyperledger Fabric 區(qū)塊鏈開發(fā)詳解,本課程面向初學者,內(nèi)容即包含Hyperledger Fabric的身份證書與MSP服務、權(quán)限策略、信道配置與啟動、鏈碼通信接口等核心概念,也包含F(xiàn)abric網(wǎng)絡設計、nodejs鏈碼與應用開發(fā)的操作實踐,是Nodejs工程師學習Fabric區(qū)塊鏈開發(fā)的最佳選擇。
- Hyperledger Fabric java 區(qū)塊鏈開發(fā)詳解,課程面向初學者,內(nèi)容即包含Hyperledger Fabric的身份證書與MSP服務、權(quán)限策略、信道配置與啟動、鏈碼通信接口等核心概念,也包含F(xiàn)abric網(wǎng)絡設計、java鏈碼與應用開發(fā)的操作實踐,是java工程師學習Fabric區(qū)塊鏈開發(fā)的最佳選擇。
- tendermint區(qū)塊鏈開發(fā)詳解,本課程適合希望使用tendermint進行區(qū)塊鏈開發(fā)的工程師,課程內(nèi)容即包括tendermint應用開發(fā)模型中的核心概念,例如ABCI接口、默克爾樹、多版本狀態(tài)庫等,也包括代幣發(fā)行等豐富的實操代碼,是go語言工程師快速入門區(qū)塊鏈開發(fā)的最佳選擇。
匯智網(wǎng)原創(chuàng)翻譯,轉(zhuǎn)載請標明出處。這里是以太坊Whisper協(xié)議