以太坊Whisper协议

在本教程中,我们将学习如何使用以太坊的Whisper协议创建简单的聊天CLI。尽管本教程中的所有操作都在你的控制台中进行,但是你应该能够重新使用我们在你自己的应用程序中提供的JS,并对如何发送和显示不同类型的消息有一个很好的了解,以及使用Whisper可以构建什么。

我们了解到,没有多少DAPP开发人员希望以状态的方式使用Whisper(作为一个庞大的多用户消息传递协议),而是将有关DAPP中与其交互的特定(通常是重要的)信息移动。本教程旨在为你提供所需的技能,以适应你的需要:你应该既知道足够容易插入到任何状态聊天,以及如何使用Whisper为你自己的工作到最后。许多其他团队已经开始这样做了,例如,你可以在Bloom blog上找到更多关于如何将基本概念扩展到有趣系统的信息。

我们专门为本教程创建了这个存储库。如果你想帮助社区,可以在不同的分支下添加额外的教程。不过,在克隆存储库之前,让我们确保正确设置了所有依赖项,尤其是nodejs和go-ethereum。我们将使用最新版本的Geth、Whisper和EmochtJS来帮助你了解Whisper今天的样子。

NodeJS 8.10+

node version
> 8.10+

如果需要更新节点,请 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发行版:

sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get install ethereum

/* Just to upgrade */
sudo apt-get update ethereum

启动geth节点

要使用Whisper,你需要一个正在运行的geth节点。可以执行以下命令以使用所需的最小选项启动节点:

geth --testnet --syncmode=light --ws --wsorigins=mychat --shh --wsapi=web3,shh,net

这里,我们连接到Ropsten,确保我们没有验证完整的块(只有headers),确保websockets使用特定的源(我们稍后将在JS中使用),确保启用了Whisper,即shh,并且webshhnetAPI对我们可用。

设置和浏览

现在我们已经设置了所有的先决条件,我们需要克隆这个repo并安装依赖项。

git clone https://github.com/status-im/whisper-tutorial.git
cd whisper-tutorial
npm install

安装完所有依赖项后,可以执行npm start来查看教程的内容。这非常简单,只是一个cli界面,它允许你使用默认主题和一些其他设置发送悄悄消息。下面我们将介绍如何发送公共和私人消息。为了更好地理解我们为什么要执行以下步骤并更详细地了解我们引入的每个概念,请在完成此操作时阅读上面的扩展功能部分。

你可以随时使用ctrl+c关闭应用程序。

对聊天客户端进行编码

文件src/index.js中充满了我们需要处理的todo。以下各节详细介绍了我们将如何以逻辑方式完成这些操作。在每个部分的末尾,可以执行npm start以查看进度。

TODO:Web3连接

为了通过Whisper进行交流,我们需要一个Web3连接。确保geth正在运行后,我们可以使用以下代码连接到节点:

// 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();
}

调用web3并告诉它将其provider设置为正在运行的geth实例(使用上面的选项),将使cli能够连接到我们的节点。它使用geth命令的--wsorigins标志中指定的源代码mychat。如果无法连接,聊天窗口将关闭。

TODO:生成密钥对

我们需要生成一个密钥对,用于对发送的消息进行签名。我们将使用相同的密钥对来接收和解密私有消息。这与调用通过shh API公开的函数一样简单:

// Generate keypair
const keyPair = await web3.shh.newKeyPair();

TODO:生成对称密钥

Public消息是使用对称密钥和主题加密的消息。它们不会针对特定的任何人,而是由在特定频道中收听的任何人接收。在聊天应用程序中,我们的频道由一个共享对称密钥表示,该密钥的password就是我们将要使用和收听的频道:

// Generate a symmetric key
const channelSymKey = await web3.shh.generateSymKeyFromPassword(DEFAULT_CHANNEL);

TODO:获取公钥

我们需要为自己生成公钥,以便能够将自己标识为通过我们的通道发送和接收的作者消息。这是通过以下代码完成的:

// Obtain public key
const pubKey = await web3.shh.getPublicKey(keyPair);

TODO:发送公共消息

一旦生成了对称密钥,就可以使用web3.shh.post发送消息。我们将用密钥对签署我们的消息,并将其发送到特定的主题。

// 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字节的十六进制字符串,可用于筛选消息。
  • TTL,是以秒为单位的生存时间。
  • powtime,是用于工作证明的最长时间(秒)。
  • pow target,是此消息所需的最小pow目标。

TODO:订阅公共聊天消息

你可能已经注意到你发送的消息没有显示在屏幕上。为了在Whisper中看到消息,我们需要订阅subscribe对称密钥接收的消息。我们还可以使用相同的主题创建过滤器:

// 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:发送私人消息

为了发送私人消息,我们有一个类似于irc的命令:/msg 0xcontact_public_key message。因此,如果你想发送消息,只需从chat cli复制联系人的公钥,然后编写消息。

我们已经将联系人的公钥分配给contactcode变量,并将消息的正文分配给messagecontent。向特定的非对称公钥发送消息与向对称密钥发送消息类似。区别在于,你需要指定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并拖动鼠标以选择联系人的公钥。

TODO:订阅私人消息

与从公共通道接收消息类似,我们需要创建一个订阅来接收私有消息,将其用作privatekeyid我们的keypair,以便订阅接收发送到公共密钥的消息。

// 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);
});

添加此代码后,继续打开聊天应用程序的三个实例,在一个窗口中编写一条公共消息,在另一个窗口中复制公共密钥并向创建第一条消息的帐户发送一条私有消息。第一个和第二个窗口将能够看到消息,但第三个窗口将只接收到公共消息。

最后的想法

如你所见,使用Whisper进行去中心化通信非常容易,你可以利用该协议来传递加密安全的链外消息。布鲁姆这样做了,正如Project Khoka in South Africa等。

但是,目前没有足够的在线节点可以启用低语(可能是因为缺乏运行此功能的激励措施),因此,除非你像我们在状态下这样引导某些节点,否则消息可能无法传递。你可以通过在启用了--shh选项的情况下运行自己的节点来增加可用节点的数量。我们将永远比你少3。

======================================================================

分享一些比特币、以太坊、EOS、Fabric等区块链相关的交互式在线编程实战教程:

  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • c#比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。
  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • ERC721以太坊通证实战,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • EOS入门教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • 深入浅出玩转EOS钱包开发,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。
  • Hyperledger Fabric 区块链开发详解,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。
  • Hyperledger Fabric java 区块链开发详解,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。
  • tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

汇智网原创翻译,转载请标明出处。这里是以太坊Whisper协议

推荐阅读更多精彩内容