diff --git a/cmd/puppeth/genesis.go b/cmd/puppeth/genesis.go
index 5f39a889d1b583543488bbe2ed88655a97a074ee..83212a126b1d60a216f5ab5af8567ccc041c8b09 100644
--- a/cmd/puppeth/genesis.go
+++ b/cmd/puppeth/genesis.go
@@ -20,35 +20,41 @@ import (
 	"encoding/binary"
 	"errors"
 	"math"
+	"math/big"
+	"strings"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/hexutil"
+	math2 "github.com/ethereum/go-ethereum/common/math"
 	"github.com/ethereum/go-ethereum/consensus/ethash"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/params"
 )
 
-// cppEthereumGenesisSpec represents the genesis specification format used by the
+// alethGenesisSpec represents the genesis specification format used by the
 // C++ Ethereum implementation.
-type cppEthereumGenesisSpec struct {
+type alethGenesisSpec struct {
 	SealEngine string `json:"sealEngine"`
 	Params     struct {
-		AccountStartNonce       hexutil.Uint64 `json:"accountStartNonce"`
-		HomesteadForkBlock      hexutil.Uint64 `json:"homesteadForkBlock"`
-		EIP150ForkBlock         hexutil.Uint64 `json:"EIP150ForkBlock"`
-		EIP158ForkBlock         hexutil.Uint64 `json:"EIP158ForkBlock"`
-		ByzantiumForkBlock      hexutil.Uint64 `json:"byzantiumForkBlock"`
-		ConstantinopleForkBlock hexutil.Uint64 `json:"constantinopleForkBlock"`
-		NetworkID               hexutil.Uint64 `json:"networkID"`
-		ChainID                 hexutil.Uint64 `json:"chainID"`
-		MaximumExtraDataSize    hexutil.Uint64 `json:"maximumExtraDataSize"`
-		MinGasLimit             hexutil.Uint64 `json:"minGasLimit"`
-		MaxGasLimit             hexutil.Uint64 `json:"maxGasLimit"`
-		GasLimitBoundDivisor    hexutil.Uint64 `json:"gasLimitBoundDivisor"`
-		MinimumDifficulty       *hexutil.Big   `json:"minimumDifficulty"`
-		DifficultyBoundDivisor  *hexutil.Big   `json:"difficultyBoundDivisor"`
-		DurationLimit           *hexutil.Big   `json:"durationLimit"`
-		BlockReward             *hexutil.Big   `json:"blockReward"`
+		AccountStartNonce       math2.HexOrDecimal64   `json:"accountStartNonce"`
+		MaximumExtraDataSize    hexutil.Uint64         `json:"maximumExtraDataSize"`
+		HomesteadForkBlock      hexutil.Uint64         `json:"homesteadForkBlock"`
+		DaoHardforkBlock        math2.HexOrDecimal64   `json:"daoHardforkBlock"`
+		EIP150ForkBlock         hexutil.Uint64         `json:"EIP150ForkBlock"`
+		EIP158ForkBlock         hexutil.Uint64         `json:"EIP158ForkBlock"`
+		ByzantiumForkBlock      hexutil.Uint64         `json:"byzantiumForkBlock"`
+		ConstantinopleForkBlock hexutil.Uint64         `json:"constantinopleForkBlock"`
+		MinGasLimit             hexutil.Uint64         `json:"minGasLimit"`
+		MaxGasLimit             hexutil.Uint64         `json:"maxGasLimit"`
+		TieBreakingGas          bool                   `json:"tieBreakingGas"`
+		GasLimitBoundDivisor    math2.HexOrDecimal64   `json:"gasLimitBoundDivisor"`
+		MinimumDifficulty       *hexutil.Big           `json:"minimumDifficulty"`
+		DifficultyBoundDivisor  *math2.HexOrDecimal256 `json:"difficultyBoundDivisor"`
+		DurationLimit           *math2.HexOrDecimal256 `json:"durationLimit"`
+		BlockReward             *hexutil.Big           `json:"blockReward"`
+		NetworkID               hexutil.Uint64         `json:"networkID"`
+		ChainID                 hexutil.Uint64         `json:"chainID"`
+		AllowFutureBlocks       bool                   `json:"allowFutureBlocks""`
 	} `json:"params"`
 
 	Genesis struct {
@@ -62,57 +68,68 @@ type cppEthereumGenesisSpec struct {
 		GasLimit   hexutil.Uint64 `json:"gasLimit"`
 	} `json:"genesis"`
 
-	Accounts map[common.Address]*cppEthereumGenesisSpecAccount `json:"accounts"`
+	Accounts map[common.UnprefixedAddress]*alethGenesisSpecAccount `json:"accounts"`
 }
 
-// cppEthereumGenesisSpecAccount is the prefunded genesis account and/or precompiled
+// alethGenesisSpecAccount is the prefunded genesis account and/or precompiled
 // contract definition.
-type cppEthereumGenesisSpecAccount struct {
-	Balance     *hexutil.Big                   `json:"balance"`
-	Nonce       uint64                         `json:"nonce,omitempty"`
-	Precompiled *cppEthereumGenesisSpecBuiltin `json:"precompiled,omitempty"`
+type alethGenesisSpecAccount struct {
+	Balance     *math2.HexOrDecimal256   `json:"balance"`
+	Nonce       uint64                   `json:"nonce,omitempty"`
+	Precompiled *alethGenesisSpecBuiltin `json:"precompiled,omitempty"`
 }
 
-// cppEthereumGenesisSpecBuiltin is the precompiled contract definition.
-type cppEthereumGenesisSpecBuiltin struct {
-	Name          string                               `json:"name,omitempty"`
-	StartingBlock hexutil.Uint64                       `json:"startingBlock,omitempty"`
-	Linear        *cppEthereumGenesisSpecLinearPricing `json:"linear,omitempty"`
+// alethGenesisSpecBuiltin is the precompiled contract definition.
+type alethGenesisSpecBuiltin struct {
+	Name          string                         `json:"name,omitempty"`
+	StartingBlock hexutil.Uint64                 `json:"startingBlock,omitempty"`
+	Linear        *alethGenesisSpecLinearPricing `json:"linear,omitempty"`
 }
 
-type cppEthereumGenesisSpecLinearPricing struct {
+type alethGenesisSpecLinearPricing struct {
 	Base uint64 `json:"base"`
 	Word uint64 `json:"word"`
 }
 
-// newCppEthereumGenesisSpec converts a go-ethereum genesis block into a Parity specific
+// newAlethGenesisSpec converts a go-ethereum genesis block into a Aleth-specific
 // chain specification format.
-func newCppEthereumGenesisSpec(network string, genesis *core.Genesis) (*cppEthereumGenesisSpec, error) {
-	// Only ethash is currently supported between go-ethereum and cpp-ethereum
+func newAlethGenesisSpec(network string, genesis *core.Genesis) (*alethGenesisSpec, error) {
+	// Only ethash is currently supported between go-ethereum and aleth
 	if genesis.Config.Ethash == nil {
 		return nil, errors.New("unsupported consensus engine")
 	}
-	// Reconstruct the chain spec in Parity's format
-	spec := &cppEthereumGenesisSpec{
+	// Reconstruct the chain spec in Aleth format
+	spec := &alethGenesisSpec{
 		SealEngine: "Ethash",
 	}
+	// Some defaults
 	spec.Params.AccountStartNonce = 0
+	spec.Params.TieBreakingGas = false
+	spec.Params.AllowFutureBlocks = false
+	spec.Params.DaoHardforkBlock = 0
+
 	spec.Params.HomesteadForkBlock = (hexutil.Uint64)(genesis.Config.HomesteadBlock.Uint64())
 	spec.Params.EIP150ForkBlock = (hexutil.Uint64)(genesis.Config.EIP150Block.Uint64())
 	spec.Params.EIP158ForkBlock = (hexutil.Uint64)(genesis.Config.EIP158Block.Uint64())
-	spec.Params.ByzantiumForkBlock = (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64())
-	spec.Params.ConstantinopleForkBlock = (hexutil.Uint64)(math.MaxUint64)
+
+	// Byzantium
+	if num := genesis.Config.ByzantiumBlock; num != nil {
+		spec.setByzantium(num)
+	}
+	// Constantinople
+	if num := genesis.Config.ConstantinopleBlock; num != nil {
+		spec.setConstantinople(num)
+	}
 
 	spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
 	spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
-
 	spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
 	spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
-	spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxUint64)
+	spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxInt64)
 	spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
-	spec.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
-	spec.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor)
-	spec.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
+	spec.Params.DifficultyBoundDivisor = (*math2.HexOrDecimal256)(params.DifficultyBoundDivisor)
+	spec.Params.GasLimitBoundDivisor = (math2.HexOrDecimal64)(params.GasLimitBoundDivisor)
+	spec.Params.DurationLimit = (*math2.HexOrDecimal256)(params.DurationLimit)
 	spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
 
 	spec.Genesis.Nonce = (hexutil.Bytes)(make([]byte, 8))
@@ -126,77 +143,104 @@ func newCppEthereumGenesisSpec(network string, genesis *core.Genesis) (*cppEther
 	spec.Genesis.ExtraData = (hexutil.Bytes)(genesis.ExtraData)
 	spec.Genesis.GasLimit = (hexutil.Uint64)(genesis.GasLimit)
 
-	spec.Accounts = make(map[common.Address]*cppEthereumGenesisSpecAccount)
 	for address, account := range genesis.Alloc {
-		spec.Accounts[address] = &cppEthereumGenesisSpecAccount{
-			Balance: (*hexutil.Big)(account.Balance),
-			Nonce:   account.Nonce,
-		}
+		spec.setAccount(address, account)
 	}
-	spec.Accounts[common.BytesToAddress([]byte{1})].Precompiled = &cppEthereumGenesisSpecBuiltin{
-		Name: "ecrecover", Linear: &cppEthereumGenesisSpecLinearPricing{Base: 3000},
-	}
-	spec.Accounts[common.BytesToAddress([]byte{2})].Precompiled = &cppEthereumGenesisSpecBuiltin{
-		Name: "sha256", Linear: &cppEthereumGenesisSpecLinearPricing{Base: 60, Word: 12},
+
+	spec.setPrecompile(1, &alethGenesisSpecBuiltin{Name: "ecrecover",
+		Linear: &alethGenesisSpecLinearPricing{Base: 3000}})
+	spec.setPrecompile(2, &alethGenesisSpecBuiltin{Name: "sha256",
+		Linear: &alethGenesisSpecLinearPricing{Base: 60, Word: 12}})
+	spec.setPrecompile(3, &alethGenesisSpecBuiltin{Name: "ripemd160",
+		Linear: &alethGenesisSpecLinearPricing{Base: 600, Word: 120}})
+	spec.setPrecompile(4, &alethGenesisSpecBuiltin{Name: "identity",
+		Linear: &alethGenesisSpecLinearPricing{Base: 15, Word: 3}})
+	if genesis.Config.ByzantiumBlock != nil {
+		spec.setPrecompile(5, &alethGenesisSpecBuiltin{Name: "modexp",
+			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64())})
+		spec.setPrecompile(6, &alethGenesisSpecBuiltin{Name: "alt_bn128_G1_add",
+			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()),
+			Linear:        &alethGenesisSpecLinearPricing{Base: 500}})
+		spec.setPrecompile(7, &alethGenesisSpecBuiltin{Name: "alt_bn128_G1_mul",
+			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()),
+			Linear:        &alethGenesisSpecLinearPricing{Base: 40000}})
+		spec.setPrecompile(8, &alethGenesisSpecBuiltin{Name: "alt_bn128_pairing_product",
+			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64())})
 	}
-	spec.Accounts[common.BytesToAddress([]byte{3})].Precompiled = &cppEthereumGenesisSpecBuiltin{
-		Name: "ripemd160", Linear: &cppEthereumGenesisSpecLinearPricing{Base: 600, Word: 120},
+	return spec, nil
+}
+
+func (spec *alethGenesisSpec) setPrecompile(address byte, data *alethGenesisSpecBuiltin) {
+	if spec.Accounts == nil {
+		spec.Accounts = make(map[common.UnprefixedAddress]*alethGenesisSpecAccount)
 	}
-	spec.Accounts[common.BytesToAddress([]byte{4})].Precompiled = &cppEthereumGenesisSpecBuiltin{
-		Name: "identity", Linear: &cppEthereumGenesisSpecLinearPricing{Base: 15, Word: 3},
+	spec.Accounts[common.UnprefixedAddress(common.BytesToAddress([]byte{address}))].Precompiled = data
+}
+
+func (spec *alethGenesisSpec) setAccount(address common.Address, account core.GenesisAccount) {
+	if spec.Accounts == nil {
+		spec.Accounts = make(map[common.UnprefixedAddress]*alethGenesisSpecAccount)
 	}
-	if genesis.Config.ByzantiumBlock != nil {
-		spec.Accounts[common.BytesToAddress([]byte{5})].Precompiled = &cppEthereumGenesisSpecBuiltin{
-			Name: "modexp", StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()),
-		}
-		spec.Accounts[common.BytesToAddress([]byte{6})].Precompiled = &cppEthereumGenesisSpecBuiltin{
-			Name: "alt_bn128_G1_add", StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()), Linear: &cppEthereumGenesisSpecLinearPricing{Base: 500},
-		}
-		spec.Accounts[common.BytesToAddress([]byte{7})].Precompiled = &cppEthereumGenesisSpecBuiltin{
-			Name: "alt_bn128_G1_mul", StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()), Linear: &cppEthereumGenesisSpecLinearPricing{Base: 40000},
-		}
-		spec.Accounts[common.BytesToAddress([]byte{8})].Precompiled = &cppEthereumGenesisSpecBuiltin{
-			Name: "alt_bn128_pairing_product", StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()),
-		}
+
+	a, exist := spec.Accounts[common.UnprefixedAddress(address)]
+	if !exist {
+		a = &alethGenesisSpecAccount{}
+		spec.Accounts[common.UnprefixedAddress(address)] = a
 	}
-	return spec, nil
+	a.Balance = (*math2.HexOrDecimal256)(account.Balance)
+	a.Nonce = account.Nonce
+
+}
+
+func (spec *alethGenesisSpec) setByzantium(num *big.Int) {
+	spec.Params.ByzantiumForkBlock = hexutil.Uint64(num.Uint64())
+}
+
+func (spec *alethGenesisSpec) setConstantinople(num *big.Int) {
+	spec.Params.ConstantinopleForkBlock = hexutil.Uint64(num.Uint64())
 }
 
 // parityChainSpec is the chain specification format used by Parity.
 type parityChainSpec struct {
-	Name   string `json:"name"`
-	Engine struct {
+	Name    string `json:"name"`
+	Datadir string `json:"dataDir"`
+	Engine  struct {
 		Ethash struct {
 			Params struct {
-				MinimumDifficulty      *hexutil.Big `json:"minimumDifficulty"`
-				DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"`
-				DurationLimit          *hexutil.Big `json:"durationLimit"`
-				BlockReward            *hexutil.Big `json:"blockReward"`
-				HomesteadTransition    uint64       `json:"homesteadTransition"`
-				EIP150Transition       uint64       `json:"eip150Transition"`
-				EIP160Transition       uint64       `json:"eip160Transition"`
-				EIP161abcTransition    uint64       `json:"eip161abcTransition"`
-				EIP161dTransition      uint64       `json:"eip161dTransition"`
-				EIP649Reward           *hexutil.Big `json:"eip649Reward"`
-				EIP100bTransition      uint64       `json:"eip100bTransition"`
-				EIP649Transition       uint64       `json:"eip649Transition"`
+				MinimumDifficulty      *hexutil.Big      `json:"minimumDifficulty"`
+				DifficultyBoundDivisor *hexutil.Big      `json:"difficultyBoundDivisor"`
+				DurationLimit          *hexutil.Big      `json:"durationLimit"`
+				BlockReward            map[string]string `json:"blockReward"`
+				DifficultyBombDelays   map[string]string `json:"difficultyBombDelays"`
+				HomesteadTransition    hexutil.Uint64    `json:"homesteadTransition"`
+				EIP100bTransition      hexutil.Uint64    `json:"eip100bTransition"`
 			} `json:"params"`
 		} `json:"Ethash"`
 	} `json:"engine"`
 
 	Params struct {
-		MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"`
-		MinGasLimit          hexutil.Uint64 `json:"minGasLimit"`
-		GasLimitBoundDivisor hexutil.Uint64 `json:"gasLimitBoundDivisor"`
-		NetworkID            hexutil.Uint64 `json:"networkID"`
-		MaxCodeSize          uint64         `json:"maxCodeSize"`
-		EIP155Transition     uint64         `json:"eip155Transition"`
-		EIP98Transition      uint64         `json:"eip98Transition"`
-		EIP86Transition      uint64         `json:"eip86Transition"`
-		EIP140Transition     uint64         `json:"eip140Transition"`
-		EIP211Transition     uint64         `json:"eip211Transition"`
-		EIP214Transition     uint64         `json:"eip214Transition"`
-		EIP658Transition     uint64         `json:"eip658Transition"`
+		AccountStartNonce     hexutil.Uint64       `json:"accountStartNonce"`
+		MaximumExtraDataSize  hexutil.Uint64       `json:"maximumExtraDataSize"`
+		MinGasLimit           hexutil.Uint64       `json:"minGasLimit"`
+		GasLimitBoundDivisor  math2.HexOrDecimal64 `json:"gasLimitBoundDivisor"`
+		NetworkID             hexutil.Uint64       `json:"networkID"`
+		ChainID               hexutil.Uint64       `json:"chainID"`
+		MaxCodeSize           hexutil.Uint64       `json:"maxCodeSize"`
+		MaxCodeSizeTransition hexutil.Uint64       `json:"maxCodeSizeTransition"`
+		EIP98Transition       hexutil.Uint64       `json:"eip98Transition"`
+		EIP150Transition      hexutil.Uint64       `json:"eip150Transition"`
+		EIP160Transition      hexutil.Uint64       `json:"eip160Transition"`
+		EIP161abcTransition   hexutil.Uint64       `json:"eip161abcTransition"`
+		EIP161dTransition     hexutil.Uint64       `json:"eip161dTransition"`
+		EIP155Transition      hexutil.Uint64       `json:"eip155Transition"`
+		EIP140Transition      hexutil.Uint64       `json:"eip140Transition"`
+		EIP211Transition      hexutil.Uint64       `json:"eip211Transition"`
+		EIP214Transition      hexutil.Uint64       `json:"eip214Transition"`
+		EIP658Transition      hexutil.Uint64       `json:"eip658Transition"`
+		EIP145Transition      hexutil.Uint64       `json:"eip145Transition"`
+		EIP1014Transition     hexutil.Uint64       `json:"eip1014Transition"`
+		EIP1052Transition     hexutil.Uint64       `json:"eip1052Transition"`
+		EIP1283Transition     hexutil.Uint64       `json:"eip1283Transition"`
 	} `json:"params"`
 
 	Genesis struct {
@@ -215,22 +259,22 @@ type parityChainSpec struct {
 		GasLimit   hexutil.Uint64 `json:"gasLimit"`
 	} `json:"genesis"`
 
-	Nodes    []string                                   `json:"nodes"`
-	Accounts map[common.Address]*parityChainSpecAccount `json:"accounts"`
+	Nodes    []string                                             `json:"nodes"`
+	Accounts map[common.UnprefixedAddress]*parityChainSpecAccount `json:"accounts"`
 }
 
 // parityChainSpecAccount is the prefunded genesis account and/or precompiled
 // contract definition.
 type parityChainSpecAccount struct {
-	Balance *hexutil.Big            `json:"balance"`
-	Nonce   uint64                  `json:"nonce,omitempty"`
+	Balance math2.HexOrDecimal256   `json:"balance"`
+	Nonce   math2.HexOrDecimal64    `json:"nonce,omitempty"`
 	Builtin *parityChainSpecBuiltin `json:"builtin,omitempty"`
 }
 
 // parityChainSpecBuiltin is the precompiled contract definition.
 type parityChainSpecBuiltin struct {
 	Name       string                  `json:"name,omitempty"`
-	ActivateAt uint64                  `json:"activate_at,omitempty"`
+	ActivateAt math2.HexOrDecimal64    `json:"activate_at,omitempty"`
 	Pricing    *parityChainSpecPricing `json:"pricing,omitempty"`
 }
 
@@ -265,34 +309,51 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
 	}
 	// Reconstruct the chain spec in Parity's format
 	spec := &parityChainSpec{
-		Name:  network,
-		Nodes: bootnodes,
+		Name:    network,
+		Nodes:   bootnodes,
+		Datadir: strings.ToLower(network),
 	}
+	spec.Engine.Ethash.Params.BlockReward = make(map[string]string)
+	spec.Engine.Ethash.Params.DifficultyBombDelays = make(map[string]string)
+	// Frontier
 	spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
 	spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
 	spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
-	spec.Engine.Ethash.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
-	spec.Engine.Ethash.Params.HomesteadTransition = genesis.Config.HomesteadBlock.Uint64()
-	spec.Engine.Ethash.Params.EIP150Transition = genesis.Config.EIP150Block.Uint64()
-	spec.Engine.Ethash.Params.EIP160Transition = genesis.Config.EIP155Block.Uint64()
-	spec.Engine.Ethash.Params.EIP161abcTransition = genesis.Config.EIP158Block.Uint64()
-	spec.Engine.Ethash.Params.EIP161dTransition = genesis.Config.EIP158Block.Uint64()
-	spec.Engine.Ethash.Params.EIP649Reward = (*hexutil.Big)(ethash.ByzantiumBlockReward)
-	spec.Engine.Ethash.Params.EIP100bTransition = genesis.Config.ByzantiumBlock.Uint64()
-	spec.Engine.Ethash.Params.EIP649Transition = genesis.Config.ByzantiumBlock.Uint64()
+	spec.Engine.Ethash.Params.BlockReward["0x0"] = hexutil.EncodeBig(ethash.FrontierBlockReward)
+
+	// Homestead
+	spec.Engine.Ethash.Params.HomesteadTransition = hexutil.Uint64(genesis.Config.HomesteadBlock.Uint64())
+
+	// Tangerine Whistle : 150
+	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md
+	spec.Params.EIP150Transition = hexutil.Uint64(genesis.Config.EIP150Block.Uint64())
+
+	// Spurious Dragon: 155, 160, 161, 170
+	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md
+	spec.Params.EIP155Transition = hexutil.Uint64(genesis.Config.EIP155Block.Uint64())
+	spec.Params.EIP160Transition = hexutil.Uint64(genesis.Config.EIP155Block.Uint64())
+	spec.Params.EIP161abcTransition = hexutil.Uint64(genesis.Config.EIP158Block.Uint64())
+	spec.Params.EIP161dTransition = hexutil.Uint64(genesis.Config.EIP158Block.Uint64())
 
+	// Byzantium
+	if num := genesis.Config.ByzantiumBlock; num != nil {
+		spec.setByzantium(num)
+	}
+	// Constantinople
+	if num := genesis.Config.ConstantinopleBlock; num != nil {
+		spec.setConstantinople(num)
+	}
 	spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
 	spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
-	spec.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor)
+	spec.Params.GasLimitBoundDivisor = (math2.HexOrDecimal64)(params.GasLimitBoundDivisor)
 	spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
+	spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
 	spec.Params.MaxCodeSize = params.MaxCodeSize
-	spec.Params.EIP155Transition = genesis.Config.EIP155Block.Uint64()
-	spec.Params.EIP98Transition = math.MaxUint64
-	spec.Params.EIP86Transition = math.MaxUint64
-	spec.Params.EIP140Transition = genesis.Config.ByzantiumBlock.Uint64()
-	spec.Params.EIP211Transition = genesis.Config.ByzantiumBlock.Uint64()
-	spec.Params.EIP214Transition = genesis.Config.ByzantiumBlock.Uint64()
-	spec.Params.EIP658Transition = genesis.Config.ByzantiumBlock.Uint64()
+	// geth has it set from zero
+	spec.Params.MaxCodeSizeTransition = 0
+
+	// Disable this one
+	spec.Params.EIP98Transition = math.MaxInt64
 
 	spec.Genesis.Seal.Ethereum.Nonce = (hexutil.Bytes)(make([]byte, 8))
 	binary.LittleEndian.PutUint64(spec.Genesis.Seal.Ethereum.Nonce[:], genesis.Nonce)
@@ -305,42 +366,77 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
 	spec.Genesis.ExtraData = (hexutil.Bytes)(genesis.ExtraData)
 	spec.Genesis.GasLimit = (hexutil.Uint64)(genesis.GasLimit)
 
-	spec.Accounts = make(map[common.Address]*parityChainSpecAccount)
+	spec.Accounts = make(map[common.UnprefixedAddress]*parityChainSpecAccount)
 	for address, account := range genesis.Alloc {
-		spec.Accounts[address] = &parityChainSpecAccount{
-			Balance: (*hexutil.Big)(account.Balance),
-			Nonce:   account.Nonce,
+		bal := math2.HexOrDecimal256(*account.Balance)
+
+		spec.Accounts[common.UnprefixedAddress(address)] = &parityChainSpecAccount{
+			Balance: bal,
+			Nonce:   math2.HexOrDecimal64(account.Nonce),
 		}
 	}
-	spec.Accounts[common.BytesToAddress([]byte{1})].Builtin = &parityChainSpecBuiltin{
-		Name: "ecrecover", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 3000}},
-	}
-	spec.Accounts[common.BytesToAddress([]byte{2})].Builtin = &parityChainSpecBuiltin{
+	spec.setPrecompile(1, &parityChainSpecBuiltin{Name: "ecrecover",
+		Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 3000}}})
+
+	spec.setPrecompile(2, &parityChainSpecBuiltin{
 		Name: "sha256", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 60, Word: 12}},
