wizard_genesis.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of go-ethereum.
  3. //
  4. // go-ethereum 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-ethereum 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-ethereum. If not, see <http://www.gnu.org/licenses/>.
  16. package main
  17. import (
  18. "bytes"
  19. "fmt"
  20. "math/big"
  21. "math/rand"
  22. "time"
  23. "github.com/ethereum/go-ethereum/common"
  24. "github.com/ethereum/go-ethereum/core"
  25. "github.com/ethereum/go-ethereum/log"
  26. "github.com/ethereum/go-ethereum/params"
  27. )
  28. // makeGenesis creates a new genesis struct based on some user input.
  29. func (w *wizard) makeGenesis() {
  30. // Construct a default genesis block
  31. genesis := &core.Genesis{
  32. Timestamp: uint64(time.Now().Unix()),
  33. GasLimit: 4700000,
  34. Difficulty: big.NewInt(1048576),
  35. Alloc: make(core.GenesisAlloc),
  36. Config: &params.ChainConfig{
  37. HomesteadBlock: big.NewInt(1),
  38. EIP150Block: big.NewInt(2),
  39. EIP155Block: big.NewInt(3),
  40. EIP158Block: big.NewInt(3),
  41. },
  42. }
  43. // Figure out which consensus engine to choose
  44. fmt.Println()
  45. fmt.Println("Which consensus engine to use? (default = clique)")
  46. fmt.Println(" 1. Ethash - proof-of-work")
  47. fmt.Println(" 2. Clique - proof-of-authority")
  48. choice := w.read()
  49. switch {
  50. case choice == "1":
  51. // In case of ethash, we're pretty much done
  52. genesis.Config.Ethash = new(params.EthashConfig)
  53. genesis.ExtraData = make([]byte, 32)
  54. case choice == "" || choice == "2":
  55. // In the case of clique, configure the consensus parameters
  56. genesis.Difficulty = big.NewInt(1)
  57. genesis.Config.Clique = &params.CliqueConfig{
  58. Period: 15,
  59. Epoch: 30000,
  60. }
  61. fmt.Println()
  62. fmt.Println("How many seconds should blocks take? (default = 15)")
  63. genesis.Config.Clique.Period = uint64(w.readDefaultInt(15))
  64. // We also need the initial list of signers
  65. fmt.Println()
  66. fmt.Println("Which accounts are allowed to seal? (mandatory at least one)")
  67. var signers []common.Address
  68. for {
  69. if address := w.readAddress(); address != nil {
  70. signers = append(signers, *address)
  71. continue
  72. }
  73. if len(signers) > 0 {
  74. break
  75. }
  76. }
  77. // Sort the signers and embed into the extra-data section
  78. for i := 0; i < len(signers); i++ {
  79. for j := i + 1; j < len(signers); j++ {
  80. if bytes.Compare(signers[i][:], signers[j][:]) > 0 {
  81. signers[i], signers[j] = signers[j], signers[i]
  82. }
  83. }
  84. }
  85. genesis.ExtraData = make([]byte, 32+len(signers)*common.AddressLength+65)
  86. for i, signer := range signers {
  87. copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:])
  88. }
  89. default:
  90. log.Crit("Invalid consensus engine choice", "choice", choice)
  91. }
  92. // Consensus all set, just ask for initial funds and go
  93. fmt.Println()
  94. fmt.Println("Which accounts should be pre-funded? (advisable at least one)")
  95. for {
  96. // Read the address of the account to fund
  97. if address := w.readAddress(); address != nil {
  98. genesis.Alloc[*address] = core.GenesisAccount{
  99. Balance: new(big.Int).Lsh(big.NewInt(1), 256-7), // 2^256 / 128 (allow many pre-funds without balance overflows)
  100. }
  101. continue
  102. }
  103. break
  104. }
  105. // Add a batch of precompile balances to avoid them getting deleted
  106. for i := int64(0); i < 256; i++ {
  107. genesis.Alloc[common.BigToAddress(big.NewInt(i))] = core.GenesisAccount{Balance: big.NewInt(1)}
  108. }
  109. fmt.Println()
  110. // Query the user for some custom extras
  111. fmt.Println()
  112. fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)")
  113. genesis.Config.ChainId = big.NewInt(int64(w.readDefaultInt(rand.Intn(65536))))
  114. fmt.Println()
  115. fmt.Println("Anything fun to embed into the genesis block? (max 32 bytes)")
  116. extra := w.read()
  117. if len(extra) > 32 {
  118. extra = extra[:32]
  119. }
  120. genesis.ExtraData = append([]byte(extra), genesis.ExtraData[len(extra):]...)
  121. // All done, store the genesis and flush to disk
  122. w.conf.genesis = genesis
  123. }