github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/cmd/bootnode/main.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU 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  // go-ethereum 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 General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // bootnode runs a bootstrap node for the Ethereum Discovery Protocol.
    18  package main
    19  
    20  import (
    21  	"crypto/ecdsa"
    22  	"flag"
    23  	"fmt"
    24  	"github.com/ethereum/go-ethereum/cmd/utils"
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/config"
    27  	"github.com/ethereum/go-ethereum/crypto"
    28  	"github.com/ethereum/go-ethereum/log"
    29  	"github.com/ethereum/go-ethereum/p2p/discover"
    30  	"github.com/ethereum/go-ethereum/p2p/discv5"
    31  	"github.com/ethereum/go-ethereum/p2p/nat"
    32  	"github.com/ethereum/go-ethereum/p2p/netutil"
    33  	"github.com/ethereum/go-ethereum/qmanager/global"
    34  	"net"
    35  	"os"
    36  	"strings"
    37  )
    38  // setNodeKey creates a node key from set command line flags, either loading it
    39  // from a file or as a specified hex value. If neither flags were provided, this
    40  // method returns nil and an emphemeral key is to be generated.
    41  /* func setNodeKey(ctx *cli.Context, cfg *p2p.Config) {
    42  	var (
    43  		hex  = ctx.GlobalString(NodeKeyHexFlag.Name)
    44  		file = ctx.GlobalString(NodeKeyFileFlag.Name)
    45  		key  *ecdsa.PrivateKey
    46  		err  error
    47  	)
    48  	switch {
    49  	case file != "" && hex != "":
    50  		Fatalf("Options %q and %q are mutually exclusive", NodeKeyFileFlag.Name, NodeKeyHexFlag.Name)
    51  	case file != "":
    52  		if key, err = crypto.LoadECDSA(file); err != nil {  //산출되는 key 가 20바이트 Address 인가?
    53  			Fatalf("Option %q: %v", NodeKeyFileFlag.Name, err)  //
    54  		}
    55  		cfg.PrivateKey = key
    56  	case hex != "":
    57  		if key, err = crypto.HexToECDSA(hex); err != nil {
    58  			Fatalf("Option %q: %v", NodeKeyHexFlag.Name, err)
    59  		}
    60  		cfg.PrivateKey = key
    61  	}
    62  } */
    63  
    64  /**
    65   * SimpleBackend
    66   * Private key: bb047e5940b6d83354d9432db7c449ac8fca2248008aaa7271369880f9f11cc1
    67   * Public key: 04a2bfb0f7da9e1b9c0c64e14f87e8fb82eb0144e97c25fe3a977a921041a50976984d18257d2495e7bfd3d4b280220217f429287d252b0d7c0f7aae9aa624
    68                 c0001a6a20
    69  
    70                 5d686a07e38d2862322a2b7e829ee90c9931f119391c63328cab0d56506783588e46cb16dc2a0e920cf1a6a68806e6129b986b6b143cdb7d0752dec45a7f12c
    71   * Address: 0x26ea01d982c8aeafab7f440084f90fe078cba92
    72  
    73  
    74  // nodekey  : 0d53d73629f75adcecd6fc1eb1c1ecb1e6a20e82a2227c0905b5bc0440be6036
    75  
    76   */
    77  func getAddress() common.Address {
    78  	return common.HexToAddress("0x70524d664ffe731100208a0154e556f9bb679ae6")
    79  }
    80  
    81  func getInvalidAddress() common.Address {
    82  	return common.HexToAddress("0x9535b2e7faaba5288511d89341d94a38063a349b")
    83  }
    84  
    85  func generatePrivateKey() (*ecdsa.PrivateKey, error) {
    86  	key := "bb047e5940b6d83354d9432db7c449ac8fca2248008aaa7271369880f9f11cc1"
    87  	return crypto.HexToECDSA(key)
    88  }
    89  /*
    90  func newTestValidatorSet(n int) (istanbul.ValidatorSet, []*ecdsa.PrivateKey) {
    91  	// generate validators
    92  	keys := make(Keys, n)
    93  	addrs := make([]common.Address, n)
    94  	for i := 0; i < n; i++ {
    95  		privateKey, _ := crypto.GenerateKey()
    96  		keys[i] = privateKey
    97  		addrs[i] = crypto.PubkeyToAddress(privateKey.PublicKey)
    98  	}
    99  //	vset := validator.NewSet(addrs, istanbul.RoundRobin)
   100  	sort.Sort(keys) //Keys need to be sorted by its public key address
   101  	return vset, keys
   102  }
   103  */
   104  
   105  type Keys []*ecdsa.PrivateKey
   106  
   107  func (slice Keys) Len() int {
   108  	return len(slice)
   109  }
   110  
   111  func (slice Keys) Less(i, j int) bool {
   112  	return strings.Compare(crypto.PubkeyToAddress(slice[i].PublicKey).String(), crypto.PubkeyToAddress(slice[j].PublicKey).String()) < 0
   113  }
   114  
   115  func (slice Keys) Swap(i, j int) {
   116  	slice[i], slice[j] = slice[j], slice[i]
   117  }
   118  /*
   119  func newSimpleBackend() (backend *simpleBackend, validatorKeys Keys, validatorSet istanbul.ValidatorSet) {
   120  	key, _ := generatePrivateKey()
   121  	validatorSet, validatorKeys = newTestValidatorSet(5)
   122  	backend = &simpleBackend{
   123  		privateKey: key,
   124  		logger:     log.New("backend", "simple"),
   125  		commitCh:   make(chan *types.Block, 1),
   126  	}
   127  	return
   128  }
   129  */
   130  // FromECDSA exports a private key into a binary dump.
   131  /* func FromECDSA(priv *ecdsa.PrivateKey) []byte {
   132  	if priv == nil {
   133  		return nil
   134  	}
   135  	return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
   136  }
   137  // Keccak256Hash calculates and returns the Keccak256 hash of the input data,
   138  // converting it to an internal Hash data structure.
   139  func Keccak256Hash(data ...[]byte) (h common.Hash) {
   140  	d := sha3.NewKeccak256()
   141  	for _, b := range data {
   142  		d.Write(b)
   143  	}
   144  	d.Sum(h[:0])
   145  	return h
   146  } */
   147  func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
   148  	pubBytes := crypto.FromECDSAPub(&p)
   149  	return common.BytesToAddress(crypto.Keccak256(pubBytes[1:])[12:])
   150  }
   151  /*
   152  type conn struct {
   153  	fd net.Conn
   154  	p2p.transport
   155  	flags connFlag
   156  	cont  chan error      // The run loop uses cont to signal errors to setupConn.
   157  	id    discover.NodeID // valid after the encryption handshake
   158  	caps  []Cap           // valid after the protocol handshake
   159  	name  string          // valid after the protocol handshake
   160  } */
   161  
   162  // Peer represents a connected remote node.
   163  /* type Peer struct {
   164  	rw      *p2p.conn
   165  	running map[string]*p2p.protoRW
   166  	log     log.Logger
   167  	//created mclock.AbsTime
   168  
   169  	wg       sync.WaitGroup
   170  	protoErr chan error
   171  	closed   chan struct{}
   172  //	disc     chan DiscReason
   173  } */
   174  /*
   175  func  sendEvent2(event istanbul.ConsensusDataEvent) {
   176  	// FIXME: it's inefficient because it retrieves all peers every time
   177  	//p := pm.findPeer(event.Target)
   178  	var p  *p2p.Peer=&{
   179  		rw : 1
   180  	}
   181  
   182  	if p == nil {
   183  		log.Warn("Failed to find peer by address", "addr", event.Target)
   184  		return
   185  	}
   186  	p2p.Send(p.rw, 0, event.Data)
   187  } */
   188  func GetLocalIP() string {
   189  	addrs, err := net.InterfaceAddrs()
   190  	if err != nil {
   191  		return ""
   192  	}
   193  	for _, address := range addrs {
   194  		// check the address type and if it is not a loopback the display it
   195  		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
   196  			if ipnet.IP.To4() != nil {
   197  				return ipnet.IP.String()
   198  			}
   199  		}
   200  	}
   201  	return ""
   202  }
   203  func main() {
   204  	var (
   205  		listenAddr  = flag.String("addr", ":30391", "listen address")
   206  		port        = flag.String("port", ":30391", "port")
   207  		genKey      = flag.String("genkey", "", "generate a node key")
   208  		writeAddr   = flag.Bool("writeAddress", false, "write out the node's pubkey hash and quit")
   209  		writeAccount   = flag.Bool("writeAccount", false, "write out the node's account hash and quit")
   210  		nodeKeyFile = flag.String("nodekey", "", "private key filename")
   211  		nodeKeyHex  = flag.String("nodekeyhex", "", "private key as hex (for testing)")
   212  		natdesc     = flag.String("nat", "none", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)")
   213  		netrestrict = flag.String("netrestrict", "", "restrict network communication to the given IP networks (CIDR masks)")
   214  		runv5       = flag.Bool("v5", false, "run a v5 topic discovery bootnode")
   215  		verbosity   = flag.Int("verbosity", int(log.LvlInfo), "log verbosity (0-9)")
   216  		vmodule     = flag.String("vmodule", "", "log verbosity pattern")
   217  		qman        = flag.String( "qman", "", "boot as bootnode and qmanager")
   218  
   219  		nodeKey *ecdsa.PrivateKey
   220  		//key  *ecdsa.PrivateKey
   221  		err     error
   222  	)
   223  	flag.Parse()
   224  
   225  	glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false)))
   226  	//glogger.Qmanager()
   227  	glogger.Verbosity(log.Lvl(*verbosity))
   228  	glogger.Vmodule(*vmodule)
   229  	log.Root().SetHandler(glogger)
   230  
   231  	natm, err := nat.Parse(*natdesc)
   232  	if err != nil {
   233  		utils.Fatalf("-nat: %v", err)
   234  	}
   235  	switch {
   236  	case *genKey != "":
   237  		nodeKey, err = crypto.GenerateKey()  //private key와 public key를 쌍으로 생성하고, private key 구조체는 public key를 담고 있다.
   238  
   239  		fmt.Printf("nodeKey(Private key)= %v\n, public Key= %v\n", nodeKey, nodeKey.Public() )
   240  		if err != nil {
   241  			utils.Fatalf("could not generate key: %v", err)
   242  		}
   243  		if err = crypto.SaveECDSA(*genKey, nodeKey); err != nil {
   244  			utils.Fatalf("%v", err)
   245  		}
   246  		return
   247  	case *nodeKeyFile == "" && *nodeKeyHex == "":
   248  		utils.Fatalf("Use -nodekey or -nodekeyhex to specify a private key")
   249  	case *nodeKeyFile != "" && *nodeKeyHex != "":
   250  		utils.Fatalf("Options -nodekey and -nodekeyhex are mutually exclusive")
   251  	case *nodeKeyFile != "":
   252  		if nodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil {
   253  			fmt.Printf("%v\n", nodeKey )
   254  		}
   255  
   256  //			fmt.Printf("read nodekey= %x\n, read nodekey(Public)= %x\n", nodeKey, nodeKey.Public() )
   257  		if(err != nil) {
   258  			fmt.Printf("%v\n", nodeKey )
   259  
   260  			utils.Fatalf("-nodekey: %v", err)
   261  		}
   262  
   263  	case *nodeKeyHex != "":
   264  		if nodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil {
   265  			utils.Fatalf("-nodekeyhex: %v", err)
   266  		}
   267  		fmt.Printf("return private key from nodekey= %x\n", nodeKey )
   268  
   269  	}
   270  
   271  	if *writeAddr {
   272  		fmt.Printf("%v\n", discover.PubkeyID(&nodeKey.PublicKey))
   273  		os.Exit(0)
   274  	}
   275  	if *writeAccount {
   276  		var account common.Address
   277  		account = PubkeyToAddress(nodeKey.PublicKey)
   278  		fmt.Printf("Address(20byte account) : %v\n, %x\n", account ,account )
   279  		// sendEvent sends a p2p message with given data to a peer
   280  
   281  
   282  		//var accountfile string
   283  		//if err = crypto.SaveECDSA(accountfile, account); err != nil {
   284  		//	utils.Fatalf("%v", err)
   285  		//}
   286  		//os.Exit(0)
   287  	}
   288  	var restrictList *netutil.Netlist
   289  	if *netrestrict != "" {
   290  		restrictList, err = netutil.ParseNetlist(*netrestrict)  //// ParseCIDR parses s as a CIDR notation IP address and prefix length,
   291  		// like "192.0.2.0/24"
   292  		//amazon:inet 172.31.6.169  netmask 255.255.240.0  broadcast 172.31.15.255 => CIDR TYPE:   	172.31.6.169/20
   293  		//제한 ip 범위: 172.31.0.0 ~ 172.31.15.255
   294  	    // https://www.ipaddressguide.com/cidr
   295  		if err != nil {
   296  			utils.Fatalf("-netrestrict: %v", err)
   297  		}
   298  	}
   299  	if( *qman !="" ){
   300  		fmt.Printf("%v\n", qman )
   301  		//p2p.Send(p.rw, 0, event.Data)
   302  
   303  	}
   304  	if( *listenAddr ==""){
   305  		*listenAddr = GetLocalIP()
   306  
   307  		log.Info("I've get Local IP on this machine!", "listenAddr", listenAddr)
   308  	}
   309  	if( *port ==""){
   310  		*port = "30391"
   311  
   312  		log.Info("I've get Local IP on this machine!")
   313  	}
   314  
   315  
   316  	if *runv5 {
   317  		if _, err := discv5.ListenUDP(nodeKey, *listenAddr, natm, "", restrictList); err != nil {
   318  			utils.Fatalf("%v", err)
   319  		}
   320  	} else {  //main Listen server init and run discovery
   321  
   322  		var account common.Address
   323  		account = PubkeyToAddress(nodeKey.PublicKey)
   324  		fmt.Printf("Address(20byte account) : %v\n, %x\n", PubkeyToAddress(nodeKey.PublicKey),account )
   325  
   326  		config.Config.GetConfig("REAPCHAIN_ENV", "SETUP_INFO")
   327  		global.IsBootNode = true
   328  		if _, err := discover.ListenUDP(nodeKey, *listenAddr, natm, "", restrictList); err != nil {  //main
   329  			utils.Fatalf("%v", err)
   330  		}
   331  	}
   332  
   333  	select {}
   334  }