-	}
-	spec.Accounts[common.BytesToAddress([]byte{3})].Builtin = &parityChainSpecBuiltin{
+	})
+	spec.setPrecompile(3, &parityChainSpecBuiltin{
 		Name: "ripemd160", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 600, Word: 120}},
-	}
-	spec.Accounts[common.BytesToAddress([]byte{4})].Builtin = &parityChainSpecBuiltin{
+	})
+	spec.setPrecompile(4, &parityChainSpecBuiltin{
 		Name: "identity", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 15, Word: 3}},
-	}
+	})
 	if genesis.Config.ByzantiumBlock != nil {
-		spec.Accounts[common.BytesToAddress([]byte{5})].Builtin = &parityChainSpecBuiltin{
-			Name: "modexp", ActivateAt: genesis.Config.ByzantiumBlock.Uint64(), Pricing: &parityChainSpecPricing{ModExp: &parityChainSpecModExpPricing{Divisor: 20}},
-		}
-		spec.Accounts[common.BytesToAddress([]byte{6})].Builtin = &parityChainSpecBuiltin{
-			Name: "alt_bn128_add", ActivateAt: genesis.Config.ByzantiumBlock.Uint64(), Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 500}},
-		}
-		spec.Accounts[common.BytesToAddress([]byte{7})].Builtin = &parityChainSpecBuiltin{
-			Name: "alt_bn128_mul", ActivateAt: genesis.Config.ByzantiumBlock.Uint64(), Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 40000}},
-		}
-		spec.Accounts[common.BytesToAddress([]byte{8})].Builtin = &parityChainSpecBuiltin{
-			Name: "alt_bn128_pairing", ActivateAt: genesis.Config.ByzantiumBlock.Uint64(), Pricing: &parityChainSpecPricing{AltBnPairing: &parityChainSpecAltBnPairingPricing{Base: 100000, Pair: 80000}},
-		}
+		blnum := math2.HexOrDecimal64(genesis.Config.ByzantiumBlock.Uint64())
+		spec.setPrecompile(5, &parityChainSpecBuiltin{
+			Name: "modexp", ActivateAt: blnum, Pricing: &parityChainSpecPricing{ModExp: &parityChainSpecModExpPricing{Divisor: 20}},
+		})
+		spec.setPrecompile(6, &parityChainSpecBuiltin{
+			Name: "alt_bn128_add", ActivateAt: blnum, Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 500}},
+		})
+		spec.setPrecompile(7, &parityChainSpecBuiltin{
+			Name: "alt_bn128_mul", ActivateAt: blnum, Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 40000}},
+		})
+		spec.setPrecompile(8, &parityChainSpecBuiltin{
+			Name: "alt_bn128_pairing", ActivateAt: blnum, Pricing: &parityChainSpecPricing{AltBnPairing: &parityChainSpecAltBnPairingPricing{Base: 100000, Pair: 80000}},
+		})
 	}
 	return spec, nil
 }
 
