123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- // Copyright 2017 The go-ethereum Authors
- // This file is part of go-ethereum.
- //
- // go-ethereum is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // go-ethereum is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
- package main
- import (
- "bytes"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "math/big"
- "math/rand"
- "time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- )
- // makeGenesis creates a new genesis struct based on some user input.
- func (w *wizard) makeGenesis() {
- // Construct a default genesis block
- genesis := &core.Genesis{
- Timestamp: uint64(time.Now().Unix()),
- GasLimit: 4700000,
- Difficulty: big.NewInt(524288),
- Alloc: make(core.GenesisAlloc),
- Config: ¶ms.ChainConfig{
- HomesteadBlock: big.NewInt(1),
- EIP150Block: big.NewInt(2),
- EIP155Block: big.NewInt(3),
- EIP158Block: big.NewInt(3),
- ByzantiumBlock: big.NewInt(4),
- },
- }
- // Figure out which consensus engine to choose
- fmt.Println()
- fmt.Println("Which consensus engine to use? (default = clique)")
- fmt.Println(" 1. Ethash - proof-of-work")
- fmt.Println(" 2. Clique - proof-of-authority")
- choice := w.read()
- switch {
- case choice == "1":
- // In case of ethash, we're pretty much done
- genesis.Config.Ethash = new(params.EthashConfig)
- genesis.ExtraData = make([]byte, 32)
- case choice == "" || choice == "2":
- // In the case of clique, configure the consensus parameters
- genesis.Difficulty = big.NewInt(1)
- genesis.Config.Clique = ¶ms.CliqueConfig{
- Period: 15,
- Epoch: 30000,
- }
- fmt.Println()
- fmt.Println("How many seconds should blocks take? (default = 15)")
- genesis.Config.Clique.Period = uint64(w.readDefaultInt(15))
- // We also need the initial list of signers
- fmt.Println()
- fmt.Println("Which accounts are allowed to seal? (mandatory at least one)")
- var signers []common.Address
- for {
- if address := w.readAddress(); address != nil {
- signers = append(signers, *address)
- continue
- }
- if len(signers) > 0 {
- break
- }
- }
- // Sort the signers and embed into the extra-data section
- for i := 0; i < len(signers); i++ {
- for j := i + 1; j < len(signers); j++ {
- if bytes.Compare(signers[i][:], signers[j][:]) > 0 {
- signers[i], signers[j] = signers[j], signers[i]
- }
- }
- }
- genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65)
- for i, signer := range signers {
- copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:])
- }
- default:
- log.Crit("Invalid consensus engine choice", "choice", choice)
- }
- // Consensus all set, just ask for initial funds and go
- fmt.Println()
- fmt.Println("Which accounts should be pre-funded? (advisable at least one)")
- for {
- // Read the address of the account to fund
- if address := w.readAddress(); address != nil {
- genesis.Alloc[*address] = core.GenesisAccount{
- Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows)
- }
- continue
- }
- break
- }
- // Add a batch of precompile balances to avoid them getting deleted
- for i := int64(0); i < 256; i++ {
- genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)}
- }
- // Query the user for some custom extras
- fmt.Println()
- fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
- genesis.Config.ChainId = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
- // All done, store the genesis and flush to disk
- log.Info("Configured new genesis block")
- w.conf.Genesis = genesis
- w.conf.flush()
- }
- // manageGenesis permits the modification of chain configuration parameters in
- // a genesis config and the export of the entire genesis spec.
- func (w *wizard) manageGenesis() {
- // Figure out whether to modify or export the genesis
- fmt.Println()
- fmt.Println(" 1. Modify existing fork rules")
- fmt.Println(" 2. Export genesis configuration")
- fmt.Println(" 3. Remove genesis configuration")
- choice := w.read()
- switch {
- case choice == "1":
- // Fork rule updating requested, iterate over each fork
- fmt.Println()
- fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", w.conf.Genesis.Config.HomesteadBlock)
- w.conf.Genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.Genesis.Config.HomesteadBlock)
- fmt.Println()
- fmt.Printf("Which block should EIP150 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP150Block)
- w.conf.Genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP150Block)
- fmt.Println()
- fmt.Printf("Which block should EIP155 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP155Block)
- w.conf.Genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP155Block)
- fmt.Println()
- fmt.Printf("Which block should EIP158 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP158Block)
- w.conf.Genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP158Block)
- fmt.Println()
- fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", w.conf.Genesis.Config.ByzantiumBlock)
- w.conf.Genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ByzantiumBlock)
- out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ")
- fmt.Printf("Chain configuration updated:\n\n%s\n", out)
- case choice == "2":
- // Save whatever genesis configuration we currently have
- fmt.Println()
- fmt.Printf("Which file to save the genesis into? (default = %s.json)\n", w.network)
- out, _ := json.MarshalIndent(w.conf.Genesis, "", " ")
- if err := ioutil.WriteFile(w.readDefaultString(fmt.Sprintf("%s.json", w.network)), out, 0644); err != nil {
- log.Error("Failed to save genesis file", "err", err)
- }
- log.Info("Exported existing genesis block")
- case choice == "3":
- // Make sure we don't have any services running
- if len(w.conf.servers()) > 0 {
- log.Error("Genesis reset requires all services and servers torn down")
- return
- }
- log.Info("Genesis block destroyed")
- w.conf.Genesis = nil
- w.conf.flush()
- default:
- log.Error("That's not something I can do")
- }
- }
|