github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/cmd/bootnode/main.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:32</date> 10 //</624450067012521984> 11 12 13 //Bootnode为以太坊发现协议运行一个引导节点。 14 package main 15 16 import ( 17 "crypto/ecdsa" 18 "flag" 19 "fmt" 20 "net" 21 "os" 22 23 "github.com/ethereum/go-ethereum/cmd/utils" 24 "github.com/ethereum/go-ethereum/crypto" 25 "github.com/ethereum/go-ethereum/log" 26 "github.com/ethereum/go-ethereum/p2p/discover" 27 "github.com/ethereum/go-ethereum/p2p/discv5" 28 "github.com/ethereum/go-ethereum/p2p/enode" 29 "github.com/ethereum/go-ethereum/p2p/nat" 30 "github.com/ethereum/go-ethereum/p2p/netutil" 31 ) 32 33 func main() { 34 var ( 35 listenAddr = flag.String("addr", ":30301", "listen address") 36 genKey = flag.String("genkey", "", "generate a node key") 37 writeAddr = flag.Bool("writeaddress", false, "write out the node's public key and quit") 38 nodeKeyFile = flag.String("nodekey", "", "private key filename") 39 nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") 40 natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") 41 netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)") 42 runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode") 43 verbosity = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-9)") 44 vmodule = flag.String("vmodule", "", "log verbosity pattern") 45 46 nodeKey *ecdsa.PrivateKey 47 err error 48 ) 49 flag.Parse() 50 51 glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) 52 glogger.Verbosity(log.Lvl(*verbosity)) 53 glogger.Vmodule(*vmodule) 54 log.Root().SetHandler(glogger) 55 56 natm, err := nat.Parse(*natdesc) 57 if err != nil { 58 utils.Fatalf("-nat: %v", err) 59 } 60 switch { 61 case *genKey != "": 62 nodeKey, err = crypto.GenerateKey() 63 if err != nil { 64 utils.Fatalf("could not generate key: %v", err) 65 } 66 if err = crypto.SaveECDSA(*genKey, nodeKey); err != nil { 67 utils.Fatalf("%v", err) 68 } 69 return 70 case *nodeKeyFile == "" && *nodeKeyHex == "": 71 utils.Fatalf("Use -nodekey or -nodekeyhex to specify a private key") 72 case *nodeKeyFile != "" && *nodeKeyHex != "": 73 utils.Fatalf("Options -nodekey and -nodekeyhex are mutually exclusive") 74 case *nodeKeyFile != "": 75 if nodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { 76 utils.Fatalf("-nodekey: %v", err) 77 } 78 case *nodeKeyHex != "": 79 if nodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { 80 utils.Fatalf("-nodekeyhex: %v", err) 81 } 82 } 83 84 if *writeAddr { 85 fmt.Printf("%x\n", crypto.FromECDSAPub(&nodeKey.PublicKey)[1:]) 86 os.Exit(0) 87 } 88 89 var restrictList *netutil.Netlist 90 if *netrestrict != "" { 91 restrictList, err = netutil.ParseNetlist(*netrestrict) 92 if err != nil { 93 utils.Fatalf("-netrestrict: %v", err) 94 } 95 } 96 97 addr, err := net.ResolveUDPAddr("udp", *listenAddr) 98 if err != nil { 99 utils.Fatalf("-ResolveUDPAddr: %v", err) 100 } 101 conn, err := net.ListenUDP("udp", addr) 102 if err != nil { 103 utils.Fatalf("-ListenUDP: %v", err) 104 } 105 106 realaddr := conn.LocalAddr().(*net.UDPAddr) 107 if natm != nil { 108 if !realaddr.IP.IsLoopback() { 109 go nat.Map(natm, nil, "udp", realaddr.Port, realaddr.Port, "ethereum discovery") 110 } 111 //TODO:随着时间的推移对外部IP更改做出响应。 112 if ext, err := natm.ExternalIP(); err == nil { 113 realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port} 114 } 115 } 116 117 if *runv5 { 118 if _, err := discv5.ListenUDP(nodeKey, conn, "", restrictList); err != nil { 119 utils.Fatalf("%v", err) 120 } 121 } else { 122 db, _ := enode.OpenDB("") 123 ln := enode.NewLocalNode(db, nodeKey) 124 cfg := discover.Config{ 125 PrivateKey: nodeKey, 126 NetRestrict: restrictList, 127 } 128 if _, err := discover.ListenUDP(conn, ln, cfg); err != nil { 129 utils.Fatalf("%v", err) 130 } 131 } 132 133 select {} 134 } 135