+func (spec *parityChainSpec) setPrecompile(address byte, data *parityChainSpecBuiltin) {
+	if spec.Accounts == nil {
+		spec.Accounts = make(map[common.UnprefixedAddress]*parityChainSpecAccount)
+	}
+	a := common.UnprefixedAddress(common.BytesToAddress([]byte{address}))
+	if _, exist := spec.Accounts[a]; !exist {
+		spec.Accounts[a] = &parityChainSpecAccount{}
+	}
+	spec.Accounts[a].Builtin = data
+}
+
+func (spec *parityChainSpec) setByzantium(num *big.Int) {
+	spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.ByzantiumBlockReward)
+	spec.Engine.Ethash.Params.DifficultyBombDelays[hexutil.EncodeBig(num)] = hexutil.EncodeUint64(3000000)
+	n := hexutil.Uint64(num.Uint64())
+	spec.Engine.Ethash.Params.EIP100bTransition = n
+	spec.Params.EIP140Transition = n
+	spec.Params.EIP211Transition = n
+	spec.Params.EIP214Transition = n
+	spec.Params.EIP658Transition = n
+}
+
+func (spec *parityChainSpec) setConstantinople(num *big.Int) {
+	spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.ConstantinopleBlockReward)
+	spec.Engine.Ethash.Params.DifficultyBombDelays[hexutil.EncodeBig(num)] = hexutil.EncodeUint64(2000000)
+	n := hexutil.Uint64(num.Uint64())
+	spec.Params.EIP145Transition = n
+	spec.Params.EIP1014Transition = n
+	spec.Params.EIP1052Transition = n
+	spec.Params.EIP1283Transition = n
+}
+
 // pyEthereumGenesisSpec represents the genesis specification format used by the
 // Python Ethereum implementation.
 type pyEthereumGenesisSpec struct {
diff --git a/cmd/puppeth/genesis_test.go b/cmd/puppeth/genesis_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..83e73836057233c317a1243e6e826af092eb12cd
--- /dev/null
+++ b/cmd/puppeth/genesis_test.go
@@ -0,0 +1,109 @@
+// Copyright 2018 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 (
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"reflect"
+	"strings"
+	"testing"
+
+	"github.com/davecgh/go-spew/spew"
+	"github.com/ethereum/go-ethereum/core"
+)
+
+// Tests the go-ethereum to Aleth chainspec conversion for the Stureby testnet.
+func TestAlethSturebyConverter(t *testing.T) {
+	blob, err := ioutil.ReadFile("testdata/stureby_geth.json")
+	if err != nil {
+		t.Fatalf("could not read file: %v", err)
+	}
+	var genesis core.Genesis
+	if err := json.Unmarshal(blob, &genesis); err != nil {
+		t.Fatalf("failed parsing genesis: %v", err)
+	}
+	spec, err := newAlethGenesisSpec("stureby", &genesis)
+	if err != nil {
+		t.Fatalf("failed creating chainspec: %v", err)
+	}
+
+	expBlob, err := ioutil.ReadFile("testdata/stureby_aleth.json")
+	if err != nil {
+		t.Fatalf("could not read file: %v", err)
+	}
+	expspec := &alethGenesisSpec{}
+	if err := json.Unmarshal(expBlob, expspec); err != nil {
+		t.Fatalf("failed parsing genesis: %v", err)
+	}
+	if !reflect.DeepEqual(expspec, spec) {
+		t.Errorf("chainspec mismatch")
+		c := spew.ConfigState{
+			DisablePointerAddresses: true,
+			SortKeys:                true,
+		}
+		exp := strings.Split(c.Sdump(expspec), "\n")
+		got := strings.Split(c.Sdump(spec), "\n")
+		for i := 0; i < len(exp) && i < len(got); i++ {
+			if exp[i] != got[i] {
+				fmt.Printf("got: %v\nexp: %v\n", exp[i], got[i])
+			}
+		}
+	}
+}
+
+// Tests the go-ethereum to Parity chainspec conversion for the Stureby testnet.
+func TestParitySturebyConverter(t *testing.T) {
+	blob, err := ioutil.ReadFile("testdata/stureby_geth.json")
+	if err != nil {
+		t.Fatalf("could not read file: %v", err)
+	}
+	var genesis core.Genesis
+	if err := json.Unmarshal(blob, &genesis); err != nil {
+		t.Fatalf("failed parsing genesis: %v", err)
+	}
+	spec, err := newParityChainSpec("Stureby", &genesis, []string{})
+	if err != nil {
+		t.Fatalf("failed creating chainspec: %v", err)
+	}
+
+	expBlob, err := ioutil.ReadFile("testdata/stureby_parity.json")
+	if err != nil {
+		t.Fatalf("could not read file: %v", err)
+	}
+	expspec := &parityChainSpec{}
+	if err := json.Unmarshal(expBlob, expspec); err != nil {
+		t.Fatalf("failed parsing genesis: %v", err)
+	}
+	expspec.Nodes = []string{}
+
+	if !reflect.DeepEqual(expspec, spec) {
+		t.Errorf("chainspec mismatch")
+		c := spew.ConfigState{
+			DisablePointerAddresses: true,
+			SortKeys:                true,
+		}
+		exp := strings.Split(c.Sdump(expspec), "\n")
+		got := strings.Split(c.Sdump(spec), "\n")
+		for i := 0; i < len(exp) && i < len(got); i++ {
+			if exp[i] != got[i] {
+				fmt.Printf("got: %v\nexp: %v\n", exp[i], got[i])
+			}
+		}
+	}
+}
diff --git a/cmd/puppeth/module_dashboard.go b/cmd/puppeth/module_dashboard.go
index d22bd8110398a2bff38c29f30cdcb56221ad4f11..cb3ed6e71ccb2a96c60b88bf377adaf33f0f4b01 100644
--- a/cmd/puppeth/module_dashboard.go
+++ b/cmd/puppeth/module_dashboard.go
@@ -640,7 +640,7 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da
 	files[filepath.Join(workdir, network+".json")] = genesis
 
 	if conf.Genesis.Config.Ethash != nil {
-		cppSpec, err := newCppEthereumGenesisSpec(network, conf.Genesis)
+		cppSpec, err := newAlethGenesisSpec(network, conf.Genesis)
 		if err != nil {
 			return nil, err
 		}
diff --git a/cmd/puppeth/puppeth.go b/cmd/puppeth/puppeth.go
index df3fff51b0190b8f757da8fca406245be7282899..c3de5f9360242ebdc460c49eb6ee4d6c6314d5b0 100644
--- a/cmd/puppeth/puppeth.go
+++ b/cmd/puppeth/puppeth.go
@@ -43,18 +43,23 @@ func main() {
 			Usage: "log level to emit to the screen",
 		},
 	}
