github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/cmd/puppeth/wizard_genesis.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:31</date>
    10  //</624342604368056320>
    11  
    12  
    13  package main
    14  
    15  import (
    16  	"bytes"
    17  	"encoding/json"
    18  	"fmt"
    19  	"io/ioutil"
    20  	"math/big"
    21  	"math/rand"
    22  	"time"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/core"
    26  	"github.com/ethereum/go-ethereum/log"
    27  	"github.com/ethereum/go-ethereum/params"
    28  )
    29  
    30  //
    31  func (w *wizard) makeGenesis() {
    32  //
    33  	genesis := &core.Genesis{
    34  		Timestamp:  uint64(time.Now().Unix()),
    35  		GasLimit:   4700000,
    36  		Difficulty: big.NewInt(524288),
    37  		Alloc:      make(core.GenesisAlloc),
    38  		Config: &params.ChainConfig{
    39  			HomesteadBlock: big.NewInt(1),
    40  			EIP150Block:    big.NewInt(2),
    41  			EIP155Block:    big.NewInt(3),
    42  			EIP158Block:    big.NewInt(3),
    43  			ByzantiumBlock: big.NewInt(4),
    44  		},
    45  	}
    46  //
    47  	fmt.Println()
    48  	fmt.Println("Which consensus engine to use? (default = clique)")
    49  	fmt.Println(" 1. Ethash - proof-of-work")
    50  	fmt.Println(" 2. Clique - proof-of-authority")
    51  
    52  	choice := w.read()
    53  	switch {
    54  	case choice == "1":
    55  //
    56  		genesis.Config.Ethash = new(params.EthashConfig)
    57  		genesis.ExtraData = make([]byte, 32)
    58  
    59  	case choice == "" || choice == "2":
    60  //
    61  		genesis.Difficulty = big.NewInt(1)
    62  		genesis.Config.Clique = &params.CliqueConfig{
    63  			Period: 15,
    64  			Epoch:  30000,
    65  		}
    66  		fmt.Println()
    67  		fmt.Println("How many seconds should blocks take? (default = 15)")
    68  		genesis.Config.Clique.Period = uint64(w.readDefaultInt(15))
    69  
    70  //我们还需要签名者的初始列表
    71  		fmt.Println()
    72  		fmt.Println("Which accounts are allowed to seal? (mandatory at least one)")
    73  
    74  		var signers []common.Address
    75  		for {
    76  			if address := w.readAddress(); address != nil {
    77  				signers = append(signers, *address)
    78  				continue
    79  			}
    80  			if len(signers) > 0 {
    81  				break
    82  			}
    83  		}
    84  //对签名者排序并嵌入到额外的数据部分
    85  		for i := 0; i < len(signers); i++ {
    86  			for j := i + 1; j < len(signers); j++ {
    87  				if bytes.Compare(signers[i][:], signers[j][:]) > 0 {
    88  					signers[i], signers[j] = signers[j], signers[i]
    89  				}
    90  			}
    91  		}
    92  		genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65)
    93  		for i, signer := range signers {
    94  			copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:])
    95  		}
    96  
    97  	default:
    98  		log.Crit("Invalid consensus engine choice", "choice", choice)
    99  	}
   100  //协商一致,只需申请初始资金就可以了。
   101  	fmt.Println()
   102  	fmt.Println("Which accounts should be pre-funded? (advisable at least one)")
   103  	for {
   104  //读取要资助的帐户的地址
   105  		if address := w.readAddress(); address != nil {
   106  			genesis.Alloc[*address] = core.GenesisAccount{
   107  Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), //2^256/128(允许多个预付款没有余额溢出)
   108  			}
   109  			continue
   110  		}
   111  		break
   112  	}
   113  //添加一批预编译余额以避免删除它们
   114  	for i := int64(0); i < 256; i++ {
   115  		genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)}
   116  	}
   117  //向用户查询一些自定义附加项
   118  	fmt.Println()
   119  	fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
   120  	genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
   121  
   122  //全部完成,存储Genesis并刷新到磁盘
   123  	log.Info("Configured new genesis block")
   124  
   125  	w.conf.Genesis = genesis
   126  	w.conf.flush()
   127  }
   128  
   129  //ManageGenesis允许在
   130  //一个Genesis配置和整个Genesis规范的导出。
   131  func (w *wizard) manageGenesis() {
   132  //确定是修改还是导出Genesis
   133  	fmt.Println()
   134  	fmt.Println(" 1. Modify existing fork rules")
   135  	fmt.Println(" 2. Export genesis configuration")
   136  	fmt.Println(" 3. Remove genesis configuration")
   137  
   138  	choice := w.read()
   139  	switch {
   140  	case choice == "1":
   141  //请求了fork规则更新,对每个fork进行迭代
   142  		fmt.Println()
   143  		fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", w.conf.Genesis.Config.HomesteadBlock)
   144  		w.conf.Genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.Genesis.Config.HomesteadBlock)
   145  
   146  		fmt.Println()
   147  		fmt.Printf("Which block should EIP150 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP150Block)
   148  		w.conf.Genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP150Block)
   149  
   150  		fmt.Println()
   151  		fmt.Printf("Which block should EIP155 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP155Block)
   152  		w.conf.Genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP155Block)
   153  
   154  		fmt.Println()
   155  		fmt.Printf("Which block should EIP158 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP158Block)
   156  		w.conf.Genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP158Block)
   157  
   158  		fmt.Println()
   159  		fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", w.conf.Genesis.Config.ByzantiumBlock)
   160  		w.conf.Genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ByzantiumBlock)
   161  
   162  		out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", "  ")
   163  		fmt.Printf("Chain configuration updated:\n\n%s\n", out)
   164  
   165  	case choice == "2":
   166  //保存我们当前的Genesis配置
   167  		fmt.Println()
   168  		fmt.Printf("Which file to save the genesis into? (default = %s.json)\n", w.network)
   169  		out, _ := json.MarshalIndent(w.conf.Genesis, "", "  ")
   170  		if err := ioutil.WriteFile(w.readDefaultString(fmt.Sprintf("%s.json", w.network)), out, 0644); err != nil {
   171  			log.Error("Failed to save genesis file", "err", err)
   172  		}
   173  		log.Info("Exported existing genesis block")
   174  
   175  	case choice == "3":
   176  //
   177  		if len(w.conf.servers()) > 0 {
   178  			log.Error("Genesis reset requires all services and servers torn down")
   179  			return
   180  		}
   181  		log.Info("Genesis block destroyed")
   182  
   183  		w.conf.Genesis = nil
   184  		w.conf.flush()
   185  
   186  	default:
   187  		log.Error("That's not something I can do")
   188  	}
   189  }
   190