github.com/theQRL/go-zond@v0.1.1/cmd/devp2p/keycmd.go (about)

     1  // Copyright 2020 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  package main
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"net"
    23  
    24  	"github.com/theQRL/go-zond/crypto"
    25  	"github.com/theQRL/go-zond/p2p/enode"
    26  	"github.com/theQRL/go-zond/p2p/enr"
    27  	"github.com/urfave/cli/v2"
    28  )
    29  
    30  var (
    31  	keyCommand = &cli.Command{
    32  		Name:  "key",
    33  		Usage: "Operations on node keys",
    34  		Subcommands: []*cli.Command{
    35  			keyGenerateCommand,
    36  			keyToIDCommand,
    37  			keyToNodeCommand,
    38  			keyToRecordCommand,
    39  		},
    40  	}
    41  	keyGenerateCommand = &cli.Command{
    42  		Name:      "generate",
    43  		Usage:     "Generates node key files",
    44  		ArgsUsage: "keyfile",
    45  		Action:    genkey,
    46  	}
    47  	keyToIDCommand = &cli.Command{
    48  		Name:      "to-id",
    49  		Usage:     "Creates a node ID from a node key file",
    50  		ArgsUsage: "keyfile",
    51  		Action:    keyToID,
    52  		Flags:     []cli.Flag{},
    53  	}
    54  	keyToNodeCommand = &cli.Command{
    55  		Name:      "to-enode",
    56  		Usage:     "Creates an enode URL from a node key file",
    57  		ArgsUsage: "keyfile",
    58  		Action:    keyToURL,
    59  		Flags:     []cli.Flag{hostFlag, tcpPortFlag, udpPortFlag},
    60  	}
    61  	keyToRecordCommand = &cli.Command{
    62  		Name:      "to-enr",
    63  		Usage:     "Creates an ENR from a node key file",
    64  		ArgsUsage: "keyfile",
    65  		Action:    keyToRecord,
    66  		Flags:     []cli.Flag{hostFlag, tcpPortFlag, udpPortFlag},
    67  	}
    68  )
    69  
    70  var (
    71  	hostFlag = &cli.StringFlag{
    72  		Name:  "ip",
    73  		Usage: "IP address of the node",
    74  		Value: "127.0.0.1",
    75  	}
    76  	tcpPortFlag = &cli.IntFlag{
    77  		Name:  "tcp",
    78  		Usage: "TCP port of the node",
    79  		Value: 30303,
    80  	}
    81  	udpPortFlag = &cli.IntFlag{
    82  		Name:  "udp",
    83  		Usage: "UDP port of the node",
    84  		Value: 30303,
    85  	}
    86  )
    87  
    88  func genkey(ctx *cli.Context) error {
    89  	if ctx.NArg() != 1 {
    90  		return errors.New("need key file as argument")
    91  	}
    92  	file := ctx.Args().Get(0)
    93  
    94  	key, err := crypto.GenerateKey()
    95  	if err != nil {
    96  		return fmt.Errorf("could not generate key: %v", err)
    97  	}
    98  	return crypto.SaveECDSA(file, key)
    99  }
   100  
   101  func keyToID(ctx *cli.Context) error {
   102  	n, err := makeRecord(ctx)
   103  	if err != nil {
   104  		return err
   105  	}
   106  	fmt.Println(n.ID())
   107  	return nil
   108  }
   109  
   110  func keyToURL(ctx *cli.Context) error {
   111  	n, err := makeRecord(ctx)
   112  	if err != nil {
   113  		return err
   114  	}
   115  	fmt.Println(n.URLv4())
   116  	return nil
   117  }
   118  
   119  func keyToRecord(ctx *cli.Context) error {
   120  	n, err := makeRecord(ctx)
   121  	if err != nil {
   122  		return err
   123  	}
   124  	fmt.Println(n.String())
   125  	return nil
   126  }
   127  
   128  func makeRecord(ctx *cli.Context) (*enode.Node, error) {
   129  	if ctx.NArg() != 1 {
   130  		return nil, errors.New("need key file as argument")
   131  	}
   132  
   133  	var (
   134  		file = ctx.Args().Get(0)
   135  		host = ctx.String(hostFlag.Name)
   136  		tcp  = ctx.Int(tcpPortFlag.Name)
   137  		udp  = ctx.Int(udpPortFlag.Name)
   138  	)
   139  	key, err := crypto.LoadECDSA(file)
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  
   144  	var r enr.Record
   145  	if host != "" {
   146  		ip := net.ParseIP(host)
   147  		if ip == nil {
   148  			return nil, fmt.Errorf("invalid IP address %q", host)
   149  		}
   150  		r.Set(enr.IP(ip))
   151  	}
   152  	if udp != 0 {
   153  		r.Set(enr.UDP(udp))
   154  	}
   155  	if tcp != 0 {
   156  		r.Set(enr.TCP(tcp))
   157  	}
   158  
   159  	if err := enode.SignV4(&r, key); err != nil {
   160  		return nil, err
   161  	}
   162  	return enode.New(enode.ValidSchemes, &r)
   163  }