github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/cmd/wnode/main.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2017 Go Ethereum作者 10 //此文件是Go以太坊的一部分。 11 // 12 //Go以太坊是免费软件:您可以重新发布和/或修改它 13 //根据GNU通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊的分布希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU通用公共许可证了解更多详细信息。 21 // 22 //你应该已经收到一份GNU通用公共许可证的副本 23 //一起去以太坊吧。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 //这是一个简单的耳语节点。它可以用作独立的引导节点。 26 //也可用于不同的测试和诊断目的。 27 28 package main 29 30 import ( 31 "bufio" 32 "crypto/ecdsa" 33 crand "crypto/rand" 34 "crypto/sha512" 35 "encoding/binary" 36 "encoding/hex" 37 "flag" 38 "fmt" 39 "io/ioutil" 40 "os" 41 "path/filepath" 42 "strconv" 43 "strings" 44 "time" 45 46 "github.com/ethereum/go-ethereum/cmd/utils" 47 "github.com/ethereum/go-ethereum/common" 48 "github.com/ethereum/go-ethereum/console" 49 "github.com/ethereum/go-ethereum/crypto" 50 "github.com/ethereum/go-ethereum/log" 51 "github.com/ethereum/go-ethereum/p2p" 52 "github.com/ethereum/go-ethereum/p2p/discover" 53 "github.com/ethereum/go-ethereum/p2p/nat" 54 "github.com/ethereum/go-ethereum/whisper/mailserver" 55 whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" 56 "golang.org/x/crypto/pbkdf2" 57 ) 58 59 const quitCommand = "~Q" 60 const entropySize = 32 61 62 //独生子女 63 var ( 64 server *p2p.Server 65 shh *whisper.Whisper 66 done chan struct{} 67 mailServer mailserver.WMailServer 68 entropy [entropySize]byte 69 70 input = bufio.NewReader(os.Stdin) 71 ) 72 73 //加密 74 var ( 75 symKey []byte 76 pub *ecdsa.PublicKey 77 asymKey *ecdsa.PrivateKey 78 nodeid *ecdsa.PrivateKey 79 topic whisper.TopicType 80 81 asymKeyID string 82 asymFilterID string 83 symFilterID string 84 symPass string 85 msPassword string 86 ) 87 88 //CMD参数 89 var ( 90 bootstrapMode = flag.Bool("standalone", false, "boostrap node: don't initiate connection to peers, just wait for incoming connections") 91 forwarderMode = flag.Bool("forwarder", false, "forwarder mode: only forward messages, neither encrypt nor decrypt messages") 92 mailServerMode = flag.Bool("mailserver", false, "mail server mode: delivers expired messages on demand") 93 requestMail = flag.Bool("mailclient", false, "request expired messages from the bootstrap server") 94 asymmetricMode = flag.Bool("asym", false, "use asymmetric encryption") 95 generateKey = flag.Bool("generatekey", false, "generate and show the private key") 96 fileExMode = flag.Bool("fileexchange", false, "file exchange mode") 97 fileReader = flag.Bool("filereader", false, "load and decrypt messages saved as files, display as plain text") 98 testMode = flag.Bool("test", false, "use of predefined parameters for diagnostics (password, etc.)") 99 echoMode = flag.Bool("echo", false, "echo mode: prints some arguments for diagnostics") 100 101 argVerbosity = flag.Int("verbosity", int(log.LvlError), "log verbosity level") 102 argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds") 103 argWorkTime = flag.Uint("work", 5, "work time in seconds") 104 argMaxSize = flag.Uint("maxsize", uint(whisper.DefaultMaxMessageSize), "max size of message") 105 argPoW = flag.Float64("pow", whisper.DefaultMinimumPoW, "PoW for normal messages in float format (e.g. 2.7)") 106 argServerPoW = flag.Float64("mspow", whisper.DefaultMinimumPoW, "PoW requirement for Mail Server request") 107 108 argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)") 109 argPub = flag.String("pub", "", "public key for asymmetric encryption") 110 argDBPath = flag.String("dbpath", "", "path to the server's DB directory") 111 argIDFile = flag.String("idfile", "", "file name with node id (private key)") 112 argEnode = flag.String("boot", "", "bootstrap node you want to connect to (e.g. enode://E454……08D50@52.176.211.200:16428)”) 113 argTopic = flag.String("topic", "", "topic in hexadecimal format (e.g. 70a4beef)") 114 argSaveDir = flag.String("savedir", "", "directory where all incoming messages will be saved as files") 115 ) 116 117 func main() { 118 processArgs() 119 initialize() 120 run() 121 shutdown() 122 } 123 124 func processArgs() { 125 flag.Parse() 126 127 if len(*argIDFile) > 0 { 128 var err error 129 nodeid, err = crypto.LoadECDSA(*argIDFile) 130 if err != nil { 131 utils.Fatalf("Failed to load file [%s]: %s.", *argIDFile, err) 132 } 133 } 134 135 const enodePrefix = "enode://“ 136 if len(*argEnode) > 0 { 137 if (*argEnode)[:len(enodePrefix)] != enodePrefix { 138 *argEnode = enodePrefix + *argEnode 139 } 140 } 141 142 if len(*argTopic) > 0 { 143 x, err := hex.DecodeString(*argTopic) 144 if err != nil { 145 utils.Fatalf("Failed to parse the topic: %s", err) 146 } 147 topic = whisper.BytesToTopic(x) 148 } 149 150 if *asymmetricMode && len(*argPub) > 0 { 151 var err error 152 if pub, err = crypto.UnmarshalPubkey(common.FromHex(*argPub)); err != nil { 153 utils.Fatalf("invalid public key") 154 } 155 } 156 157 if len(*argSaveDir) > 0 { 158 if _, err := os.Stat(*argSaveDir); os.IsNotExist(err) { 159 utils.Fatalf("Download directory '%s' does not exist", *argSaveDir) 160 } 161 } else if *fileExMode { 162 utils.Fatalf("Parameter 'savedir' is mandatory for file exchange mode") 163 } 164 165 if *echoMode { 166 echo() 167 } 168 } 169 170 func echo() { 171 fmt.Printf("ttl = %d \n", *argTTL) 172 fmt.Printf("workTime = %d \n", *argWorkTime) 173 fmt.Printf("pow = %f \n", *argPoW) 174 fmt.Printf("mspow = %f \n", *argServerPoW) 175 fmt.Printf("ip = %s \n", *argIP) 176 fmt.Printf("pub = %s \n", common.ToHex(crypto.FromECDSAPub(pub))) 177 fmt.Printf("idfile = %s \n", *argIDFile) 178 fmt.Printf("dbpath = %s \n", *argDBPath) 179 fmt.Printf("boot = %s \n", *argEnode) 180 } 181 182 func initialize() { 183 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*argVerbosity), log.StreamHandler(os.Stderr, log.TerminalFormat(false)))) 184 185 done = make(chan struct{}) 186 var peers []*discover.Node 187 var err error 188 189 if *generateKey { 190 key, err := crypto.GenerateKey() 191 if err != nil { 192 utils.Fatalf("Failed to generate private key: %s", err) 193 } 194 k := hex.EncodeToString(crypto.FromECDSA(key)) 195 fmt.Printf("Random private key: %s \n", k) 196 os.Exit(0) 197 } 198 199 if *testMode { 200 symPass = "wwww" //ASCII码:0x77777777 201 msPassword = "wwww" 202 } 203 204 if *bootstrapMode { 205 if len(*argIP) == 0 { 206 argIP = scanLineA("Please enter your IP and port (e.g. 127.0.0.1:30348): ") 207 } 208 } else if *fileReader { 209 *bootstrapMode = true 210 } else { 211 if len(*argEnode) == 0 { 212 argEnode = scanLineA("Please enter the peer's enode: ") 213 } 214 peer := discover.MustParseNode(*argEnode) 215 peers = append(peers, peer) 216 } 217 218 if *mailServerMode { 219 if len(msPassword) == 0 { 220 msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ") 221 if err != nil { 222 utils.Fatalf("Failed to read Mail Server password: %s", err) 223 } 224 } 225 } 226 227 cfg := &whisper.Config{ 228 MaxMessageSize: uint32(*argMaxSize), 229 MinimumAcceptedPOW: *argPoW, 230 } 231 232 shh = whisper.New(cfg) 233 234 if *argPoW != whisper.DefaultMinimumPoW { 235 err := shh.SetMinimumPoW(*argPoW) 236 if err != nil { 237 utils.Fatalf("Failed to set PoW: %s", err) 238 } 239 } 240 241 if uint32(*argMaxSize) != whisper.DefaultMaxMessageSize { 242 err := shh.SetMaxMessageSize(uint32(*argMaxSize)) 243 if err != nil { 244 utils.Fatalf("Failed to set max message size: %s", err) 245 } 246 } 247 248 asymKeyID, err = shh.NewKeyPair() 249 if err != nil { 250 utils.Fatalf("Failed to generate a new key pair: %s", err) 251 } 252 253 asymKey, err = shh.GetPrivateKey(asymKeyID) 254 if err != nil { 255 utils.Fatalf("Failed to retrieve a new key pair: %s", err) 256 } 257 258 if nodeid == nil { 259 tmpID, err := shh.NewKeyPair() 260 if err != nil { 261 utils.Fatalf("Failed to generate a new key pair: %s", err) 262 } 263 264 nodeid, err = shh.GetPrivateKey(tmpID) 265 if err != nil { 266 utils.Fatalf("Failed to retrieve a new key pair: %s", err) 267 } 268 } 269 270 maxPeers := 80 271 if *bootstrapMode { 272 maxPeers = 800 273 } 274 275 _, err = crand.Read(entropy[:]) 276 if err != nil { 277 utils.Fatalf("crypto/rand failed: %s", err) 278 } 279 280 if *mailServerMode { 281 shh.RegisterServer(&mailServer) 282 if err := mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW); err != nil { 283 utils.Fatalf("Failed to init MailServer: %s", err) 284 } 285 } 286 287 server = &p2p.Server{ 288 Config: p2p.Config{ 289 PrivateKey: nodeid, 290 MaxPeers: maxPeers, 291 Name: common.MakeName("wnode", "6.0"), 292 Protocols: shh.Protocols(), 293 ListenAddr: *argIP, 294 NAT: nat.Any(), 295 BootstrapNodes: peers, 296 StaticNodes: peers, 297 TrustedNodes: peers, 298 }, 299 } 300 } 301 302 func startServer() error { 303 err := server.Start() 304 if err != nil { 305 fmt.Printf("Failed to start Whisper peer: %s.", err) 306 return err 307 } 308 309 fmt.Printf("my public key: %s \n", common.ToHex(crypto.FromECDSAPub(&asymKey.PublicKey))) 310 fmt.Println(server.NodeInfo().Enode) 311 312 if *bootstrapMode { 313 configureNode() 314 fmt.Println("Bootstrap Whisper node started") 315 } else { 316 fmt.Println("Whisper node started") 317 //首先看看我们是否可以建立连接,然后请求用户输入 318 waitForConnection(true) 319 configureNode() 320 } 321 322 if *fileExMode { 323 fmt.Printf("Please type the file name to be send. To quit type: '%s'\n", quitCommand) 324 } else if *fileReader { 325 fmt.Printf("Please type the file name to be decrypted. To quit type: '%s'\n", quitCommand) 326 } else if !*forwarderMode { 327 fmt.Printf("Please type the message. To quit type: '%s'\n", quitCommand) 328 } 329 return nil 330 } 331 332 func configureNode() { 333 var err error 334 var p2pAccept bool 335 336 if *forwarderMode { 337 return 338 } 339 340 if *asymmetricMode { 341 if len(*argPub) == 0 { 342 s := scanLine("Please enter the peer's public key: ") 343 b := common.FromHex(s) 344 if b == nil { 345 utils.Fatalf("Error: can not convert hexadecimal string") 346 } 347 if pub, err = crypto.UnmarshalPubkey(b); err != nil { 348 utils.Fatalf("Error: invalid peer public key") 349 } 350 } 351 } 352 353 if *requestMail { 354 p2pAccept = true 355 if len(msPassword) == 0 { 356 msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ") 357 if err != nil { 358 utils.Fatalf("Failed to read Mail Server password: %s", err) 359 } 360 } 361 } 362 363 if !*asymmetricMode && !*forwarderMode { 364 if len(symPass) == 0 { 365 symPass, err = console.Stdin.PromptPassword("Please enter the password for symmetric encryption: ") 366 if err != nil { 367 utils.Fatalf("Failed to read passphrase: %v", err) 368 } 369 } 370 371 symKeyID, err := shh.AddSymKeyFromPassword(symPass) 372 if err != nil { 373 utils.Fatalf("Failed to create symmetric key: %s", err) 374 } 375 symKey, err = shh.GetSymKey(symKeyID) 376 if err != nil { 377 utils.Fatalf("Failed to save symmetric key: %s", err) 378 } 379 if len(*argTopic) == 0 { 380 generateTopic([]byte(symPass)) 381 } 382 383 fmt.Printf("Filter is configured for the topic: %x \n", topic) 384 } 385 386 if *mailServerMode { 387 if len(*argDBPath) == 0 { 388 argDBPath = scanLineA("Please enter the path to DB file: ") 389 } 390 } 391 392 symFilter := whisper.Filter{ 393 KeySym: symKey, 394 Topics: [][]byte{topic[:]}, 395 AllowP2P: p2pAccept, 396 } 397 symFilterID, err = shh.Subscribe(&symFilter) 398 if err != nil { 399 utils.Fatalf("Failed to install filter: %s", err) 400 } 401 402 asymFilter := whisper.Filter{ 403 KeyAsym: asymKey, 404 Topics: [][]byte{topic[:]}, 405 AllowP2P: p2pAccept, 406 } 407 asymFilterID, err = shh.Subscribe(&asymFilter) 408 if err != nil { 409 utils.Fatalf("Failed to install filter: %s", err) 410 } 411 } 412 413 func generateTopic(password []byte) { 414 x := pbkdf2.Key(password, password, 4096, 128, sha512.New) 415 for i := 0; i < len(x); i++ { 416 topic[i%whisper.TopicLength] ^= x[i] 417 } 418 } 419 420 func waitForConnection(timeout bool) { 421 var cnt int 422 var connected bool 423 for !connected { 424 time.Sleep(time.Millisecond * 50) 425 connected = server.PeerCount() > 0 426 if timeout { 427 cnt++ 428 if cnt > 1000 { 429 utils.Fatalf("Timeout expired, failed to connect") 430 } 431 } 432 } 433 434 fmt.Println("Connected to peer.") 435 } 436 437 func run() { 438 err := startServer() 439 if err != nil { 440 return 441 } 442 defer server.Stop() 443 shh.Start(nil) 444 defer shh.Stop() 445 446 if !*forwarderMode { 447 go messageLoop() 448 } 449 450 if *requestMail { 451 requestExpiredMessagesLoop() 452 } else if *fileExMode { 453 sendFilesLoop() 454 } else if *fileReader { 455 fileReaderLoop() 456 } else { 457 sendLoop() 458 } 459 } 460 461 func shutdown() { 462 close(done) 463 mailServer.Close() 464 } 465 466 func sendLoop() { 467 for { 468 s := scanLine("") 469 if s == quitCommand { 470 fmt.Println("Quit command received") 471 return 472 } 473 sendMsg([]byte(s)) 474 if *asymmetricMode { 475 //为方便起见,请打印您自己的消息, 476 //因为在非对称模式下是不可能解密的 477 timestamp := time.Now().Unix() 478 from := crypto.PubkeyToAddress(asymKey.PublicKey) 479 fmt.Printf("\n%d <%x>: %s\n", timestamp, from, s) 480 } 481 } 482 } 483 484 func sendFilesLoop() { 485 for { 486 s := scanLine("") 487 if s == quitCommand { 488 fmt.Println("Quit command received") 489 return 490 } 491 b, err := ioutil.ReadFile(s) 492 if err != nil { 493 fmt.Printf(">>> Error: %s \n", err) 494 } else { 495 h := sendMsg(b) 496 if (h == common.Hash{}) { 497 fmt.Printf(">>> Error: message was not sent \n") 498 } else { 499 timestamp := time.Now().Unix() 500 from := crypto.PubkeyToAddress(asymKey.PublicKey) 501 fmt.Printf("\n%d <%x>: sent message with hash %x\n", timestamp, from, h) 502 } 503 } 504 } 505 } 506 507 func fileReaderLoop() { 508 watcher1 := shh.GetFilter(symFilterID) 509 watcher2 := shh.GetFilter(asymFilterID) 510 if watcher1 == nil && watcher2 == nil { 511 fmt.Println("Error: neither symmetric nor asymmetric filter is installed") 512 return 513 } 514 515 for { 516 s := scanLine("") 517 if s == quitCommand { 518 fmt.Println("Quit command received") 519 return 520 } 521 raw, err := ioutil.ReadFile(s) 522 if err != nil { 523 fmt.Printf(">>> Error: %s \n", err) 524 } else { 525 env := whisper.Envelope{Data: raw} //主题为零 526 msg := env.Open(watcher1) //不管主题如何,都强制打开信封 527 if msg == nil { 528 msg = env.Open(watcher2) 529 } 530 if msg == nil { 531 fmt.Printf(">>> Error: failed to decrypt the message \n") 532 } else { 533 printMessageInfo(msg) 534 } 535 } 536 } 537 } 538 539 func scanLine(prompt string) string { 540 if len(prompt) > 0 { 541 fmt.Print(prompt) 542 } 543 txt, err := input.ReadString('\n') 544 if err != nil { 545 utils.Fatalf("input error: %s", err) 546 } 547 txt = strings.TrimRight(txt, "\n\r") 548 return txt 549 } 550 551 func scanLineA(prompt string) *string { 552 s := scanLine(prompt) 553 return &s 554 } 555 556 func scanUint(prompt string) uint32 { 557 s := scanLine(prompt) 558 i, err := strconv.Atoi(s) 559 if err != nil { 560 utils.Fatalf("Fail to parse the lower time limit: %s", err) 561 } 562 return uint32(i) 563 } 564 565 func sendMsg(payload []byte) common.Hash { 566 params := whisper.MessageParams{ 567 Src: asymKey, 568 Dst: pub, 569 KeySym: symKey, 570 Payload: payload, 571 Topic: topic, 572 TTL: uint32(*argTTL), 573 PoW: *argPoW, 574 WorkTime: uint32(*argWorkTime), 575 } 576 577 msg, err := whisper.NewSentMessage(¶ms) 578 if err != nil { 579 utils.Fatalf("failed to create new message: %s", err) 580 } 581 582 envelope, err := msg.Wrap(¶ms) 583 if err != nil { 584 fmt.Printf("failed to seal message: %v \n", err) 585 return common.Hash{} 586 } 587 588 err = shh.Send(envelope) 589 if err != nil { 590 fmt.Printf("failed to send message: %v \n", err) 591 return common.Hash{} 592 } 593 594 return envelope.Hash() 595 } 596 597 func messageLoop() { 598 sf := shh.GetFilter(symFilterID) 599 if sf == nil { 600 utils.Fatalf("symmetric filter is not installed") 601 } 602 603 af := shh.GetFilter(asymFilterID) 604 if af == nil { 605 utils.Fatalf("asymmetric filter is not installed") 606 } 607 608 ticker := time.NewTicker(time.Millisecond * 50) 609 610 for { 611 select { 612 case <-ticker.C: 613 m1 := sf.Retrieve() 614 m2 := af.Retrieve() 615 messages := append(m1, m2...) 616 for _, msg := range messages { 617 reportedOnce := false 618 if !*fileExMode && len(msg.Payload) <= 2048 { 619 printMessageInfo(msg) 620 reportedOnce = true 621 } 622 623 //在指定argsavedir时保存所有消息。 624 // 625 //如果fileexmode==true,则只显示哈希值,因为消息可能太大。 626 if len(*argSaveDir) > 0 { 627 writeMessageToFile(*argSaveDir, msg, !reportedOnce) 628 } 629 } 630 case <-done: 631 return 632 } 633 } 634 } 635 636 func printMessageInfo(msg *whisper.ReceivedMessage) { 637 timestamp := fmt.Sprintf("%d", msg.Sent) //用于诊断的Unix时间戳 638 text := string(msg.Payload) 639 640 var address common.Address 641 if msg.Src != nil { 642 address = crypto.PubkeyToAddress(*msg.Src) 643 } 644 645 if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) { 646 fmt.Printf("\n%s <%x>: %s\n", timestamp, address, text) //我的信息 647 } else { 648 fmt.Printf("\n%s [%x]: %s\n", timestamp, address, text) // 649 } 650 } 651 652 func writeMessageToFile(dir string, msg *whisper.ReceivedMessage, show bool) { 653 if len(dir) == 0 { 654 return 655 } 656 657 timestamp := fmt.Sprintf("%d", msg.Sent) 658 name := fmt.Sprintf("%x", msg.EnvelopeHash) 659 660 var address common.Address 661 if msg.Src != nil { 662 address = crypto.PubkeyToAddress(*msg.Src) 663 } 664 665 env := shh.GetEnvelope(msg.EnvelopeHash) 666 if env == nil { 667 fmt.Printf("\nUnexpected error: envelope not found: %x\n", msg.EnvelopeHash) 668 return 669 } 670 671 //这是一个示例代码;如果不想保存自己的消息,请取消注释。 672 //如果whisper.ispubkeyequal(msg.src,&asymkey.publickey) 673 //fmt.printf(“\n%s<%x>:我收到的消息,未保存:“%s'\n”,时间戳,地址,名称) 674 //返回 675 //} 676 677 fullpath := filepath.Join(dir, name) 678 err := ioutil.WriteFile(fullpath, env.Data, 0644) 679 if err != nil { 680 fmt.Printf("\n%s {%x}: message received but not saved: %s\n", timestamp, address, err) 681 } else if show { 682 fmt.Printf("\n%s {%x}: message received and saved as '%s' (%d bytes)\n", timestamp, address, name, len(env.Data)) 683 } 684 } 685 686 func requestExpiredMessagesLoop() { 687 var key, peerID, bloom []byte 688 var timeLow, timeUpp uint32 689 var t string 690 var xt whisper.TopicType 691 692 keyID, err := shh.AddSymKeyFromPassword(msPassword) 693 if err != nil { 694 utils.Fatalf("Failed to create symmetric key for mail request: %s", err) 695 } 696 key, err = shh.GetSymKey(keyID) 697 if err != nil { 698 utils.Fatalf("Failed to save symmetric key for mail request: %s", err) 699 } 700 peerID = extractIDFromEnode(*argEnode) 701 shh.AllowP2PMessagesFromPeer(peerID) 702 703 for { 704 timeLow = scanUint("Please enter the lower limit of the time range (unix timestamp): ") 705 timeUpp = scanUint("Please enter the upper limit of the time range (unix timestamp): ") 706 t = scanLine("Enter the topic (hex). Press enter to request all messages, regardless of the topic: ") 707 if len(t) == whisper.TopicLength*2 { 708 x, err := hex.DecodeString(t) 709 if err != nil { 710 fmt.Printf("Failed to parse the topic: %s \n", err) 711 continue 712 } 713 xt = whisper.BytesToTopic(x) 714 bloom = whisper.TopicToBloom(xt) 715 obfuscateBloom(bloom) 716 } else if len(t) == 0 { 717 bloom = whisper.MakeFullNodeBloom() 718 } else { 719 fmt.Println("Error: topic is invalid, request aborted") 720 continue 721 } 722 723 if timeUpp == 0 { 724 timeUpp = 0xFFFFFFFF 725 } 726 727 data := make([]byte, 8, 8+whisper.BloomFilterSize) 728 binary.BigEndian.PutUint32(data, timeLow) 729 binary.BigEndian.PutUint32(data[4:], timeUpp) 730 data = append(data, bloom...) 731 732 var params whisper.MessageParams 733 params.PoW = *argServerPoW 734 params.Payload = data 735 params.KeySym = key 736 params.Src = asymKey 737 params.WorkTime = 5 738 739 msg, err := whisper.NewSentMessage(¶ms) 740 if err != nil { 741 utils.Fatalf("failed to create new message: %s", err) 742 } 743 env, err := msg.Wrap(¶ms) 744 if err != nil { 745 utils.Fatalf("Wrap failed: %s", err) 746 } 747 748 err = shh.RequestHistoricMessages(peerID, env) 749 if err != nil { 750 utils.Fatalf("Failed to send P2P message: %s", err) 751 } 752 753 time.Sleep(time.Second * 5) 754 } 755 } 756 757 func extractIDFromEnode(s string) []byte { 758 n, err := discover.ParseNode(s) 759 if err != nil { 760 utils.Fatalf("Failed to parse enode: %s", err) 761 } 762 return n.ID[:] 763 } 764 765 //模糊布卢姆增加16个随机位的布卢姆 766 //筛选,以便混淆包含的主题。 767 //它在每个会话中都具有确定性。 768 //尽管有额外的位,它将平均匹配 769 //比完整节点的Bloom过滤器少32000倍的消息。 770 func obfuscateBloom(bloom []byte) { 771 const half = entropySize / 2 772 for i := 0; i < half; i++ { 773 x := int(entropy[i]) 774 if entropy[half+i] < 128 { 775 x += 256 776 } 777 778 bloom[x/8] = 1 << uint(x%8) //设置位号x 779 } 780 }