-	app.Action = func(c *cli.Context) error {
+	app.Before = func(c *cli.Context) error {
 		// Set up the logger to print everything and the random generator
 		log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(c.Int("loglevel")), log.StreamHandler(os.Stdout, log.TerminalFormat(true))))
 		rand.Seed(time.Now().UnixNano())
 
-		network := c.String("network")
-		if strings.Contains(network, " ") || strings.Contains(network, "-") || strings.ToLower(network) != network {
-			log.Crit("No spaces, hyphens or capital letters allowed in network name")
-		}
-		// Start the wizard and relinquish control
-		makeWizard(c.String("network")).run()
 		return nil
 	}
+	app.Action = runWizard
 	app.Run(os.Args)
 }
+
+// runWizard start the wizard and relinquish control to it.
+func runWizard(c *cli.Context) error {
+	network := c.String("network")
+	if strings.Contains(network, " ") || strings.Contains(network, "-") || strings.ToLower(network) != network {
+		log.Crit("No spaces, hyphens or capital letters allowed in network name")
+	}
+	makeWizard(c.String("network")).run()
+	return nil
+}
diff --git a/cmd/puppeth/testdata/stureby_aleth.json b/cmd/puppeth/testdata/stureby_aleth.json
new file mode 100644
index 0000000000000000000000000000000000000000..1ef1d8ae1866ce146e8d3e14977c15b037d8098b
--- /dev/null
+++ b/cmd/puppeth/testdata/stureby_aleth.json
@@ -0,0 +1,112 @@
+{
+  "sealEngine":"Ethash",
+  "params":{
+    "accountStartNonce":"0x00",
+    "maximumExtraDataSize":"0x20",
+    "homesteadForkBlock":"0x2710",
+    "daoHardforkBlock":"0x00",
+    "EIP150ForkBlock":"0x3a98",
+    "EIP158ForkBlock":"0x59d8",
+    "byzantiumForkBlock":"0x7530",
+    "constantinopleForkBlock":"0x9c40",
+    "minGasLimit":"0x1388",
+    "maxGasLimit":"0x7fffffffffffffff",
+    "tieBreakingGas":false,
+    "gasLimitBoundDivisor":"0x0400",
+    "minimumDifficulty":"0x20000",
+    "difficultyBoundDivisor":"0x0800",
+    "durationLimit":"0x0d",
+    "blockReward":"0x4563918244F40000",
+    "networkID":"0x4cb2e",
+    "chainID":"0x4cb2e",
+    "allowFutureBlocks":false
+  },
+  "genesis":{
+    "nonce":"0x0000000000000000",
+    "difficulty":"0x20000",
+    "mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
+    "author":"0x0000000000000000000000000000000000000000",
+    "timestamp":"0x59a4e76d",
+    "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
+    "extraData":"0x0000000000000000000000000000000000000000000000000000000b4dc0ffee",
+    "gasLimit":"0x47b760"
+  },
+  "accounts":{
+    "0000000000000000000000000000000000000001":{
+      "balance":"1",
+      "precompiled":{
+        "name":"ecrecover",
+        "linear":{
+          "base":3000,
+          "word":0
+        }
+      }
+    },
+    "0000000000000000000000000000000000000002":{
+      "balance":"1",
+      "precompiled":{
+        "name":"sha256",
+        "linear":{
+          "base":60,
+          "word":12
+        }
+      }
+    },
+    "0000000000000000000000000000000000000003":{
+      "balance":"1",
+      "precompiled":{
+        "name":"ripemd160",
+        "linear":{
+          "base":600,
+          "word":120
+        }
+      }
+    },
+    "0000000000000000000000000000000000000004":{
+      "balance":"1",
+      "precompiled":{
+        "name":"identity",
+        "linear":{
+          "base":15,
+          "word":3
+        }
+      }
+    },
+    "0000000000000000000000000000000000000005":{
+      "balance":"1",
+      "precompiled":{
+        "name":"modexp",
+        "startingBlock":"0x7530"
+      }
+    },
+    "0000000000000000000000000000000000000006":{
+      "balance":"1",
+      "precompiled":{
+        "name":"alt_bn128_G1_add",
+        "startingBlock":"0x7530",
+        "linear":{
+          "base":500,
+          "word":0
+        }
+      }
+    },
+    "0000000000000000000000000000000000000007":{
+      "balance":"1",
+      "precompiled":{
+        "name":"alt_bn128_G1_mul",
+        "startingBlock":"0x7530",
+        "linear":{
+          "base":40000,
+          "word":0
+        }
+      }
+    },
+    "0000000000000000000000000000000000000008":{
+      "balance":"1",
+      "precompiled":{
+        "name":"alt_bn128_pairing_product",
+        "startingBlock":"0x7530"
+      }
+    }
+  }
+}
diff --git a/cmd/puppeth/testdata/stureby_geth.json b/cmd/puppeth/testdata/stureby_geth.json
new file mode 100644
index 0000000000000000000000000000000000000000..c8c3b3c9564c2285f7f4998b723abe00db9092c8
--- /dev/null
+++ b/cmd/puppeth/testdata/stureby_geth.json
@@ -0,0 +1,47 @@
+{
+  "config": {
+    "ethash":{},
+    "chainId": 314158,
+    "homesteadBlock": 10000,
+    "eip150Block": 15000,
+    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+    "eip155Block": 23000,
+    "eip158Block": 23000,
+    "byzantiumBlock": 30000,
+    "constantinopleBlock": 40000
+  },
+  "nonce": "0x0",
+  "timestamp": "0x59a4e76d",
+  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+  "extraData": "0x0000000000000000000000000000000000000000000000000000000b4dc0ffee",
+  "gasLimit": "0x47b760",
+  "difficulty": "0x20000",
+  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+  "coinbase": "0x0000000000000000000000000000000000000000",
+  "alloc": {
+    "0000000000000000000000000000000000000001": {
+      "balance": "0x01"
+    },
+    "0000000000000000000000000000000000000002": {
+      "balance": "0x01"
+    },
+    "0000000000000000000000000000000000000003": {
+      "balance": "0x01"
+    },
+    "0000000000000000000000000000000000000004": {
+      "balance": "0x01"
+    },
+    "0000000000000000000000000000000000000005": {
+      "balance": "0x01"
+    },
+    "0000000000000000000000000000000000000006": {
+      "balance": "0x01"
+    },
+    "0000000000000000000000000000000000000007": {
+      "balance": "0x01"
+    },
+    "0000000000000000000000000000000000000008": {
+      "balance": "0x01"
+    }
+  }
+}
diff --git a/cmd/puppeth/testdata/stureby_parity.json b/cmd/puppeth/testdata/stureby_parity.json
new file mode 100644
index 0000000000000000000000000000000000000000..f3fa8386a0618f032d33e02d49a6d0875ce27fd1
--- /dev/null
+++ b/cmd/puppeth/testdata/stureby_parity.json
@@ -0,0 +1,181 @@
+{
+  "name":"Stureby",
+  "dataDir":"stureby",
+  "engine":{
+    "Ethash":{
+      "params":{
+        "minimumDifficulty":"0x20000",
+        "difficultyBoundDivisor":"0x800",
+        "durationLimit":"0xd",
+        "blockReward":{
+          "0x0":"0x4563918244f40000",
+          "0x7530":"0x29a2241af62c0000",
+          "0x9c40":"0x1bc16d674ec80000"
+        },
+        "homesteadTransition":"0x2710",
+        "eip100bTransition":"0x7530",
+        "difficultyBombDelays":{
+          "0x7530":"0x2dc6c0",
+          "0x9c40":"0x1e8480"
+        }
+      }
+    }
+  },
+  "params":{
+    "accountStartNonce":"0x0",
+    "maximumExtraDataSize":"0x20",
+    "gasLimitBoundDivisor":"0x400",
+    "minGasLimit":"0x1388",
+    "networkID":"0x4cb2e",
+    "chainID":"0x4cb2e",
+    "maxCodeSize":"0x6000",
+    "maxCodeSizeTransition":"0x0",
+    "eip98Transition": "0x7fffffffffffffff",
+    "eip150Transition":"0x3a98",
+    "eip160Transition":"0x59d8",
+    "eip161abcTransition":"0x59d8",
+    "eip161dTransition":"0x59d8",
+    "eip155Transition":"0x59d8",
+    "eip140Transition":"0x7530",
+    "eip211Transition":"0x7530",
+    "eip214Transition":"0x7530",
+    "eip658Transition":"0x7530",
+    "eip145Transition":"0x9c40",
+    "eip1014Transition":"0x9c40",
+    "eip1052Transition":"0x9c40",
+    "eip1283Transition":"0x9c40"
+  },
+  "genesis":{
+    "seal":{
+      "ethereum":{
+        "nonce":"0x0000000000000000",
+        "mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000"
+      }
+    },
+    "difficulty":"0x20000",
+    "author":"0x0000000000000000000000000000000000000000",
+    "timestamp":"0x59a4e76d",
+    "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
+    "extraData":"0x0000000000000000000000000000000000000000000000000000000b4dc0ffee",
+    "gasLimit":"0x47b760"
+  },
+  "nodes":[
+    "enode://dfa7aca3f5b635fbfe7d0b20575f25e40d9e27b4bfbb3cf74364a42023ad9f25c1a4383bcc8cced86ee511a7d03415345a4df05be37f1dff040e4c780699f1c0@168.61.153.255:31303",
+    "enode://ef441b20dd70aeabf0eac35c3b8a2854e5ce04db0e30be9152ea9fd129359dcbb3f803993303ff5781c755dfd7223f3fe43505f583cccb740949407677412ba9@40.74.91.252:31303",
+    "enode://953b5ea1c8987cf46008232a0160324fd00d41320ecf00e23af86ec8f5396b19eb57ddab37c78141be56f62e9077de4f4dfa0747fa768ed8c8531bbfb1046237@40.70.214.166:31303",
+    "enode://276e613dd4b277a66591e565711e6c8bb107f0905248a9f8f8228c1a87992e156e5114bb9937c02824a9d9d25f76340442cf86e2028bf5293cae19904fb2b98e@35.178.251.52:30303",
+    "enode://064c820d41e52ed7d426ac64b60506c2998235bedc7e67cb497c6faf7bb4fc54fe56fc82d0add3180b747c0c4f40a1108a6f84d7d0629ed606d504528e61cc57@3.8.5.3:30303",
+    "enode://90069fdabcc5e684fa5d59430bebbb12755d9362dfe5006a1485b13d71a78a3812d36e74dd7d88e50b51add01e097ea80f16263aeaa4f0230db6c79e2a97e7ca@217.29.191.142:30303",
+    "enode://0aac74b7fd28726275e466acb5e03bc88a95927e9951eb66b5efb239b2f798ada0690853b2f2823fe4efa408f0f3d4dd258430bc952a5ff70677b8625b3e3b14@40.115.33.57:40404",
+    "enode://0b96415a10f835106d83e090a0528eed5e7887e5c802a6d084e9f1993a9d0fc713781e6e4101f6365e9b91259712f291acc0a9e6e667e22023050d602c36fbe2@40.115.33.57:40414"
+  ],
+  "accounts":{
+    "0000000000000000000000000000000000000001":{
+      "balance":"1",
+      "nonce":"0",
+      "builtin":{
+        "name":"ecrecover",
+        "pricing":{
+          "linear":{
+            "base":3000,
+            "word":0
+          }
+        }
+      }
+    },
+    "0000000000000000000000000000000000000002":{
+      "balance":"1",
+      "nonce":"0",
+      "builtin":{
+        "name":"sha256",
+        "pricing":{
+          "linear":{
+            "base":60,
+            "word":12
+          }
+        }
+      }
+    },
+    "0000000000000000000000000000000000000003":{
+      "balance":"1",
+      "nonce":"0",
+      "builtin":{
+        "name":"ripemd160",
+        "pricing":{
+          "linear":{
+            "base":600,
+            "word":120
+          }
+        }
+      }
+    },
+    "0000000000000000000000000000000000000004":{
+      "balance":"1",
+      "nonce":"0",
+      "builtin":{
+        "name":"identity",
+        "pricing":{
+          "linear":{
+            "base":15,
+            "word":3
+          }
+        }
+      }
+    },
+    "0000000000000000000000000000000000000005":{
+      "balance":"1",
+      "nonce":"0",
+      "builtin":{
+        "name":"modexp",
+        "activate_at":"0x7530",
+        "pricing":{
+          "modexp":{
+            "divisor":20
+          }
+        }
+      }
+    },
+    "0000000000000000000000000000000000000006":{
+      "balance":"1",
+      "nonce":"0",
+      "builtin":{
+        "name":"alt_bn128_add",
+        "activate_at":"0x7530",
+        "pricing":{
+          "linear":{
+            "base":500,
+            "word":0
+          }
+        }
+      }
+    },
+    "0000000000000000000000000000000000000007":{
+      "balance":"1",
+      "nonce":"0",
+      "builtin":{
+        "name":"alt_bn128_mul",
+        "activate_at":"0x7530",
+        "pricing":{
+          "linear":{
+            "base":40000,
+            "word":0
+          }
+        }
+      }
+    },
+    "0000000000000000000000000000000000000008":{
+      "balance":"1",
+      "nonce":"0",
+      "builtin":{
+        "name":"alt_bn128_pairing",
+        "activate_at":"0x7530",
+        "pricing":{
+          "alt_bn128_pairing":{
+            "base":100000,
+            "pair":80000
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/cmd/puppeth/wizard.go b/cmd/puppeth/wizard.go
index b88a61de7dedb1f088c1abc5d6c52dade03f6d28..83536506c4cb3d02b9301ec79855ea19e6f22dfe 100644
--- a/cmd/puppeth/wizard.go
+++ b/cmd/puppeth/wizard.go
@@ -23,6 +23,7 @@ import (
 	"io/ioutil"
 	"math/big"
 	"net"
+	"net/url"
 	"os"
 	"path/filepath"
 	"sort"
@@ -118,6 +119,47 @@ func (w *wizard) readDefaultString(def string) string {
 	return def
 }
 
+// readDefaultYesNo reads a single line from stdin, trimming if from spaces and
+// interpreting it as a 'yes' or a 'no'. If an empty line is entered, the default
+// value is returned.
+func (w *wizard) readDefaultYesNo(def bool) bool {
+	for {
+		fmt.Printf("> ")
+		text, err := w.in.ReadString('\n')
+		if err != nil {
+			log.Crit("Failed to read user input", "err", err)
+		}
+		if text = strings.ToLower(strings.TrimSpace(text)); text == "" {
+			return def
+		}
+		if text == "y" || text == "yes" {
+			return true
+		}
+		if text == "n" || text == "no" {
+			return false
+		}
+		log.Error("Invalid input, expected 'y', 'yes', 'n', 'no' or empty")
+	}
+}
+
+// readURL reads a single line from stdin, trimming if from spaces and trying to
+// interpret it as a URL (http, https or file).
+func (w *wizard) readURL() *url.URL {
+	for {
+		fmt.Printf("> ")
+		text, err := w.in.ReadString('\n')
+		if err != nil {
+			log.Crit("Failed to read user input", "err", err)
+		}
+		uri, err := url.Parse(strings.TrimSpace(text))
+		if err != nil {
+			log.Error("Invalid input, expected URL", "err", err)
+			continue
+		}
+		return uri
+	}
+}
+
 // readInt reads a single line from stdin, trimming if from spaces, enforcing it
 // to parse into an integer.
 func (w *wizard) readInt() int {
diff --git a/cmd/puppeth/wizard_dashboard.go b/cmd/puppeth/wizard_dashboard.go
index 1a01631ff453e8668e8321902be5733e3f8ca508..8a8370845b69b6c2b9dfb1234df45e8a8be1a5e3 100644
--- a/cmd/puppeth/wizard_dashboard.go
+++ b/cmd/puppeth/wizard_dashboard.go
@@ -137,14 +137,14 @@ func (w *wizard) deployDashboard() {
 	if w.conf.ethstats != "" {
 		fmt.Println()
 		fmt.Println("Include ethstats secret on dashboard (y/n)? (default = yes)")
-		infos.trusted = w.readDefaultString("y") == "y"
+		infos.trusted = w.readDefaultYesNo(true)
 	}
 	// Try to deploy the dashboard container on the host
 	nocache := false
 	if existed {
 		fmt.Println()
 		fmt.Printf("Should the dashboard be built from scratch (y/n)? (default = no)\n")
-		nocache = w.readDefaultString("n") != "n"
+		nocache = w.readDefaultYesNo(false)
 	}
 	if out, err := deployDashboard(client, w.network, &w.conf, infos, nocache); err != nil {
 		log.Error("Failed to deploy dashboard container", "err", err)
diff --git a/cmd/puppeth/wizard_ethstats.go b/cmd/puppeth/wizard_ethstats.go
index fb2529c2673a4975edac42b4fd6311c9f7633cab..58ff3efbe98693acea4d730ff544ad7b676526ec 100644
--- a/cmd/puppeth/wizard_ethstats.go
+++ b/cmd/puppeth/wizard_ethstats.go
@@ -67,11 +67,11 @@ func (w *wizard) deployEthstats() {
 	if existed {
 		fmt.Println()
 		fmt.Printf("Keep existing IP %v blacklist (y/n)? (default = yes)\n", infos.banned)
-		if w.readDefaultString("y") != "y" {
+		if !w.readDefaultYesNo(true) {
 			// The user might want to clear the entire list, although generally probably not
 			fmt.Println()
 			fmt.Printf("Clear out blacklist and start over (y/n)? (default = no)\n")
-			if w.readDefaultString("n") != "n" {
+			if w.readDefaultYesNo(false) {
 				infos.banned = nil
 			}
 			// Offer the user to explicitly add/remove certain IP addresses
@@ -106,7 +106,7 @@ func (w *wizard) deployEthstats() {
 	if existed {
 		fmt.Println()
 		fmt.Printf("Should the ethstats be built from scratch (y/n)? (default = no)\n")
-		nocache = w.readDefaultString("n") != "n"
+		nocache = w.readDefaultYesNo(false)
 	}
 	trusted := make([]string, 0, len(w.servers))
 	for _, client := range w.servers {
diff --git a/cmd/puppeth/wizard_explorer.go b/cmd/puppeth/wizard_explorer.go
index 413511c1c3a1e6accd678b987ef0821a3636fdf8..a128fb9fb52b08285a1aeb2685353ccec8377e17 100644
--- a/cmd/puppeth/wizard_explorer.go
+++ b/cmd/puppeth/wizard_explorer.go
@@ -100,7 +100,7 @@ func (w *wizard) deployExplorer() {
 	if existed {
 		fmt.Println()
 		fmt.Printf("Should the explorer be built from scratch (y/n)? (default = no)\n")
-		nocache = w.readDefaultString("n") != "n"
+		nocache = w.readDefaultYesNo(false)
 	}
 	if out, err := deployExplorer(client, w.network, chain, infos, nocache); err != nil {
 		log.Error("Failed to deploy explorer container", "err", err)
diff --git a/cmd/puppeth/wizard_faucet.go b/cmd/puppeth/wizard_faucet.go
index 6f0840894747c93acfc42b5da5d79bf73bab630a..9068c1d30b5ae093470c08eb1d5052d425842bda 100644
--- a/cmd/puppeth/wizard_faucet.go
+++ b/cmd/puppeth/wizard_faucet.go
@@ -81,7 +81,7 @@ func (w *wizard) deployFaucet() {
 	if infos.captchaToken != "" {
 		fmt.Println()
 		fmt.Println("Reuse previous reCaptcha API authorization (y/n)? (default = yes)")
-		if w.readDefaultString("y") != "y" {
+		if !w.readDefaultYesNo(true) {
 			infos.captchaToken, infos.captchaSecret = "", ""
 		}
 	}
@@ -89,7 +89,7 @@ func (w *wizard) deployFaucet() {
 		// No previous authorization (or old one discarded)
 		fmt.Println()
 		fmt.Println("Enable reCaptcha protection against robots (y/n)? (default = no)")
-		if w.readDefaultString("n") == "n" {
+		if !w.readDefaultYesNo(false) {
 			log.Warn("Users will be able to requests funds via automated scripts")
 		} else {
 			// Captcha protection explicitly requested, read the site and secret keys
@@ -132,7 +132,7 @@ func (w *wizard) deployFaucet() {
 		} else {
 			fmt.Println()
 			fmt.Printf("Reuse previous (%s) funding account (y/n)? (default = yes)\n", key.Address.Hex())
-			if w.readDefaultString("y") != "y" {
+			if !w.readDefaultYesNo(true) {
 				infos.node.keyJSON, infos.node.keyPass = "", ""
 			}
 		}
@@ -166,7 +166,7 @@ func (w *wizard) deployFaucet() {
 	if existed {
 		fmt.Println()
 		fmt.Printf("Should the faucet be built from scratch (y/n)? (default = no)\n")
-		nocache = w.readDefaultString("n") != "n"
+		nocache = w.readDefaultYesNo(false)
 	}
 	if out, err := deployFaucet(client, w.network, w.conf.bootnodes, infos, nocache); err != nil {
 		log.Error("Failed to deploy faucet container", "err", err)
diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go
index 6c4cd571fbaa31d0f9b02d562cfcbb7882235487..95da5bd4f3c925b43b8c41b49edf43b22e7e82a0 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: &params.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
@@ -114,9 +119,13 @@ func (w *wizard) makeGenesis() {
 		}
 		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()
+	fmt.Println("Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)")
+	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)}
+		}
 	}
 	// Query the user for some custom extras
 	fmt.Println()
@@ -130,53 +139,130 @@ 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() {
 	// 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(" 2. Export genesis configurations")
 	fmt.Println(" 3. Remove genesis configuration")
 
 	choice := w.read()
-	switch {
-	case choice == "1":
+	switch choice {
+	case "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)
+		fmt.Printf("Which block should EIP150 (Tangerine Whistle) 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)
+		fmt.Printf("Which block should EIP155 (Spurious Dragon) 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)
+		fmt.Printf("Which block should EIP158/161 (also Spurious Dragon) 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)
 
+		fmt.Println()
+		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, "", "  ")
 		fmt.Printf("Chain configuration updated:\n\n%s\n", out)
 
-	case choice == "2":
+	case "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)
+		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, "", "  ")
-		if err := ioutil.WriteFile(w.readDefaultString(fmt.Sprintf("%s.json", w.network)), out, 0644); err != nil {
+
+		// 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("Exported existing genesis block")
+		log.Info("Saved native genesis chain spec", "path", gethJson)
 
-	case choice == "3":
+		// 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
 		if len(w.conf.servers()) > 0 {
 			log.Error("Genesis reset requires all services and servers torn down")
@@ -186,8 +272,20 @@ func (w *wizard) manageGenesis() {
 
 		w.conf.Genesis = nil
 		w.conf.flush()
-
 	default:
 		log.Error("That's not something I can do")
+		return
+	}
+}
+
+// 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))
+
+	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
 	}
+	log.Info("Saved genesis chain spec", "client", client, "path", path)
 }
diff --git a/cmd/puppeth/wizard_intro.go b/cmd/puppeth/wizard_intro.go
index 3db9a1087e455c891e74d3a159e9fd11e611e4f0..75fb04b76f70b99fda903bfa9ece687b25e0ba60 100644
--- a/cmd/puppeth/wizard_intro.go
+++ b/cmd/puppeth/wizard_intro.go
@@ -131,7 +131,20 @@ func (w *wizard) run() {
 
 		case choice == "2":
 			if w.conf.Genesis == nil {
-				w.makeGenesis()
+				fmt.Println()
+				fmt.Println("What would you like to do? (default = create)")
+				fmt.Println(" 1. Create new genesis from scratch")
+				fmt.Println(" 2. Import already existing genesis")
+
+				choice := w.read()
+				switch {
+				case choice == "" || choice == "1":
+					w.makeGenesis()
+				case choice == "2":
+					w.importGenesis()
+				default:
+					log.Error("That's not something I can do")
+				}
 			} else {
 				w.manageGenesis()
 			}
@@ -149,7 +162,6 @@ func (w *wizard) run() {
 			} else {
 				w.manageComponents()
 			}
-
 		default:
 			log.Error("That's not something I can do")
 		}
diff --git a/cmd/puppeth/wizard_nginx.go b/cmd/puppeth/wizard_nginx.go
index 4eeae93a0b26ba8c5aec0f3ec624ec006fefb802..8397b7fd57ff3edc3b142627ef402e5201c40bcc 100644
--- a/cmd/puppeth/wizard_nginx.go
+++ b/cmd/puppeth/wizard_nginx.go
@@ -41,12 +41,12 @@ func (w *wizard) ensureVirtualHost(client *sshClient, port int, def string) (str
 	// Reverse proxy is not running, offer to deploy a new one
 	fmt.Println()
 	fmt.Println("Allow sharing the port with other services (y/n)? (default = yes)")
-	if w.readDefaultString("y") == "y" {
+	if w.readDefaultYesNo(true) {
 		nocache := false
 		if proxy != nil {
 			fmt.Println()
 			fmt.Printf("Should the reverse-proxy be rebuilt from scratch (y/n)? (default = no)\n")
-			nocache = w.readDefaultString("n") != "n"
+			nocache = w.readDefaultYesNo(false)
 		}
 		if out, err := deployNginx(client, w.network, port, nocache); err != nil {
 			log.Error("Failed to deploy reverse-proxy", "err", err)
diff --git a/cmd/puppeth/wizard_node.go b/cmd/puppeth/wizard_node.go
index 49b10a023a44005ba5dce0912dea094e991ec231..e37297f6d629329b6bc8269347d20ffc9a9dccc8 100644
--- a/cmd/puppeth/wizard_node.go
+++ b/cmd/puppeth/wizard_node.go
@@ -126,7 +126,7 @@ func (w *wizard) deployNode(boot bool) {
 				} else {
 					fmt.Println()
 					fmt.Printf("Reuse previous (%s) signing account (y/n)? (default = yes)\n", key.Address.Hex())
-					if w.readDefaultString("y") != "y" {
+					if !w.readDefaultYesNo(true) {
 						infos.keyJSON, infos.keyPass = "", ""
 					}
 				}
@@ -165,7 +165,7 @@ func (w *wizard) deployNode(boot bool) {
 	if existed {
 		fmt.Println()
 		fmt.Printf("Should the node be built from scratch (y/n)? (default = no)\n")
-		nocache = w.readDefaultString("n") != "n"
+		nocache = w.readDefaultYesNo(false)
 	}
 	if out, err := deployNode(client, w.network, w.conf.bootnodes, infos, nocache); err != nil {
 		log.Error("Failed to deploy Ethereum node container", "err", err)
diff --git a/cmd/puppeth/wizard_wallet.go b/cmd/puppeth/wizard_wallet.go
index 7624d11e20e2c68e5869050397a60b320de65644..ca1ea5bd25915cd5bf60af8ee080c70e596057a2 100644
--- a/cmd/puppeth/wizard_wallet.go
+++ b/cmd/puppeth/wizard_wallet.go
@@ -96,7 +96,7 @@ func (w *wizard) deployWallet() {
 	if existed {
 		fmt.Println()
 		fmt.Printf("Should the wallet be built from scratch (y/n)? (default = no)\n")
-		nocache = w.readDefaultString("n") != "n"
+		nocache = w.readDefaultYesNo(false)
 	}
 	if out, err := deployWallet(client, w.network, w.conf.bootnodes, infos, nocache); err != nil {
 		log.Error("Failed to deploy wallet container", "err", err)