github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/cmd/puppeth/wizard_genesis.go (about) 1 // Copyright 2017 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 "github.com/PlatONnetwork/PlatON-Go/crypto" 21 "github.com/PlatONnetwork/PlatON-Go/p2p/discover" 22 "bytes" 23 "encoding/json" 24 "fmt" 25 "io/ioutil" 26 "math/big" 27 "math/rand" 28 "time" 29 30 "github.com/PlatONnetwork/PlatON-Go/common" 31 "github.com/PlatONnetwork/PlatON-Go/core" 32 "github.com/PlatONnetwork/PlatON-Go/log" 33 "github.com/PlatONnetwork/PlatON-Go/params" 34 ) 35 36 // makeGenesis creates a new genesis struct based on some user input. 37 func (w *wizard) makeGenesis() { 38 // Construct a default genesis block 39 genesis := &core.Genesis{ 40 Timestamp: uint64(time.Now().Unix()), 41 GasLimit: 3150000000, 42 Alloc: make(core.GenesisAlloc), 43 Config: ¶ms.ChainConfig{ 44 HomesteadBlock: big.NewInt(1), 45 EIP150Block: big.NewInt(2), 46 EIP155Block: big.NewInt(3), 47 EIP158Block: big.NewInt(3), 48 ByzantiumBlock: big.NewInt(4), 49 }, 50 } 51 // Figure out which consensus engine to choose 52 fmt.Println() 53 fmt.Println("Which consensus engine to use? (default = CBFT)") 54 fmt.Println(" 1. Ethash - proof-of-work") 55 fmt.Println(" 2. Clique - proof-of-authority") 56 fmt.Println(" 3. CBFT - Concurrent Byzantine Fault Tolerance") 57 58 choice := w.read() 59 switch { 60 case choice == "1": 61 // In case of ethash, we're pretty much done 62 genesis.Config.Ethash = new(params.EthashConfig) 63 genesis.ExtraData = make([]byte, 32) 64 65 case choice == "2": 66 // In the case of clique, configure the consensus parameters 67 genesis.Config.Clique = ¶ms.CliqueConfig{ 68 Period: 15, 69 Epoch: 30000, 70 } 71 fmt.Println() 72 fmt.Println("How many seconds should blocks take? (default = 15)") 73 genesis.Config.Clique.Period = uint64(w.readDefaultInt(15)) 74 75 // We also need the initial list of signers 76 fmt.Println() 77 fmt.Println("Which accounts are allowed to seal? (mandatory at least one)") 78 79 var signers []common.Address 80 for { 81 if address := w.readAddress(); address != nil { 82 signers = append(signers, *address) 83 continue 84 } 85 if len(signers) > 0 { 86 break 87 } 88 } 89 // Sort the signers and embed into the extra-data section 90 for i := 0; i < len(signers); i++ { 91 for j := i + 1; j < len(signers); j++ { 92 if bytes.Compare(signers[i][:], signers[j][:]) > 0 { 93 signers[i], signers[j] = signers[j], signers[i] 94 } 95 } 96 } 97 genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65) 98 for i, signer := range signers { 99 copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) 100 } 101 102 case choice == "" || choice == "3": 103 // In the case of cbft, configure the consensus parameters 104 genesis.Config.Cbft = ¶ms.CbftConfig{} 105 // We also need the initial list of signers 106 fmt.Println() 107 fmt.Println("Which nodes are allowed to seal? (mandatory at least four)") 108 109 var nodes []discover.Node 110 for { 111 if node := w.readNodeURL(); node != nil { 112 nodes = append(nodes, *node) 113 continue 114 } 115 if len(nodes) >= 4 { 116 break 117 } 118 } 119 // Sort the signers and embed into the extra-data section 120 for i := 0; i < len(nodes); i++ { 121 for j := i + 1; j < len(nodes); j++ { 122 if bytes.Compare(nodes[i].ID[:], nodes[j].ID[:]) > 0 { 123 nodes[i], nodes[j] = nodes[j], nodes[i] 124 } 125 } 126 } 127 genesis.ExtraData = make([]byte, 32+len(nodes)*common.AddressLength+65) 128 for i, node := range nodes { 129 copy(genesis.ExtraData[32+i*common.AddressLength:], crypto.Keccak256(node.ID[:])[12:]) 130 } 131 genesis.Config.Cbft.InitialNodes = nodes 132 default: 133 log.Crit("Invalid consensus engine choice", "choice", choice) 134 } 135 // Consensus all set, just ask for initial funds and go 136 fmt.Println() 137 fmt.Println("Which accounts should be pre-funded? (advisable at least one)") 138 for { 139 // Read the address of the account to fund 140 if address := w.readAddress(); address != nil { 141 genesis.Alloc[*address] = core.GenesisAccount{ 142 Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows) 143 } 144 continue 145 } 146 break 147 } 148 // Add a batch of precompile balances to avoid them getting deleted 149 for i := int64(0); i < 256; i++ { 150 genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)} 151 } 152 // Query the user for some custom extras 153 fmt.Println() 154 fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)") 155 genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536)))) 156 157 // All done, store the genesis and flush to disk 158 log.Info("Configured new genesis block") 159 160 w.conf.Genesis = genesis 161 w.conf.flush() 162 } 163 164 // manageGenesis permits the modification of chain configuration parameters in 165 // a genesis config and the export of the entire genesis spec. 166 func (w *wizard) manageGenesis() { 167 // Figure out whether to modify or export the genesis 168 fmt.Println() 169 fmt.Println(" 1. Modify existing fork rules") 170 fmt.Println(" 2. Export genesis configuration") 171 fmt.Println(" 3. Remove genesis configuration") 172 173 choice := w.read() 174 switch { 175 case choice == "1": 176 // Fork rule updating requested, iterate over each fork 177 fmt.Println() 178 fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", w.conf.Genesis.Config.HomesteadBlock) 179 w.conf.Genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.Genesis.Config.HomesteadBlock) 180 181 fmt.Println() 182 fmt.Printf("Which block should EIP150 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP150Block) 183 w.conf.Genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP150Block) 184 185 fmt.Println() 186 fmt.Printf("Which block should EIP155 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP155Block) 187 w.conf.Genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP155Block) 188 189 fmt.Println() 190 fmt.Printf("Which block should EIP158 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP158Block) 191 w.conf.Genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP158Block) 192 193 fmt.Println() 194 fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", w.conf.Genesis.Config.ByzantiumBlock) 195 w.conf.Genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ByzantiumBlock) 196 197 out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ") 198 fmt.Printf("Chain configuration updated:\n\n%s\n", out) 199 200 case choice == "2": 201 // Save whatever genesis configuration we currently have 202 fmt.Println() 203 fmt.Printf("Which file to save the genesis into? (default = %s.json)\n", w.network) 204 out, _ := json.MarshalIndent(w.conf.Genesis, "", " ") 205 if err := ioutil.WriteFile(w.readDefaultString(fmt.Sprintf("%s.json", w.network)), out, 0644); err != nil { 206 log.Error("Failed to save genesis file", "err", err) 207 } 208 log.Info("Exported existing genesis block") 209 210 case choice == "3": 211 // Make sure we don't have any services running 212 if len(w.conf.servers()) > 0 { 213 log.Error("Genesis reset requires all services and servers torn down") 214 return 215 } 216 log.Info("Genesis block destroyed") 217 218 w.conf.Genesis = nil 219 w.conf.flush() 220 221 default: 222 log.Error("That's not something I can do") 223 } 224 }