github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:27</date> 10 //</624342588538753024> 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/nat" 29 "github.com/ethereum/go-ethereum/p2p/netutil" 30 ) 31 32 func main() { 33 var ( 34 listenAddr = flag.String("addr", ":30301", "listen address") 35 genKey = flag.String("genkey", "", "generate a node key") 36 writeAddr = flag.Bool("writeaddress", false, "write out the node's pubkey hash and quit") 37 nodeKeyFile = flag.String("nodekey", "", "private key filename") 38 nodeKeyHex = flag.String("nodekeyhex", "", "private key as hex (for testing)") 39 natdesc = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)") 40 netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)") 41 runv5 = flag.Bool("v5", false, "run a v5 topic discovery bootnode") 42 verbosity = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-9)") 43 vmodule = flag.String("vmodule", "", "log verbosity pattern") 44 45 nodeKey *ecdsa.PrivateKey 46 err error 47 ) 48 flag.Parse() 49 50 glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) 51 glogger.Verbosity(log.Lvl(*verbosity)) 52 glogger.Vmodule(*vmodule) 53 log.Root().SetHandler(glogger) 54 55 natm, err := nat.Parse(*natdesc) 56 if err != nil { 57 utils.Fatalf("-nat: %v", err) 58 } 59 switch { 60 case *genKey != "": 61 nodeKey, err = crypto.GenerateKey() 62 if err != nil { 63 utils.Fatalf("could not generate key: %v", err) 64 } 65 if err = crypto.SaveECDSA(*genKey, nodeKey); err != nil { 66 utils.Fatalf("%v", err) 67 } 68 return 69 case *nodeKeyFile == "" && *nodeKeyHex == "": 70 utils.Fatalf("Use -nodekey or -nodekeyhex to specify a private key") 71 case *nodeKeyFile != "" && *nodeKeyHex != "": 72 utils.Fatalf("Options -nodekey and -nodekeyhex are mutually exclusive") 73 case *nodeKeyFile != "": 74 if nodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil { 75 utils.Fatalf("-nodekey: %v", err) 76 } 77 case *nodeKeyHex != "": 78 if nodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil { 79 utils.Fatalf("-nodekeyhex: %v", err) 80 } 81 } 82 83 if *writeAddr { 84 fmt.Printf("%v\n", discover.PubkeyID(&nodeKey.PublicKey)) 85 os.Exit(0) 86 } 87 88 var restrictList *netutil.Netlist 89 if *netrestrict != "" { 90 restrictList, err = netutil.ParseNetlist(*netrestrict) 91 if err != nil { 92 utils.Fatalf("-netrestrict: %v", err) 93 } 94 } 95 96 addr, err := net.ResolveUDPAddr("udp", *listenAddr) 97 if err != nil { 98 utils.Fatalf("-ResolveUDPAddr: %v", err) 99 } 100 conn, err := net.ListenUDP("udp", addr) 101 if err != nil { 102 utils.Fatalf("-ListenUDP: %v", err) 103 } 104 105 realaddr := conn.LocalAddr().(*net.UDPAddr) 106 if natm != nil { 107 if !realaddr.IP.IsLoopback() { 108 go nat.Map(natm, nil, "udp", realaddr.Port, realaddr.Port, "ethereum discovery") 109 } 110 //TODO:随着时间的推移对外部IP更改做出响应。 111 if ext, err := natm.ExternalIP(); err == nil { 112 realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port} 113 } 114 } 115 116 if *runv5 { 117 if _, err := discv5.ListenUDP(nodeKey, conn, realaddr, "", restrictList); err != nil { 118 utils.Fatalf("%v", err) 119 } 120 } else { 121 cfg := discover.Config{ 122 PrivateKey: nodeKey, 123 AnnounceAddr: realaddr, 124 NetRestrict: restrictList, 125 } 126 if _, err := discover.ListenUDP(conn, cfg); err != nil { 127 utils.Fatalf("%v", err) 128 } 129 } 130 131 select {} 132 } 133