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: ¶ms.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 = ¶ms.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