github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/cmd/puppeth/wizard_genesis.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package main 13 14 import ( 15 "bytes" 16 "encoding/json" 17 "fmt" 18 "io/ioutil" 19 "math/big" 20 "math/rand" 21 "time" 22 23 "github.com/Sberex/go-sberex/common" 24 "github.com/Sberex/go-sberex/core" 25 "github.com/Sberex/go-sberex/log" 26 "github.com/Sberex/go-sberex/params" 27 ) 28 29 // makeGenesis creates a new genesis struct based on some user input. 30 func (w *wizard) makeGenesis() { 31 // Construct a default genesis block 32 genesis := &core.Genesis{ 33 Timestamp: uint64(time.Now().Unix()), 34 GasLimit: 4700000, 35 Difficulty: big.NewInt(524288), 36 Alloc: make(core.GenesisAlloc), 37 Config: ¶ms.ChainConfig{ 38 HomesteadBlock: big.NewInt(1), 39 EIP150Block: big.NewInt(2), 40 EIP155Block: big.NewInt(3), 41 EIP158Block: big.NewInt(3), 42 ByzantiumBlock: big.NewInt(4), 43 }, 44 } 45 // Figure out which consensus engine to choose 46 fmt.Println() 47 fmt.Println("Which consensus engine to use? (default = clique)") 48 fmt.Println(" 1. Ethash - proof-of-work") 49 fmt.Println(" 2. Clique - proof-of-authority") 50 51 choice := w.read() 52 switch { 53 case choice == "1": 54 // In case of ethash, we're pretty much done 55 genesis.Config.Ethash = new(params.EthashConfig) 56 genesis.ExtraData = make([]byte, 32) 57 58 case choice == "" || choice == "2": 59 // In the case of clique, configure the consensus parameters 60 genesis.Difficulty = big.NewInt(1) 61 genesis.Config.Clique = ¶ms.CliqueConfig{ 62 Period: 33, 63 Epoch: 90000, 64 } 65 fmt.Println() 66 fmt.Println("How many seconds should blocks take? (default = 33)") 67 genesis.Config.Clique.Period = uint64(w.readDefaultInt(33)) 68 69 // We also need the initial list of signers 70 fmt.Println() 71 fmt.Println("Which accounts are allowed to seal? (mandatory at least one)") 72 73 var signers []common.Address 74 for { 75 if address := w.readAddress(); address != nil { 76 signers = append(signers, *address) 77 continue 78 } 79 if len(signers) > 0 { 80 break 81 } 82 } 83 // Sort the signers and embed into the extra-data section 84 for i := 0; i < len(signers); i++ { 85 for j := i + 1; j < len(signers); j++ { 86 if bytes.Compare(signers[i][:], signers[j][:]) > 0 { 87 signers[i], signers[j] = signers[j], signers[i] 88 } 89 } 90 } 91 genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65) 92 for i, signer := range signers { 93 copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) 94 } 95 96 default: 97 log.Crit("Invalid consensus engine choice", "choice", choice) 98 } 99 // Consensus all set, just ask for initial funds and go 100 fmt.Println() 101 fmt.Println("Which accounts should be pre-funded? (advisable at least one)") 102 for { 103 // Read the address of the account to fund 104 if address := w.readAddress(); address != nil { 105 genesis.Alloc[*address] = core.GenesisAccount{ 106 Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows) 107 } 108 continue 109 } 110 break 111 } 112 // Add a batch of precompile balances to avoid them getting deleted 113 for i := int64(0); i < 256; i++ { 114 genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)} 115 } 116 // Query the user for some custom extras 117 fmt.Println() 118 fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)") 119 genesis.Config.ChainId = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536)))) 120 121 // All done, store the genesis and flush to disk 122 log.Info("Configured new genesis block") 123 124 w.conf.Genesis = genesis 125 w.conf.flush() 126 } 127 128 // manageGenesis permits the modification of chain configuration parameters in 129 // a genesis config and the export of the entire genesis spec. 130 func (w *wizard) manageGenesis() { 131 // Figure out whether to modify or export the genesis 132 fmt.Println() 133 fmt.Println(" 1. Modify existing fork rules") 134 fmt.Println(" 2. Export genesis configuration") 135 fmt.Println(" 3. Remove genesis configuration") 136 137 choice := w.read() 138 switch { 139 case choice == "1": 140 // Fork rule updating requested, iterate over each fork 141 fmt.Println() 142 fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", w.conf.Genesis.Config.HomesteadBlock) 143 w.conf.Genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.Genesis.Config.HomesteadBlock) 144 145 fmt.Println() 146 fmt.Printf("Which block should EIP150 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP150Block) 147 w.conf.Genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP150Block) 148 149 fmt.Println() 150 fmt.Printf("Which block should EIP155 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP155Block) 151 w.conf.Genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP155Block) 152 153 fmt.Println() 154 fmt.Printf("Which block should EIP158 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP158Block) 155 w.conf.Genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP158Block) 156 157 fmt.Println() 158 fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", w.conf.Genesis.Config.ByzantiumBlock) 159 w.conf.Genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ByzantiumBlock) 160 161 out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ") 162 fmt.Printf("Chain configuration updated:\n\n%s\n", out) 163 164 case choice == "2": 165 // Save whatever genesis configuration we currently have 166 fmt.Println() 167 fmt.Printf("Which file to save the genesis into? (default = %s.json)\n", w.network) 168 out, _ := json.MarshalIndent(w.conf.Genesis, "", " ") 169 if err := ioutil.WriteFile(w.readDefaultString(fmt.Sprintf("%s.json", w.network)), out, 0644); err != nil { 170 log.Error("Failed to save genesis file", "err", err) 171 } 172 log.Info("Exported existing genesis block") 173 174 case choice == "3": 175 // Make sure we don't have any services running 176 if len(w.conf.servers()) > 0 { 177 log.Error("Genesis reset requires all services and servers torn down") 178 return 179 } 180 log.Info("Genesis block destroyed") 181 182 w.conf.Genesis = nil 183 w.conf.flush() 184 185 default: 186 log.Error("That's not something I can do") 187 } 188 }