| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- // 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
- }
|