github.com/alexdevranger/node-1.8.27@v0.0.0-20221128213301-aa5841e41d2d/cmd/puppeth/wizard_genesis.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of go-dubxcoin. 3 // 4 // go-dubxcoin 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-dubxcoin 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-dubxcoin. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "fmt" 23 "io" 24 "io/ioutil" 25 "math/big" 26 "math/rand" 27 "net/http" 28 "os" 29 "path/filepath" 30 "time" 31 32 "github.com/alexdevranger/node-1.8.27/common" 33 "github.com/alexdevranger/node-1.8.27/core" 34 "github.com/alexdevranger/node-1.8.27/log" 35 "github.com/alexdevranger/node-1.8.27/params" 36 ) 37 38 // makeGenesis creates a new genesis struct based on some user input. 39 func (w *wizard) makeGenesis() { 40 // Construct a default genesis block 41 genesis := &core.Genesis{ 42 Timestamp: uint64(time.Now().Unix()), 43 GasLimit: 4700000, 44 Difficulty: big.NewInt(524288), 45 Alloc: make(core.GenesisAlloc), 46 Config: ¶ms.ChainConfig{ 47 HomesteadBlock: big.NewInt(1), 48 EIP150Block: big.NewInt(2), 49 EIP155Block: big.NewInt(3), 50 EIP158Block: big.NewInt(3), 51 ByzantiumBlock: big.NewInt(4), 52 ConstantinopleBlock: big.NewInt(5), 53 }, 54 } 55 // Figure out which consensus engine to choose 56 fmt.Println() 57 fmt.Println("Which consensus engine to use? (default = clique)") 58 fmt.Println(" 1. Ethash - proof-of-work") 59 fmt.Println(" 2. Clique - proof-of-authority") 60 61 choice := w.read() 62 switch { 63 case choice == "1": 64 // In case of ethash, we're pretty much done 65 genesis.Config.Ethash = new(params.EthashConfig) 66 genesis.ExtraData = make([]byte, 32) 67 68 case choice == "" || choice == "2": 69 // In the case of clique, configure the consensus parameters 70 genesis.Difficulty = big.NewInt(1) 71 genesis.Config.Clique = ¶ms.CliqueConfig{ 72 Period: 15, 73 Epoch: 30000, 74 } 75 fmt.Println() 76 fmt.Println("How many seconds should blocks take? (default = 15)") 77 genesis.Config.Clique.Period = uint64(w.readDefaultInt(15)) 78 79 // We also need the initial list of signers 80 fmt.Println() 81 fmt.Println("Which accounts are allowed to seal? (mandatory at least one)") 82 83 var signers []common.Address 84 for { 85 if address := w.readAddress(); address != nil { 86 signers = append(signers, *address) 87 continue 88 } 89 if len(signers) > 0 { 90 break 91 } 92 } 93 // Sort the signers and embed into the extra-data section 94 for i := 0; i < len(signers); i++ { 95 for j := i + 1; j < len(signers); j++ { 96 if bytes.Compare(signers[i][:], signers[j][:]) > 0 { 97 signers[i], signers[j] = signers[j], signers[i] 98 } 99 } 100 } 101 genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65) 102 for i, signer := range signers { 103 copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) 104 } 105 106 default: 107 log.Crit("Invalid consensus engine choice", "choice", choice) 108 } 109 // Consensus all set, just ask for initial funds and go 110 fmt.Println() 111 fmt.Println("Which accounts should be pre-funded? (advisable at least one)") 112 for { 113 // Read the address of the account to fund 114 if address := w.readAddress(); address != nil { 115 genesis.Alloc[*address] = core.GenesisAccount{ 116 Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows) 117 } 118 continue 119 } 120 break 121 } 122 fmt.Println() 123 fmt.Println("Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)") 124 if w.readDefaultYesNo(true) { 125 // Add a batch of precompile balances to avoid them getting deleted 126 for i := int64(0); i < 256; i++ { 127 genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)} 128 } 129 } 130 // Query the user for some custom extras 131 fmt.Println() 132 fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)") 133 genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536)))) 134 135 // All done, store the genesis and flush to disk 136 log.Info("Configured new genesis block") 137 138 w.conf.Genesis = genesis 139 w.conf.flush() 140 } 141 142 // importGenesis imports a Gdubx genesis spec into puppeth. 143 func (w *wizard) importGenesis() { 144 // Request the genesis JSON spec URL from the user 145 fmt.Println() 146 fmt.Println("Where's the genesis file? (local file or http/https url)") 147 url := w.readURL() 148 149 // Convert the various allowed URLs to a reader stream 150 var reader io.Reader 151 152 switch url.Scheme { 153 case "http", "https": 154 // Remote web URL, retrieve it via an HTTP client 155 res, err := http.Get(url.String()) 156 if err != nil { 157 log.Error("Failed to retrieve remote genesis", "err", err) 158 return 159 } 160 defer res.Body.Close() 161 reader = res.Body 162 163 case "": 164 // Schemaless URL, interpret as a local file 165 file, err := os.Open(url.String()) 166 if err != nil { 167 log.Error("Failed to open local genesis", "err", err) 168 return 169 } 170 defer file.Close() 171 reader = file 172 173 default: 174 log.Error("Unsupported genesis URL scheme", "scheme", url.Scheme) 175 return 176 } 177 // Parse the genesis file and inject it successful 178 var genesis core.Genesis 179 if err := json.NewDecoder(reader).Decode(&genesis); err != nil { 180 log.Error("Invalid genesis spec: %v", err) 181 return 182 } 183 log.Info("Imported genesis block") 184 185 w.conf.Genesis = &genesis 186 w.conf.flush() 187 } 188 189 // manageGenesis permits the modification of chain configuration parameters in 190 // a genesis config and the export of the entire genesis spec. 191 func (w *wizard) manageGenesis() { 192 // Figure out whether to modify or export the genesis 193 fmt.Println() 194 fmt.Println(" 1. Modify existing fork rules") 195 fmt.Println(" 2. Export genesis configurations") 196 fmt.Println(" 3. Remove genesis configuration") 197 198 choice := w.read() 199 switch choice { 200 case "1": 201 // Fork rule updating requested, iterate over each fork 202 fmt.Println() 203 fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", w.conf.Genesis.Config.HomesteadBlock) 204 w.conf.Genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.Genesis.Config.HomesteadBlock) 205 206 fmt.Println() 207 fmt.Printf("Which block should EIP150 (Tangerine Whistle) come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP150Block) 208 w.conf.Genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP150Block) 209 210 fmt.Println() 211 fmt.Printf("Which block should EIP155 (Spurious Dragon) come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP155Block) 212 w.conf.Genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP155Block) 213 214 fmt.Println() 215 fmt.Printf("Which block should EIP158/161 (also Spurious Dragon) come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP158Block) 216 w.conf.Genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP158Block) 217 218 fmt.Println() 219 fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", w.conf.Genesis.Config.ByzantiumBlock) 220 w.conf.Genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ByzantiumBlock) 221 222 fmt.Println() 223 fmt.Printf("Which block should Constantinople come into effect? (default = %v)\n", w.conf.Genesis.Config.ConstantinopleBlock) 224 w.conf.Genesis.Config.ConstantinopleBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ConstantinopleBlock) 225 if w.conf.Genesis.Config.PetersburgBlock == nil { 226 w.conf.Genesis.Config.PetersburgBlock = w.conf.Genesis.Config.ConstantinopleBlock 227 } 228 fmt.Println() 229 fmt.Printf("Which block should Constantinople-Fix (remove EIP-1283) come into effect? (default = %v)\n", w.conf.Genesis.Config.PetersburgBlock) 230 w.conf.Genesis.Config.PetersburgBlock = w.readDefaultBigInt(w.conf.Genesis.Config.PetersburgBlock) 231 232 out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ") 233 fmt.Printf("Chain configuration updated:\n\n%s\n", out) 234 235 w.conf.flush() 236 237 case "2": 238 // Save whatever genesis configuration we currently have 239 fmt.Println() 240 fmt.Printf("Which folder to save the genesis specs into? (default = current)\n") 241 fmt.Printf(" Will create %s.json, %s-aleth.json, %s-harmony.json, %s-parity.json\n", w.network, w.network, w.network, w.network) 242 243 folder := w.readDefaultString(".") 244 if err := os.MkdirAll(folder, 0755); err != nil { 245 log.Error("Failed to create spec folder", "folder", folder, "err", err) 246 return 247 } 248 out, _ := json.MarshalIndent(w.conf.Genesis, "", " ") 249 250 // Export the native genesis spec used by puppeth and Gdubx 251 gdubxJson := filepath.Join(folder, fmt.Sprintf("%s.json", w.network)) 252 if err := ioutil.WriteFile((gdubxJson), out, 0644); err != nil { 253 log.Error("Failed to save genesis file", "err", err) 254 return 255 } 256 log.Info("Saved native genesis chain spec", "path", gdubxJson) 257 258 // Export the genesis spec used by Aleth (formerly C++ Ethereum) 259 if spec, err := newAlethGenesisSpec(w.network, w.conf.Genesis); err != nil { 260 log.Error("Failed to create Aleth chain spec", "err", err) 261 } else { 262 saveGenesis(folder, w.network, "aleth", spec) 263 } 264 // Export the genesis spec used by Parity 265 if spec, err := newParityChainSpec(w.network, w.conf.Genesis, []string{}); err != nil { 266 log.Error("Failed to create Parity chain spec", "err", err) 267 } else { 268 saveGenesis(folder, w.network, "parity", spec) 269 } 270 // Export the genesis spec used by Harmony (formerly EthereumJ 271 saveGenesis(folder, w.network, "harmony", w.conf.Genesis) 272 273 case "3": 274 // Make sure we don't have any services running 275 if len(w.conf.servers()) > 0 { 276 log.Error("Genesis reset requires all services and servers torn down") 277 return 278 } 279 log.Info("Genesis block destroyed") 280 281 w.conf.Genesis = nil 282 w.conf.flush() 283 default: 284 log.Error("That's not something I can do") 285 return 286 } 287 } 288 289 // saveGenesis JSON encodes an arbitrary genesis spec into a pre-defined file. 290 func saveGenesis(folder, network, client string, spec interface{}) { 291 path := filepath.Join(folder, fmt.Sprintf("%s-%s.json", network, client)) 292 293 out, _ := json.Marshal(spec) 294 if err := ioutil.WriteFile(path, out, 0644); err != nil { 295 log.Error("Failed to save genesis file", "client", client, "err", err) 296 return 297 } 298 log.Info("Saved genesis chain spec", "client", client, "path", path) 299 }