diff options
Diffstat (limited to 'cmd/puppeth/wizard_genesis.go')
-rw-r--r-- | cmd/puppeth/wizard_genesis.go | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go new file mode 100644 index 000000000..a67812e92 --- /dev/null +++ b/cmd/puppeth/wizard_genesis.go @@ -0,0 +1,136 @@ +// 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" + "fmt" + "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(1048576), + Alloc: make(core.GenesisAlloc), + Config: ¶ms.ChainConfig{ + HomesteadBlock: big.NewInt(1), + EIP150Block: big.NewInt(2), + EIP155Block: big.NewInt(3), + EIP158Block: big.NewInt(3), + }, + } + // 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)} + } + fmt.Println() + + // 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 = big.NewInt(int64(w.readDefaultInt(rand.Intn(65536)))) + + fmt.Println() + fmt.Println("Anything fun to embed into the genesis block? (max 32 bytes)") + + extra := w.read() + if len(extra) > 32 { + extra = extra[:32] + } + genesis.ExtraData = append([]byte(extra), genesis.ExtraData[len(extra):]...) + + // All done, store the genesis and flush to disk + w.conf.genesis = genesis +} |