github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/whisper/whisperv2/main.go (about)

     1  // Copyright 2014 The Spectrum Authors
     2  // This file is part of the Spectrum library.
     3  //
     4  // The Spectrum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The Spectrum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the Spectrum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // +build none
    18  
    19  // Contains a simple whisper peer setup and self messaging to allow playing
    20  // around with the protocol and API without a fancy client implementation.
    21  
    22  package main
    23  
    24  import (
    25  	"fmt"
    26  	"log"
    27  	"os"
    28  	"time"
    29  
    30  	"github.com/SmartMeshFoundation/Spectrum/common"
    31  	"github.com/SmartMeshFoundation/Spectrum/crypto"
    32  	"github.com/SmartMeshFoundation/Spectrum/logger"
    33  	"github.com/SmartMeshFoundation/Spectrum/p2p"
    34  	"github.com/SmartMeshFoundation/Spectrum/p2p/nat"
    35  	"github.com/SmartMeshFoundation/Spectrum/whisper"
    36  )
    37  
    38  func main() {
    39  	logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel))
    40  
    41  	// Generate the peer identity
    42  	key, err := crypto.GenerateKey()
    43  	if err != nil {
    44  		fmt.Printf("Failed to generate peer key: %v.\n", err)
    45  		os.Exit(-1)
    46  	}
    47  	name := common.MakeName("whisper-go", "1.0")
    48  	shh := whisper.New()
    49  
    50  	// Create an Ethereum peer to communicate through
    51  	server := p2p.Server{
    52  		PrivateKey: key,
    53  		MaxPeers:   10,
    54  		Name:       name,
    55  		Protocols:  []p2p.Protocol{shh.Protocol()},
    56  		ListenAddr: ":30300",
    57  		NAT:        nat.Any(),
    58  	}
    59  	fmt.Println("Starting Ethereum peer...")
    60  	if err := server.Start(); err != nil {
    61  		fmt.Printf("Failed to start Ethereum peer: %v.\n", err)
    62  		os.Exit(1)
    63  	}
    64  
    65  	// Send a message to self to check that something works
    66  	payload := fmt.Sprintf("Hello world, this is %v. In case you're wondering, the time is %v", name, time.Now())
    67  	if err := selfSend(shh, []byte(payload)); err != nil {
    68  		fmt.Printf("Failed to self message: %v.\n", err)
    69  		os.Exit(-1)
    70  	}
    71  }
    72  
    73  // SendSelf wraps a payload into a Whisper envelope and forwards it to itself.
    74  func selfSend(shh *whisper.Whisper, payload []byte) error {
    75  	ok := make(chan struct{})
    76  
    77  	// Start watching for self messages, output any arrivals
    78  	id := shh.NewIdentity()
    79  	shh.Watch(whisper.Filter{
    80  		To: &id.PublicKey,
    81  		Fn: func(msg *whisper.Message) {
    82  			fmt.Printf("Message received: %s, signed with 0x%x.\n", string(msg.Payload), msg.Signature)
    83  			close(ok)
    84  		},
    85  	})
    86  	// Wrap the payload and encrypt it
    87  	msg := whisper.NewMessage(payload)
    88  	envelope, err := msg.Wrap(whisper.DefaultPoW, whisper.Options{
    89  		From: id,
    90  		To:   &id.PublicKey,
    91  		TTL:  whisper.DefaultTTL,
    92  	})
    93  	if err != nil {
    94  		return fmt.Errorf("failed to seal message: %v", err)
    95  	}
    96  	// Dump the message into the system and wait for it to pop back out
    97  	if err := shh.Send(envelope); err != nil {
    98  		return fmt.Errorf("failed to send self-message: %v", err)
    99  	}
   100  	select {
   101  	case <-ok:
   102  	case <-time.After(time.Second):
   103  		return fmt.Errorf("failed to receive message in time")
   104  	}
   105  	return nil
   106  }