github.com/insight-chain/inb-go@v1.1.3-0.20191221022159-da049980ae38/cmd/puppeth/genesis.go (about)

     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  
    17  package main
    18  
    19  import (
    20  	"encoding/binary"
    21  	"errors"
    22  	"github.com/insight-chain/inb-go/core/types"
    23  	"math"
    24  	"math/big"
    25  	"strings"
    26  
    27  	"github.com/insight-chain/inb-go/common"
    28  	"github.com/insight-chain/inb-go/common/hexutil"
    29  	math2 "github.com/insight-chain/inb-go/common/math"
    30  	"github.com/insight-chain/inb-go/consensus/ethash"
    31  	"github.com/insight-chain/inb-go/core"
    32  	"github.com/insight-chain/inb-go/params"
    33  )
    34  
    35  // alethGenesisSpec represents the genesis specification format used by the
    36  // C++ Ethereum implementation.
    37  type alethGenesisSpec struct {
    38  	SealEngine string `json:"sealEngine"`
    39  	Params     struct {
    40  		AccountStartNonce       math2.HexOrDecimal64   `json:"accountStartNonce"`
    41  		MaximumExtraDataSize    hexutil.Uint64         `json:"maximumExtraDataSize"`
    42  		HomesteadForkBlock      hexutil.Uint64         `json:"homesteadForkBlock"`
    43  		DaoHardforkBlock        math2.HexOrDecimal64   `json:"daoHardforkBlock"`
    44  		EIP150ForkBlock         hexutil.Uint64         `json:"EIP150ForkBlock"`
    45  		EIP158ForkBlock         hexutil.Uint64         `json:"EIP158ForkBlock"`
    46  		ByzantiumForkBlock      hexutil.Uint64         `json:"byzantiumForkBlock"`
    47  		ConstantinopleForkBlock hexutil.Uint64         `json:"constantinopleForkBlock"`
    48  		MinGasLimit             hexutil.Uint64         `json:"minGasLimit"`
    49  		MaxGasLimit             hexutil.Uint64         `json:"maxGasLimit"`
    50  		TieBreakingGas          bool                   `json:"tieBreakingGas"`
    51  		GasLimitBoundDivisor    math2.HexOrDecimal64   `json:"gasLimitBoundDivisor"`
    52  		MinimumDifficulty       *hexutil.Big           `json:"minimumDifficulty"`
    53  		DifficultyBoundDivisor  *math2.HexOrDecimal256 `json:"difficultyBoundDivisor"`
    54  		DurationLimit           *math2.HexOrDecimal256 `json:"durationLimit"`
    55  		BlockReward             *hexutil.Big           `json:"blockReward"`
    56  		NetworkID               hexutil.Uint64         `json:"networkID"`
    57  		ChainID                 hexutil.Uint64         `json:"chainID"`
    58  		AllowFutureBlocks       bool                   `json:"allowFutureBlocks"`
    59  	} `json:"params"`
    60  
    61  	Genesis struct {
    62  		Nonce            hexutil.Bytes          `json:"nonce"`
    63  		Difficulty       *hexutil.Big           `json:"difficulty"`
    64  		MixHash          common.Hash            `json:"mixHash"`
    65  		Author           common.Address         `json:"author"`
    66  		Timestamp        hexutil.Uint64         `json:"timestamp"`
    67  		ParentHash       common.Hash            `json:"parentHash"`
    68  		ExtraData        hexutil.Bytes          `json:"extraData"`
    69  		GasLimit         hexutil.Uint64         `json:"gasLimit"`
    70  		SpecialConsensus types.SpecialConsensus `json:"specialConsensus" gencodec:"required"` //2019.7.23 inb by ghy
    71  	} `json:"genesis"`
    72  
    73  	Accounts map[common.UnprefixedAddress]*alethGenesisSpecAccount `json:"accounts"`
    74  }
    75  
    76  // alethGenesisSpecAccount is the prefunded genesis account and/or precompiled
    77  // contract definition.
    78  type alethGenesisSpecAccount struct {
    79  	Balance     *math2.HexOrDecimal256   `json:"balance"`
    80  	Nonce       uint64                   `json:"nonce,omitempty"`
    81  	Precompiled *alethGenesisSpecBuiltin `json:"precompiled,omitempty"`
    82  }
    83  
    84  // alethGenesisSpecBuiltin is the precompiled contract definition.
    85  type alethGenesisSpecBuiltin struct {
    86  	Name          string                         `json:"name,omitempty"`
    87  	StartingBlock hexutil.Uint64                 `json:"startingBlock,omitempty"`
    88  	Linear        *alethGenesisSpecLinearPricing `json:"linear,omitempty"`
    89  }
    90  
    91  type alethGenesisSpecLinearPricing struct {
    92  	Base uint64 `json:"base"`
    93  	Word uint64 `json:"word"`
    94  }
    95  
    96  // newAlethGenesisSpec converts a go-ethereum genesis block into a Aleth-specific
    97  // chain specification format.
    98  func newAlethGenesisSpec(network string, genesis *core.Genesis) (*alethGenesisSpec, error) {
    99  	// Only ethash is currently supported between go-ethereum and aleth
   100  	if genesis.Config.Ethash == nil {
   101  		return nil, errors.New("unsupported consensus engine")
   102  	}
   103  	// Reconstruct the chain spec in Aleth format
   104  	spec := &alethGenesisSpec{
   105  		SealEngine: "Ethash",
   106  	}
   107  	// Some defaults
   108  	spec.Params.AccountStartNonce = 0
   109  	spec.Params.TieBreakingGas = false
   110  	spec.Params.AllowFutureBlocks = false
   111  	spec.Params.DaoHardforkBlock = 0
   112  
   113  	spec.Params.HomesteadForkBlock = (hexutil.Uint64)(genesis.Config.HomesteadBlock.Uint64())
   114  	spec.Params.EIP150ForkBlock = (hexutil.Uint64)(genesis.Config.EIP150Block.Uint64())
   115  	spec.Params.EIP158ForkBlock = (hexutil.Uint64)(genesis.Config.EIP158Block.Uint64())
   116  
   117  	// Byzantium
   118  	if num := genesis.Config.ByzantiumBlock; num != nil {
   119  		spec.setByzantium(num)
   120  	}
   121  	// Constantinople
   122  	if num := genesis.Config.ConstantinopleBlock; num != nil {
   123  		spec.setConstantinople(num)
   124  	}
   125  
   126  	spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
   127  	spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
   128  	spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
   129  	spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
   130  	spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxInt64)
   131  	spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
   132  	spec.Params.DifficultyBoundDivisor = (*math2.HexOrDecimal256)(params.DifficultyBoundDivisor)
   133  	spec.Params.GasLimitBoundDivisor = (math2.HexOrDecimal64)(params.GasLimitBoundDivisor)
   134  	spec.Params.DurationLimit = (*math2.HexOrDecimal256)(params.DurationLimit)
   135  	spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
   136  
   137  	spec.Genesis.Nonce = (hexutil.Bytes)(make([]byte, 8))
   138  	binary.LittleEndian.PutUint64(spec.Genesis.Nonce[:], genesis.Nonce)
   139  
   140  	spec.Genesis.MixHash = genesis.Mixhash
   141  	spec.Genesis.Difficulty = (*hexutil.Big)(genesis.Difficulty)
   142  	spec.Genesis.Author = genesis.Coinbase
   143  	spec.Genesis.Timestamp = (hexutil.Uint64)(genesis.Timestamp)
   144  	spec.Genesis.ParentHash = genesis.ParentHash
   145  	spec.Genesis.ExtraData = (hexutil.Bytes)(genesis.ExtraData)
   146  	spec.Genesis.GasLimit = (hexutil.Uint64)(genesis.ResUsed)
   147  	spec.Genesis.SpecialConsensus = genesis.SpecialConsensus //2019.7.23 inb by ghy
   148  
   149  	for address, account := range genesis.Alloc {
   150  		spec.setAccount(address, account)
   151  	}
   152  
   153  	spec.setPrecompile(1, &alethGenesisSpecBuiltin{Name: "ecrecover",
   154  		Linear: &alethGenesisSpecLinearPricing{Base: 3000}})
   155  	spec.setPrecompile(2, &alethGenesisSpecBuiltin{Name: "sha256",
   156  		Linear: &alethGenesisSpecLinearPricing{Base: 60, Word: 12}})
   157  	spec.setPrecompile(3, &alethGenesisSpecBuiltin{Name: "ripemd160",
   158  		Linear: &alethGenesisSpecLinearPricing{Base: 600, Word: 120}})
   159  	spec.setPrecompile(4, &alethGenesisSpecBuiltin{Name: "identity",
   160  		Linear: &alethGenesisSpecLinearPricing{Base: 15, Word: 3}})
   161  	if genesis.Config.ByzantiumBlock != nil {
   162  		spec.setPrecompile(5, &alethGenesisSpecBuiltin{Name: "modexp",
   163  			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64())})
   164  		spec.setPrecompile(6, &alethGenesisSpecBuiltin{Name: "alt_bn128_G1_add",
   165  			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()),
   166  			Linear:        &alethGenesisSpecLinearPricing{Base: 500}})
   167  		spec.setPrecompile(7, &alethGenesisSpecBuiltin{Name: "alt_bn128_G1_mul",
   168  			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()),
   169  			Linear:        &alethGenesisSpecLinearPricing{Base: 40000}})
   170  		spec.setPrecompile(8, &alethGenesisSpecBuiltin{Name: "alt_bn128_pairing_product",
   171  			StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64())})
   172  	}
   173  	return spec, nil
   174  }
   175  
   176  func (spec *alethGenesisSpec) setPrecompile(address byte, data *alethGenesisSpecBuiltin) {
   177  	if spec.Accounts == nil {
   178  		spec.Accounts = make(map[common.UnprefixedAddress]*alethGenesisSpecAccount)
   179  	}
   180  	spec.Accounts[common.UnprefixedAddress(common.BytesToAddress([]byte{address}))].Precompiled = data
   181  }
   182  
   183  func (spec *alethGenesisSpec) setAccount(address common.Address, account core.GenesisAccount) {
   184  	if spec.Accounts == nil {
   185  		spec.Accounts = make(map[common.UnprefixedAddress]*alethGenesisSpecAccount)
   186  	}
   187  
   188  	a, exist := spec.Accounts[common.UnprefixedAddress(address)]
   189  	if !exist {
   190  		a = &alethGenesisSpecAccount{}
   191  		spec.Accounts[common.UnprefixedAddress(address)] = a
   192  	}
   193  	a.Balance = (*math2.HexOrDecimal256)(account.Balance)
   194  	a.Nonce = account.Nonce
   195  
   196  }
   197  
   198  func (spec *alethGenesisSpec) setByzantium(num *big.Int) {
   199  	spec.Params.ByzantiumForkBlock = hexutil.Uint64(num.Uint64())
   200  }
   201  
   202  func (spec *alethGenesisSpec) setConstantinople(num *big.Int) {
   203  	spec.Params.ConstantinopleForkBlock = hexutil.Uint64(num.Uint64())
   204  }
   205  
   206  // parityChainSpec is the chain specification format used by Parity.
   207  type parityChainSpec struct {
   208  	Name    string `json:"name"`
   209  	Datadir string `json:"dataDir"`
   210  	Engine  struct {
   211  		Ethash struct {
   212  			Params struct {
   213  				MinimumDifficulty      *hexutil.Big      `json:"minimumDifficulty"`
   214  				DifficultyBoundDivisor *hexutil.Big      `json:"difficultyBoundDivisor"`
   215  				DurationLimit          *hexutil.Big      `json:"durationLimit"`
   216  				BlockReward            map[string]string `json:"blockReward"`
   217  				DifficultyBombDelays   map[string]string `json:"difficultyBombDelays"`
   218  				HomesteadTransition    hexutil.Uint64    `json:"homesteadTransition"`
   219  				EIP100bTransition      hexutil.Uint64    `json:"eip100bTransition"`
   220  			} `json:"params"`
   221  		} `json:"Ethash"`
   222  	} `json:"engine"`
   223  
   224  	Params struct {
   225  		AccountStartNonce     hexutil.Uint64       `json:"accountStartNonce"`
   226  		MaximumExtraDataSize  hexutil.Uint64       `json:"maximumExtraDataSize"`
   227  		MinGasLimit           hexutil.Uint64       `json:"minGasLimit"`
   228  		GasLimitBoundDivisor  math2.HexOrDecimal64 `json:"gasLimitBoundDivisor"`
   229  		NetworkID             hexutil.Uint64       `json:"networkID"`
   230  		ChainID               hexutil.Uint64       `json:"chainID"`
   231  		MaxCodeSize           hexutil.Uint64       `json:"maxCodeSize"`
   232  		MaxCodeSizeTransition hexutil.Uint64       `json:"maxCodeSizeTransition"`
   233  		EIP98Transition       hexutil.Uint64       `json:"eip98Transition"`
   234  		EIP150Transition      hexutil.Uint64       `json:"eip150Transition"`
   235  		EIP160Transition      hexutil.Uint64       `json:"eip160Transition"`
   236  		EIP161abcTransition   hexutil.Uint64       `json:"eip161abcTransition"`
   237  		EIP161dTransition     hexutil.Uint64       `json:"eip161dTransition"`
   238  		EIP155Transition      hexutil.Uint64       `json:"eip155Transition"`
   239  		EIP140Transition      hexutil.Uint64       `json:"eip140Transition"`
   240  		EIP211Transition      hexutil.Uint64       `json:"eip211Transition"`
   241  		EIP214Transition      hexutil.Uint64       `json:"eip214Transition"`
   242  		EIP658Transition      hexutil.Uint64       `json:"eip658Transition"`
   243  		EIP145Transition      hexutil.Uint64       `json:"eip145Transition"`
   244  		EIP1014Transition     hexutil.Uint64       `json:"eip1014Transition"`
   245  		EIP1052Transition     hexutil.Uint64       `json:"eip1052Transition"`
   246  		EIP1283Transition     hexutil.Uint64       `json:"eip1283Transition"`
   247  	} `json:"params"`
   248  
   249  	Genesis struct {
   250  		Seal struct {
   251  			Ethereum struct {
   252  				Nonce   hexutil.Bytes `json:"nonce"`
   253  				MixHash hexutil.Bytes `json:"mixHash"`
   254  			} `json:"ethereum"`
   255  		} `json:"seal"`
   256  
   257  		Difficulty       *hexutil.Big           `json:"difficulty"`
   258  		Author           common.Address         `json:"author"`
   259  		Timestamp        hexutil.Uint64         `json:"timestamp"`
   260  		ParentHash       common.Hash            `json:"parentHash"`
   261  		ExtraData        hexutil.Bytes          `json:"extraData"`
   262  		GasLimit         hexutil.Uint64         `json:"gasLimit"`
   263  		SpecialConsensus types.SpecialConsensus `json:"specialConsensus" gencodec:"required"`
   264  	} `json:"genesis"`
   265  
   266  	Nodes    []string                                             `json:"nodes"`
   267  	Accounts map[common.UnprefixedAddress]*parityChainSpecAccount `json:"accounts"`
   268  }
   269  
   270  // parityChainSpecAccount is the prefunded genesis account and/or precompiled
   271  // contract definition.
   272  type parityChainSpecAccount struct {
   273  	Balance math2.HexOrDecimal256   `json:"balance"`
   274  	Nonce   math2.HexOrDecimal64    `json:"nonce,omitempty"`
   275  	Builtin *parityChainSpecBuiltin `json:"builtin,omitempty"`
   276  }
   277  
   278  // parityChainSpecBuiltin is the precompiled contract definition.
   279  type parityChainSpecBuiltin struct {
   280  	Name       string                  `json:"name,omitempty"`
   281  	ActivateAt math2.HexOrDecimal64    `json:"activate_at,omitempty"`
   282  	Pricing    *parityChainSpecPricing `json:"pricing,omitempty"`
   283  }
   284  
   285  // parityChainSpecPricing represents the different pricing models that builtin
   286  // contracts might advertise using.
   287  type parityChainSpecPricing struct {
   288  	Linear       *parityChainSpecLinearPricing       `json:"linear,omitempty"`
   289  	ModExp       *parityChainSpecModExpPricing       `json:"modexp,omitempty"`
   290  	AltBnPairing *parityChainSpecAltBnPairingPricing `json:"alt_bn128_pairing,omitempty"`
   291  }
   292  
   293  type parityChainSpecLinearPricing struct {
   294  	Base uint64 `json:"base"`
   295  	Word uint64 `json:"word"`
   296  }
   297  
   298  type parityChainSpecModExpPricing struct {
   299  	Divisor uint64 `json:"divisor"`
   300  }
   301  
   302  type parityChainSpecAltBnPairingPricing struct {
   303  	Base uint64 `json:"base"`
   304  	Pair uint64 `json:"pair"`
   305  }
   306  
   307  // newParityChainSpec converts a go-ethereum genesis block into a Parity specific
   308  // chain specification format.
   309  func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []string) (*parityChainSpec, error) {
   310  	// Only ethash is currently supported between go-ethereum and Parity
   311  	if genesis.Config.Ethash == nil {
   312  		return nil, errors.New("unsupported consensus engine")
   313  	}
   314  	// Reconstruct the chain spec in Parity's format
   315  	spec := &parityChainSpec{
   316  		Name:    network,
   317  		Nodes:   bootnodes,
   318  		Datadir: strings.ToLower(network),
   319  	}
   320  	spec.Engine.Ethash.Params.BlockReward = make(map[string]string)
   321  	spec.Engine.Ethash.Params.DifficultyBombDelays = make(map[string]string)
   322  	// Frontier
   323  	spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
   324  	spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
   325  	spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
   326  	spec.Engine.Ethash.Params.BlockReward["0x0"] = hexutil.EncodeBig(ethash.FrontierBlockReward)
   327  
   328  	// Homestead
   329  	spec.Engine.Ethash.Params.HomesteadTransition = hexutil.Uint64(genesis.Config.HomesteadBlock.Uint64())
   330  
   331  	// Tangerine Whistle : 150
   332  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-608.md
   333  	spec.Params.EIP150Transition = hexutil.Uint64(genesis.Config.EIP150Block.Uint64())
   334  
   335  	// Spurious Dragon: 155, 160, 161, 170
   336  	// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-607.md
   337  	spec.Params.EIP155Transition = hexutil.Uint64(genesis.Config.EIP155Block.Uint64())
   338  	spec.Params.EIP160Transition = hexutil.Uint64(genesis.Config.EIP155Block.Uint64())
   339  	spec.Params.EIP161abcTransition = hexutil.Uint64(genesis.Config.EIP158Block.Uint64())
   340  	spec.Params.EIP161dTransition = hexutil.Uint64(genesis.Config.EIP158Block.Uint64())
   341  
   342  	// Byzantium
   343  	if num := genesis.Config.ByzantiumBlock; num != nil {
   344  		spec.setByzantium(num)
   345  	}
   346  	// Constantinople
   347  	if num := genesis.Config.ConstantinopleBlock; num != nil {
   348  		spec.setConstantinople(num)
   349  	}
   350  	spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
   351  	spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
   352  	spec.Params.GasLimitBoundDivisor = (math2.HexOrDecimal64)(params.GasLimitBoundDivisor)
   353  	spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
   354  	spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64())
   355  	spec.Params.MaxCodeSize = params.MaxCodeSize
   356  	// ginb has it set from zero
   357  	spec.Params.MaxCodeSizeTransition = 0
   358  
   359  	// Disable this one
   360  	spec.Params.EIP98Transition = math.MaxInt64
   361  
   362  	spec.Genesis.Seal.Ethereum.Nonce = (hexutil.Bytes)(make([]byte, 8))
   363  	binary.LittleEndian.PutUint64(spec.Genesis.Seal.Ethereum.Nonce[:], genesis.Nonce)
   364  
   365  	spec.Genesis.Seal.Ethereum.MixHash = (hexutil.Bytes)(genesis.Mixhash[:])
   366  	spec.Genesis.Difficulty = (*hexutil.Big)(genesis.Difficulty)
   367  	spec.Genesis.Author = genesis.Coinbase
   368  	spec.Genesis.Timestamp = (hexutil.Uint64)(genesis.Timestamp)
   369  	spec.Genesis.ParentHash = genesis.ParentHash
   370  	spec.Genesis.ExtraData = (hexutil.Bytes)(genesis.ExtraData)
   371  	spec.Genesis.GasLimit = (hexutil.Uint64)(genesis.ResLimit)
   372  	spec.Genesis.SpecialConsensus = genesis.SpecialConsensus //2019.7.23 inb by ghy
   373  
   374  	spec.Accounts = make(map[common.UnprefixedAddress]*parityChainSpecAccount)
   375  	for address, account := range genesis.Alloc {
   376  		bal := math2.HexOrDecimal256(*account.Balance)
   377  
   378  		spec.Accounts[common.UnprefixedAddress(address)] = &parityChainSpecAccount{
   379  			Balance: bal,
   380  			Nonce:   math2.HexOrDecimal64(account.Nonce),
   381  		}
   382  	}
   383  	spec.setPrecompile(1, &parityChainSpecBuiltin{Name: "ecrecover",
   384  		Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 3000}}})
   385  
   386  	spec.setPrecompile(2, &parityChainSpecBuiltin{
   387  		Name: "sha256", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 60, Word: 12}},
   388  	})
   389  	spec.setPrecompile(3, &parityChainSpecBuiltin{
   390  		Name: "ripemd160", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 600, Word: 120}},
   391  	})
   392  	spec.setPrecompile(4, &parityChainSpecBuiltin{
   393  		Name: "identity", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 15, Word: 3}},
   394  	})
   395  	if genesis.Config.ByzantiumBlock != nil {
   396  		blnum := math2.HexOrDecimal64(genesis.Config.ByzantiumBlock.Uint64())
   397  		spec.setPrecompile(5, &parityChainSpecBuiltin{
   398  			Name: "modexp", ActivateAt: blnum, Pricing: &parityChainSpecPricing{ModExp: &parityChainSpecModExpPricing{Divisor: 20}},
   399  		})
   400  		spec.setPrecompile(6, &parityChainSpecBuiltin{
   401  			Name: "alt_bn128_add", ActivateAt: blnum, Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 500}},
   402  		})
   403  		spec.setPrecompile(7, &parityChainSpecBuiltin{
   404  			Name: "alt_bn128_mul", ActivateAt: blnum, Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 40000}},
   405  		})
   406  		spec.setPrecompile(8, &parityChainSpecBuiltin{
   407  			Name: "alt_bn128_pairing", ActivateAt: blnum, Pricing: &parityChainSpecPricing{AltBnPairing: &parityChainSpecAltBnPairingPricing{Base: 100000, Pair: 80000}},
   408  		})
   409  	}
   410  	return spec, nil
   411  }
   412  
   413  func (spec *parityChainSpec) setPrecompile(address byte, data *parityChainSpecBuiltin) {
   414  	if spec.Accounts == nil {
   415  		spec.Accounts = make(map[common.UnprefixedAddress]*parityChainSpecAccount)
   416  	}
   417  	a := common.UnprefixedAddress(common.BytesToAddress([]byte{address}))
   418  	if _, exist := spec.Accounts[a]; !exist {
   419  		spec.Accounts[a] = &parityChainSpecAccount{}
   420  	}
   421  	spec.Accounts[a].Builtin = data
   422  }
   423  
   424  func (spec *parityChainSpec) setByzantium(num *big.Int) {
   425  	spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.ByzantiumBlockReward)
   426  	spec.Engine.Ethash.Params.DifficultyBombDelays[hexutil.EncodeBig(num)] = hexutil.EncodeUint64(3000000)
   427  	n := hexutil.Uint64(num.Uint64())
   428  	spec.Engine.Ethash.Params.EIP100bTransition = n
   429  	spec.Params.EIP140Transition = n
   430  	spec.Params.EIP211Transition = n
   431  	spec.Params.EIP214Transition = n
   432  	spec.Params.EIP658Transition = n
   433  }
   434  
   435  func (spec *parityChainSpec) setConstantinople(num *big.Int) {
   436  	spec.Engine.Ethash.Params.BlockReward[hexutil.EncodeBig(num)] = hexutil.EncodeBig(ethash.ConstantinopleBlockReward)
   437  	spec.Engine.Ethash.Params.DifficultyBombDelays[hexutil.EncodeBig(num)] = hexutil.EncodeUint64(2000000)
   438  	n := hexutil.Uint64(num.Uint64())
   439  	spec.Params.EIP145Transition = n
   440  	spec.Params.EIP1014Transition = n
   441  	spec.Params.EIP1052Transition = n
   442  	spec.Params.EIP1283Transition = n
   443  }
   444  
   445  // pyEthereumGenesisSpec represents the genesis specification format used by the
   446  // Python Ethereum implementation.
   447  type pyEthereumGenesisSpec struct {
   448  	Nonce      hexutil.Bytes     `json:"nonce"`
   449  	Timestamp  hexutil.Uint64    `json:"timestamp"`
   450  	ExtraData  hexutil.Bytes     `json:"extraData"`
   451  	GasLimit   hexutil.Uint64    `json:"gasLimit"`
   452  	Difficulty *hexutil.Big      `json:"difficulty"`
   453  	Mixhash    common.Hash       `json:"mixhash"`
   454  	Coinbase   common.Address    `json:"coinbase"`
   455  	Alloc      core.GenesisAlloc `json:"alloc"`
   456  	ParentHash common.Hash       `json:"parentHash"`
   457  }
   458  
   459  // newPyEthereumGenesisSpec converts a go-ethereum genesis block into a Parity specific
   460  // chain specification format.
   461  func newPyEthereumGenesisSpec(network string, genesis *core.Genesis) (*pyEthereumGenesisSpec, error) {
   462  	// Only ethash is currently supported between go-ethereum and pyethereum
   463  	if genesis.Config.Ethash == nil {
   464  		return nil, errors.New("unsupported consensus engine")
   465  	}
   466  	spec := &pyEthereumGenesisSpec{
   467  		Timestamp:  (hexutil.Uint64)(genesis.Timestamp),
   468  		ExtraData:  genesis.ExtraData,
   469  		GasLimit:   (hexutil.Uint64)(genesis.ResLimit),
   470  		Difficulty: (*hexutil.Big)(genesis.Difficulty),
   471  		Mixhash:    genesis.Mixhash,
   472  		Coinbase:   genesis.Coinbase,
   473  		Alloc:      genesis.Alloc,
   474  		ParentHash: genesis.ParentHash,
   475  	}
   476  	spec.Nonce = (hexutil.Bytes)(make([]byte, 8))
   477  	binary.LittleEndian.PutUint64(spec.Nonce[:], genesis.Nonce)
   478  
   479  	return spec, nil
   480  }