zoukankan      html  css  js  c++  java
  • whisper简介

    以太坊系列之二十 以太坊中的基础应用whisper

    1 whisper介绍

    whisper是一个比较独立的模块,它的运行完全独立于geth也就是以太坊区块链.如果要感受whisper可以通过启动wnode来感受.wnode有丰富的参数,能够让大家加入whisper网络,来感受这个去中心化的聊天系统. 我前面写的[以太坊系列之十八: 百行go代码构建p2p聊天室](http://www.cnblogs.com/baizx/p/7505096.html)就是一个简版的wnode,只取了其中一小部分.
    
    whisper实际上就是以太坊p2p网络上的一个应用, 注意我强调以太坊网络是因为它的p2p协议直接取自前面介绍的[以太坊系列之六: p2p模块--以太坊源码学习](http://www.cnblogs.com/baizx/p/6963636.html),那里提到P2p模块是支持自定义Protocol的,实际上以太坊区块的同步,tx的发布都是其中的一个协议而已.同样whisper也是其中的一个协议.
    我们来看看这个协议的定义.
    ```go
    // p2p whisper sub protocol handler
    whisper.protocol = p2p.Protocol{
    	Name:    ProtocolName, //shh
    	Version: uint(ProtocolVersion), //5
    	Length:  NumberOfMessageCodes, //64
    	Run:     whisper.HandlePeer, //数据处理
    }
    ```
    在web3 api中暴露的shh模块主体就是在这里
    

    2 whisper rpc模块

    以太坊系列对外提供的api接口都是通过rpc调用来实现的. whisper同样也是,whisper对外提供的api主要是建立账户,发送消息,过滤消息等. 我们一般意义上的接收消息就是过滤消息,因为p2p网络中会收到大量各种消息,你只有定义了自己感兴趣的消息,也就是过滤消息才能得到想要的具体消息内容.
    
    对外提供rpc api的接口一般都是如下形式:
    ```go
    []rpc.API{
    	{
    		Namespace: ProtocolName, //shh
    		Version:   ProtocolVersionStr, //5.0
    		Service:   NewPublicWhisperAPI(w),
    		Public:    true,
    	},
    }
    
    // NewPublicWhisperAPI create a new RPC whisper service.
    func NewPublicWhisperAPI(w *Whisper) *PublicWhisperAPI {
        return &PublicWhisperAPI{whisper: w}
    }
    ```
    PublicWhisperAPI包含了所有可能被访问的api.
    

    3 whisper中的消息

    主要有三种消息,分别是messagesCode  ,p2pCode,p2pRequestCode
    我们一般用的主要就是messagesCode类型,p2pCode用于点对点直接通信,p2pRequestCode为智能合约使用.
    主要说一下messageCode类型如何处理.
    
    对于收到的消息,首先检验发送时间是否正确(防止错误垃圾消息),然后计算工作量是否到位(这个就是bitmessage的核心思想),
    第三步检验该消息是否已经收到过(hash值存在),如果存在就忽略,否则进入第四步.
    第四步将消息放入本地消息队列 节点会定期对消息队列中的消息进行处理.
    第五步 检测是否满足某个过滤条件,如果是,就将消息放入过滤队列(channel)中.
    
    另外,节点还会启动一个携程定期把本地收到的合法消息广播出去.
    以上基本就是一个p2p聊天系统的核心了.
    

    4 消息的加密

    消息有两种加密形式,一种是对称的aes加密,另一种是非对称的ecdsaj加密.上面对于消息的处理流程中除了第五步检测是否满足设定的过滤条件,其他步骤都不涉及对消息内容的处理,也就无需解密.
    
    也就是说真正对消息内容的处理,是在过滤器中进行的.先看看消息的格式,里面包含什么内容. 分成两个部分,一个是信封,一个是信体,信封没有加密,信体加密.
    ```go
    // Envelope represents a clear-text data packet to transmit through the Whisper
    // network. Its contents may or may not be encrypted and signed.
    type Envelope struct {
        Version  []byte
        Expiry   uint32
        TTL      uint32
        Topic    TopicType
        AESNonce []byte
        Data     []byte
        EnvNonce uint64
    
        pow  float64     // Message-specific PoW as described in the Whisper specification.
    }
    ```
    信封里主要是时间相关信息以及验证工作量所需信息. 需要特别指出的是,whisper可以按照特定的topic过滤消息,topic是明文且没有加密的四字节数据.
    
    信体格式比较复杂,关键是里面有需要解密消息的对称密钥或者公钥.
    ```go
    // ReceivedMessage represents a data packet to be received through the
    // Whisper protocol.
    type ReceivedMessage struct {
        Raw []byte
    
        Payload   []byte
        Padding   []byte
        Signature []byte
    
        PoW   float64          // Proof of work as described in the Whisper spec
        Sent  uint32           // Time when the message was posted into the network
        TTL   uint32           // Maximum time to live allowed for the message
        Src   *ecdsa.PublicKey // Message recipient (identity used to decode the message)
        Dst   *ecdsa.PublicKey // Message recipient (identity used to decode the message)
        Topic TopicType
    
        SymKeyHash      common.Hash // The Keccak256Hash of the key, associated with the Topic
        EnvelopeHash    common.Hash // Message envelope hash to act as a unique id
        EnvelopeVersion uint64
    }
    ```
    可以看到信体里也把信封的大部分内容都包含进去了.
    

    5 过滤器

    过滤器必须给出一个公钥或者aes密钥来解密消息, 也可以给出一个或多个可选的topic来进行过滤.
    过滤器实际上是用户接入whisper消息系统的入口,也只有这种方式来接收消息.
    另外过滤器还可以指定一个更高难度(相比默认难度)的工作量来过滤消息.
    过滤器结构如下:

    type Filter struct {
    	Src        *ecdsa.PublicKey  // Sender of the message
    	KeyAsym    *ecdsa.PrivateKey // Private Key of recipient
    	KeySym     []byte            // Key associated with the Topic
    	Topics     [][]byte          // Topics to filter messages with
    	PoW        float64           // Proof of work as described in the Whisper spec
    	AllowP2P   bool              // Indicates whether this filter is interested in direct peer-to-peer messages
    	SymKeyHash common.Hash       // The Keccak256Hash of the symmetric key, needed for optimization
    
    	msgChan chan *ReceivedMessage //matched message channel
    	mutex   sync.RWMutex
    }
    

    主要包含指定的公钥,指定的对称密钥,topics,pow.

  • 相关阅读:
    Codeforces 845E Fire in the City 线段树
    Codeforces 542D Superhero's Job dp (看题解)
    Codeforces 797F Mice and Holes dp
    Codeforces 408D Parcels dp (看题解)
    Codeforces 464D World of Darkraft
    Codeforces 215E Periodical Numbers 容斥原理
    Codeforces 285E Positions in Permutations dp + 容斥原理
    Codeforces 875E Delivery Club dp
    Codeforces 888F Connecting Vertices 区间dp (看题解)
    Codeforces 946F Fibonacci String Subsequences dp (看题解)
  • 原文地址:https://www.cnblogs.com/baizx/p/7898692.html
Copyright © 2011-2022 走看看