diff options
Diffstat (limited to 'cmd/puppeth/wizard_genesis.go')
-rw-r--r-- | cmd/puppeth/wizard_genesis.go | 127 |
1 files changed, 94 insertions, 33 deletions
diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index 681a387df..95da5bd4f 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -20,9 +20,13 @@ import ( "bytes" "encoding/json" "fmt" + "io" "io/ioutil" "math/big" "math/rand" + "net/http" + "os" + "path/filepath" "time" "github.com/ethereum/go-ethereum/common" @@ -40,11 +44,12 @@ func (w *wizard) makeGenesis() { 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), + HomesteadBlock: big.NewInt(1), + EIP150Block: big.NewInt(2), + EIP155Block: big.NewInt(3), + EIP158Block: big.NewInt(3), + ByzantiumBlock: big.NewInt(4), + ConstantinopleBlock: big.NewInt(5), }, } // Figure out which consensus engine to choose @@ -116,7 +121,7 @@ func (w *wizard) makeGenesis() { } fmt.Println() fmt.Println("Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)") - if w.readYesNo(true) { + if w.readDefaultYesNo(true) { // 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)} @@ -134,6 +139,53 @@ func (w *wizard) makeGenesis() { w.conf.flush() } +// importGenesis imports a Geth genesis spec into puppeth. +func (w *wizard) importGenesis() { + // Request the genesis JSON spec URL from the user + fmt.Println() + fmt.Println("Where's the genesis file? (local file or http/https url)") + url := w.readURL() + + // Convert the various allowed URLs to a reader stream + var reader io.Reader + + switch url.Scheme { + case "http", "https": + // Remote web URL, retrieve it via an HTTP client + res, err := http.Get(url.String()) + if err != nil { + log.Error("Failed to retrieve remote genesis", "err", err) + return + } + defer res.Body.Close() + reader = res.Body + + case "": + // Schemaless URL, interpret as a local file + file, err := os.Open(url.String()) + if err != nil { + log.Error("Failed to open local genesis", "err", err) + return + } + defer file.Close() + reader = file + + default: + log.Error("Unsupported genesis URL scheme", "scheme", url.Scheme) + return + } + // Parse the genesis file and inject it successful + var genesis core.Genesis + if err := json.NewDecoder(reader).Decode(&genesis); err != nil { + log.Error("Invalid genesis spec: %v", err) + return + } + log.Info("Imported 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() { @@ -168,7 +220,7 @@ func (w *wizard) manageGenesis() { w.conf.Genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ByzantiumBlock) fmt.Println() - fmt.Printf("Which block should Constantinople come into effect? (default = %v)\n", w.conf.Genesis.Config.ByzantiumBlock) + fmt.Printf("Which block should Constantinople come into effect? (default = %v)\n", w.conf.Genesis.Config.ConstantinopleBlock) w.conf.Genesis.Config.ConstantinopleBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ConstantinopleBlock) out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ") @@ -177,18 +229,38 @@ func (w *wizard) manageGenesis() { case "2": // Save whatever genesis configuration we currently have fmt.Println() - fmt.Printf("Which base filename to save the genesis specifications into? (default = %s)\n", w.network) + fmt.Printf("Which folder to save the genesis specs into? (default = current)\n") + fmt.Printf(" Will create %s.json, %s-aleth.json, %s-harmony.json, %s-parity.json\n", w.network, w.network, w.network, w.network) + + folder := w.readDefaultString(".") + if err := os.MkdirAll(folder, 0755); err != nil { + log.Error("Failed to create spec folder", "folder", folder, "err", err) + return + } out, _ := json.MarshalIndent(w.conf.Genesis, "", " ") - basename := w.readDefaultString(fmt.Sprintf("%s.json", w.network)) - gethJson := fmt.Sprintf("%s.json", basename) + // Export the native genesis spec used by puppeth and Geth + gethJson := filepath.Join(folder, fmt.Sprintf("%s.json", w.network)) if err := ioutil.WriteFile((gethJson), out, 0644); err != nil { log.Error("Failed to save genesis file", "err", err) + return } - log.Info("Saved geth genesis as %v", gethJson) - if err := convertGenesis(w.conf.Genesis, basename, w.network, w.conf.bootnodes); err != nil { - log.Error("Conversion failed", "err", err) + log.Info("Saved native genesis chain spec", "path", gethJson) + + // Export the genesis spec used by Aleth (formerly C++ Ethereum) + if spec, err := newAlethGenesisSpec(w.network, w.conf.Genesis); err != nil { + log.Error("Failed to create Aleth chain spec", "err", err) + } else { + saveGenesis(folder, w.network, "aleth", spec) } + // Export the genesis spec used by Parity + if spec, err := newParityChainSpec(w.network, w.conf.Genesis, []string{}); err != nil { + log.Error("Failed to create Parity chain spec", "err", err) + } else { + saveGenesis(folder, w.network, "parity", spec) + } + // Export the genesis spec used by Harmony (formerly EthereumJ + saveGenesis(folder, w.network, "harmony", w.conf.Genesis) case "3": // Make sure we don't have any services running @@ -202,29 +274,18 @@ func (w *wizard) manageGenesis() { w.conf.flush() default: log.Error("That's not something I can do") + return } } -func saveGenesis(basename, client string, spec interface{}) { - filename := fmt.Sprintf("%s-%s.json", basename, client) - out, _ := json.Marshal(spec) - if err := ioutil.WriteFile(filename, out, 0644); err != nil { - log.Error("failed to save genesis file", "client", client, "err", err) - } - log.Info("saved chainspec", "client", client, "filename", filename) -} +// saveGenesis JSON encodes an arbitrary genesis spec into a pre-defined file. +func saveGenesis(folder, network, client string, spec interface{}) { + path := filepath.Join(folder, fmt.Sprintf("%s-%s.json", network, client)) -func convertGenesis(genesis *core.Genesis, basename string, network string, bootnodes []string) error { - if spec, err := newAlethGenesisSpec(network, genesis); err == nil { - saveGenesis(basename, "aleth", spec) - } else { - log.Error("failed to create chain spec", "client", "aleth", "err", err) - } - if spec, err := newParityChainSpec(network, genesis, []string{}); err == nil { - saveGenesis(basename, "parity", spec) - } else { - log.Error("failed to create chain spec", "client", "parity", "err", err) + out, _ := json.Marshal(spec) + if err := ioutil.WriteFile(path, out, 0644); err != nil { + log.Error("Failed to save genesis file", "client", client, "err", err) + return } - saveGenesis(basename, "harmony", genesis) - return nil + log.Info("Saved genesis chain spec", "client", client, "path", path) } |