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