github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/cmd/puppeth/genesis.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package main 13 14 import ( 15 "encoding/binary" 16 "errors" 17 "math" 18 19 "github.com/Sberex/go-sberex/common" 20 "github.com/Sberex/go-sberex/common/hexutil" 21 "github.com/Sberex/go-sberex/consensus/ethash" 22 "github.com/Sberex/go-sberex/core" 23 "github.com/Sberex/go-sberex/params" 24 ) 25 26 // cppSberexGenesisSpec represents the genesis specification format used by the 27 // C++ Sberex implementation. 28 type cppSberexGenesisSpec struct { 29 SealEngine string `json:"sealEngine"` 30 Params struct { 31 AccountStartNonce hexutil.Uint64 `json:"accountStartNonce"` 32 HomesteadForkBlock hexutil.Uint64 `json:"homesteadForkBlock"` 33 EIP150ForkBlock hexutil.Uint64 `json:"EIP150ForkBlock"` 34 EIP158ForkBlock hexutil.Uint64 `json:"EIP158ForkBlock"` 35 ByzantiumForkBlock hexutil.Uint64 `json:"byzantiumForkBlock"` 36 ConstantinopleForkBlock hexutil.Uint64 `json:"constantinopleForkBlock"` 37 NetworkID hexutil.Uint64 `json:"networkID"` 38 ChainID hexutil.Uint64 `json:"chainID"` 39 MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"` 40 MinGasLimit hexutil.Uint64 `json:"minGasLimit"` 41 MaxGasLimit hexutil.Uint64 `json:"maxGasLimit"` 42 GasLimitBoundDivisor hexutil.Uint64 `json:"gasLimitBoundDivisor"` 43 MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"` 44 DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"` 45 DurationLimit *hexutil.Big `json:"durationLimit"` 46 BlockReward *hexutil.Big `json:"blockReward"` 47 } `json:"params"` 48 49 Genesis struct { 50 Nonce hexutil.Bytes `json:"nonce"` 51 Difficulty *hexutil.Big `json:"difficulty"` 52 MixHash common.Hash `json:"mixHash"` 53 Author common.Address `json:"author"` 54 Timestamp hexutil.Uint64 `json:"timestamp"` 55 ParentHash common.Hash `json:"parentHash"` 56 ExtraData hexutil.Bytes `json:"extraData"` 57 GasLimit hexutil.Uint64 `json:"gasLimit"` 58 } `json:"genesis"` 59 60 Accounts map[common.Address]*cppSberexGenesisSpecAccount `json:"accounts"` 61 } 62 63 // cppSberexGenesisSpecAccount is the prefunded genesis account and/or precompiled 64 // contract definition. 65 type cppSberexGenesisSpecAccount struct { 66 Balance *hexutil.Big `json:"balance"` 67 Nonce uint64 `json:"nonce,omitempty"` 68 Precompiled *cppSberexGenesisSpecBuiltin `json:"precompiled,omitempty"` 69 } 70 71 // cppSberexGenesisSpecBuiltin is the precompiled contract definition. 72 type cppSberexGenesisSpecBuiltin struct { 73 Name string `json:"name,omitempty"` 74 StartingBlock hexutil.Uint64 `json:"startingBlock,omitempty"` 75 Linear *cppSberexGenesisSpecLinearPricing `json:"linear,omitempty"` 76 } 77 78 type cppSberexGenesisSpecLinearPricing struct { 79 Base uint64 `json:"base"` 80 Word uint64 `json:"word"` 81 } 82 83 // newCppSberexGenesisSpec converts a go-sberex genesis block into a Parity specific 84 // chain specification format. 85 func newCppSberexGenesisSpec(network string, genesis *core.Genesis) (*cppSberexGenesisSpec, error) { 86 // Only ethash is currently supported between go-sberex and cpp-sberex 87 if genesis.Config.Ethash == nil { 88 return nil, errors.New("unsupported consensus engine") 89 } 90 // Reconstruct the chain spec in Parity's format 91 spec := &cppSberexGenesisSpec{ 92 SealEngine: "Ethash", 93 } 94 spec.Params.AccountStartNonce = 0 95 spec.Params.HomesteadForkBlock = (hexutil.Uint64)(genesis.Config.HomesteadBlock.Uint64()) 96 spec.Params.EIP150ForkBlock = (hexutil.Uint64)(genesis.Config.EIP150Block.Uint64()) 97 spec.Params.EIP158ForkBlock = (hexutil.Uint64)(genesis.Config.EIP158Block.Uint64()) 98 spec.Params.ByzantiumForkBlock = (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()) 99 spec.Params.ConstantinopleForkBlock = (hexutil.Uint64)(math.MaxUint64) 100 101 spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) 102 spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) 103 104 spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize) 105 spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit) 106 spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxUint64) 107 spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty) 108 spec.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor) 109 spec.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor) 110 spec.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit) 111 spec.Params.BlockReward = (*hexutil.Big)(ethash.SberexBlockReward) 112 113 spec.Genesis.Nonce = (hexutil.Bytes)(make([]byte, 8)) 114 binary.LittleEndian.PutUint64(spec.Genesis.Nonce[:], genesis.Nonce) 115 116 spec.Genesis.MixHash = genesis.Mixhash 117 spec.Genesis.Difficulty = (*hexutil.Big)(genesis.Difficulty) 118 spec.Genesis.Author = genesis.Coinbase 119 spec.Genesis.Timestamp = (hexutil.Uint64)(genesis.Timestamp) 120 spec.Genesis.ParentHash = genesis.ParentHash 121 spec.Genesis.ExtraData = (hexutil.Bytes)(genesis.ExtraData) 122 spec.Genesis.GasLimit = (hexutil.Uint64)(genesis.GasLimit) 123 124 spec.Accounts = make(map[common.Address]*cppSberexGenesisSpecAccount) 125 for address, account := range genesis.Alloc { 126 spec.Accounts[address] = &cppSberexGenesisSpecAccount{ 127 Balance: (*hexutil.Big)(account.Balance), 128 Nonce: account.Nonce, 129 } 130 } 131 spec.Accounts[common.BytesToAddress([]byte{1})].Precompiled = &cppSberexGenesisSpecBuiltin{ 132 Name: "ecrecover", Linear: &cppSberexGenesisSpecLinearPricing{Base: 3000}, 133 } 134 spec.Accounts[common.BytesToAddress([]byte{2})].Precompiled = &cppSberexGenesisSpecBuiltin{ 135 Name: "sha256", Linear: &cppSberexGenesisSpecLinearPricing{Base: 60, Word: 12}, 136 } 137 spec.Accounts[common.BytesToAddress([]byte{3})].Precompiled = &cppSberexGenesisSpecBuiltin{ 138 Name: "ripemd160", Linear: &cppSberexGenesisSpecLinearPricing{Base: 600, Word: 120}, 139 } 140 spec.Accounts[common.BytesToAddress([]byte{4})].Precompiled = &cppSberexGenesisSpecBuiltin{ 141 Name: "identity", Linear: &cppSberexGenesisSpecLinearPricing{Base: 15, Word: 3}, 142 } 143 if genesis.Config.ByzantiumBlock != nil { 144 spec.Accounts[common.BytesToAddress([]byte{5})].Precompiled = &cppSberexGenesisSpecBuiltin{ 145 Name: "modexp", StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()), 146 } 147 spec.Accounts[common.BytesToAddress([]byte{6})].Precompiled = &cppSberexGenesisSpecBuiltin{ 148 Name: "alt_bn128_G1_add", StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()), Linear: &cppSberexGenesisSpecLinearPricing{Base: 500}, 149 } 150 spec.Accounts[common.BytesToAddress([]byte{7})].Precompiled = &cppSberexGenesisSpecBuiltin{ 151 Name: "alt_bn128_G1_mul", StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()), Linear: &cppSberexGenesisSpecLinearPricing{Base: 40000}, 152 } 153 spec.Accounts[common.BytesToAddress([]byte{8})].Precompiled = &cppSberexGenesisSpecBuiltin{ 154 Name: "alt_bn128_pairing_product", StartingBlock: (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()), 155 } 156 } 157 return spec, nil 158 } 159 160 // parityChainSpec is the chain specification format used by Parity. 161 type parityChainSpec struct { 162 Name string `json:"name"` 163 Engine struct { 164 Ethash struct { 165 Params struct { 166 MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"` 167 DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"` 168 GasLimitBoundDivisor hexutil.Uint64 `json:"gasLimitBoundDivisor"` 169 DurationLimit *hexutil.Big `json:"durationLimit"` 170 BlockReward *hexutil.Big `json:"blockReward"` 171 HomesteadTransition uint64 `json:"homesteadTransition"` 172 EIP150Transition uint64 `json:"eip150Transition"` 173 EIP160Transition uint64 `json:"eip160Transition"` 174 EIP161abcTransition uint64 `json:"eip161abcTransition"` 175 EIP161dTransition uint64 `json:"eip161dTransition"` 176 EIP649Reward *hexutil.Big `json:"eip649Reward"` 177 EIP100bTransition uint64 `json:"eip100bTransition"` 178 EIP649Transition uint64 `json:"eip649Transition"` 179 } `json:"params"` 180 } `json:"Ethash"` 181 } `json:"engine"` 182 183 Params struct { 184 MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"` 185 MinGasLimit hexutil.Uint64 `json:"minGasLimit"` 186 NetworkID hexutil.Uint64 `json:"networkID"` 187 MaxCodeSize uint64 `json:"maxCodeSize"` 188 EIP155Transition uint64 `json:"eip155Transition"` 189 EIP98Transition uint64 `json:"eip98Transition"` 190 EIP86Transition uint64 `json:"eip86Transition"` 191 EIP140Transition uint64 `json:"eip140Transition"` 192 EIP211Transition uint64 `json:"eip211Transition"` 193 EIP214Transition uint64 `json:"eip214Transition"` 194 EIP658Transition uint64 `json:"eip658Transition"` 195 } `json:"params"` 196 197 Genesis struct { 198 Seal struct { 199 Sberex struct { 200 Nonce hexutil.Bytes `json:"nonce"` 201 MixHash hexutil.Bytes `json:"mixHash"` 202 } `json:"sberex"` 203 } `json:"seal"` 204 205 Difficulty *hexutil.Big `json:"difficulty"` 206 Author common.Address `json:"author"` 207 Timestamp hexutil.Uint64 `json:"timestamp"` 208 ParentHash common.Hash `json:"parentHash"` 209 ExtraData hexutil.Bytes `json:"extraData"` 210 GasLimit hexutil.Uint64 `json:"gasLimit"` 211 } `json:"genesis"` 212 213 Nodes []string `json:"nodes"` 214 Accounts map[common.Address]*parityChainSpecAccount `json:"accounts"` 215 } 216 217 // parityChainSpecAccount is the prefunded genesis account and/or precompiled 218 // contract definition. 219 type parityChainSpecAccount struct { 220 Balance *hexutil.Big `json:"balance"` 221 Nonce uint64 `json:"nonce,omitempty"` 222 Builtin *parityChainSpecBuiltin `json:"builtin,omitempty"` 223 } 224 225 // parityChainSpecBuiltin is the precompiled contract definition. 226 type parityChainSpecBuiltin struct { 227 Name string `json:"name,omitempty"` 228 ActivateAt uint64 `json:"activate_at,omitempty"` 229 Pricing *parityChainSpecPricing `json:"pricing,omitempty"` 230 } 231 232 // parityChainSpecPricing represents the different pricing models that builtin 233 // contracts might advertise using. 234 type parityChainSpecPricing struct { 235 Linear *parityChainSpecLinearPricing `json:"linear,omitempty"` 236 ModExp *parityChainSpecModExpPricing `json:"modexp,omitempty"` 237 AltBnPairing *parityChainSpecAltBnPairingPricing `json:"alt_bn128_pairing,omitempty"` 238 } 239 240 type parityChainSpecLinearPricing struct { 241 Base uint64 `json:"base"` 242 Word uint64 `json:"word"` 243 } 244 245 type parityChainSpecModExpPricing struct { 246 Divisor uint64 `json:"divisor"` 247 } 248 249 type parityChainSpecAltBnPairingPricing struct { 250 Base uint64 `json:"base"` 251 Pair uint64 `json:"pair"` 252 } 253 254 // newParityChainSpec converts a go-sberex genesis block into a Parity specific 255 // chain specification format. 256 func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []string) (*parityChainSpec, error) { 257 // Only ethash is currently supported between go-sberex and Parity 258 if genesis.Config.Ethash == nil { 259 return nil, errors.New("unsupported consensus engine") 260 } 261 // Reconstruct the chain spec in Parity's format 262 spec := &parityChainSpec{ 263 Name: network, 264 Nodes: bootnodes, 265 } 266 spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty) 267 spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor) 268 spec.Engine.Ethash.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor) 269 spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit) 270 spec.Engine.Ethash.Params.BlockReward = (*hexutil.Big)(ethash.SberexBlockReward) 271 spec.Engine.Ethash.Params.HomesteadTransition = genesis.Config.HomesteadBlock.Uint64() 272 spec.Engine.Ethash.Params.EIP150Transition = genesis.Config.EIP150Block.Uint64() 273 spec.Engine.Ethash.Params.EIP160Transition = genesis.Config.EIP155Block.Uint64() 274 spec.Engine.Ethash.Params.EIP161abcTransition = genesis.Config.EIP158Block.Uint64() 275 spec.Engine.Ethash.Params.EIP161dTransition = genesis.Config.EIP158Block.Uint64() 276 spec.Engine.Ethash.Params.EIP649Reward = (*hexutil.Big)(ethash.SberexBlockReward) 277 spec.Engine.Ethash.Params.EIP100bTransition = genesis.Config.ByzantiumBlock.Uint64() 278 spec.Engine.Ethash.Params.EIP649Transition = genesis.Config.ByzantiumBlock.Uint64() 279 280 spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize) 281 spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit) 282 spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) 283 spec.Params.MaxCodeSize = params.MaxCodeSize 284 spec.Params.EIP155Transition = genesis.Config.EIP155Block.Uint64() 285 spec.Params.EIP98Transition = math.MaxUint64 286 spec.Params.EIP86Transition = math.MaxUint64 287 spec.Params.EIP140Transition = genesis.Config.ByzantiumBlock.Uint64() 288 spec.Params.EIP211Transition = genesis.Config.ByzantiumBlock.Uint64() 289 spec.Params.EIP214Transition = genesis.Config.ByzantiumBlock.Uint64() 290 spec.Params.EIP658Transition = genesis.Config.ByzantiumBlock.Uint64() 291 292 spec.Genesis.Seal.Sberex.Nonce = (hexutil.Bytes)(make([]byte, 8)) 293 binary.LittleEndian.PutUint64(spec.Genesis.Seal.Sberex.Nonce[:], genesis.Nonce) 294 295 spec.Genesis.Seal.Sberex.MixHash = (hexutil.Bytes)(genesis.Mixhash[:]) 296 spec.Genesis.Difficulty = (*hexutil.Big)(genesis.Difficulty) 297 spec.Genesis.Author = genesis.Coinbase 298 spec.Genesis.Timestamp = (hexutil.Uint64)(genesis.Timestamp) 299 spec.Genesis.ParentHash = genesis.ParentHash 300 spec.Genesis.ExtraData = (hexutil.Bytes)(genesis.ExtraData) 301 spec.Genesis.GasLimit = (hexutil.Uint64)(genesis.GasLimit) 302 303 spec.Accounts = make(map[common.Address]*parityChainSpecAccount) 304 for address, account := range genesis.Alloc { 305 spec.Accounts[address] = &parityChainSpecAccount{ 306 Balance: (*hexutil.Big)(account.Balance), 307 Nonce: account.Nonce, 308 } 309 } 310 spec.Accounts[common.BytesToAddress([]byte{1})].Builtin = &parityChainSpecBuiltin{ 311 Name: "ecrecover", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 3000}}, 312 } 313 spec.Accounts[common.BytesToAddress([]byte{2})].Builtin = &parityChainSpecBuiltin{ 314 Name: "sha256", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 60, Word: 12}}, 315 } 316 spec.Accounts[common.BytesToAddress([]byte{3})].Builtin = &parityChainSpecBuiltin{ 317 Name: "ripemd160", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 600, Word: 120}}, 318 } 319 spec.Accounts[common.BytesToAddress([]byte{4})].Builtin = &parityChainSpecBuiltin{ 320 Name: "identity", Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 15, Word: 3}}, 321 } 322 if genesis.Config.ByzantiumBlock != nil { 323 spec.Accounts[common.BytesToAddress([]byte{5})].Builtin = &parityChainSpecBuiltin{ 324 Name: "modexp", ActivateAt: genesis.Config.ByzantiumBlock.Uint64(), Pricing: &parityChainSpecPricing{ModExp: &parityChainSpecModExpPricing{Divisor: 20}}, 325 } 326 spec.Accounts[common.BytesToAddress([]byte{6})].Builtin = &parityChainSpecBuiltin{ 327 Name: "alt_bn128_add", ActivateAt: genesis.Config.ByzantiumBlock.Uint64(), Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 500}}, 328 } 329 spec.Accounts[common.BytesToAddress([]byte{7})].Builtin = &parityChainSpecBuiltin{ 330 Name: "alt_bn128_mul", ActivateAt: genesis.Config.ByzantiumBlock.Uint64(), Pricing: &parityChainSpecPricing{Linear: &parityChainSpecLinearPricing{Base: 40000}}, 331 } 332 spec.Accounts[common.BytesToAddress([]byte{8})].Builtin = &parityChainSpecBuiltin{ 333 Name: "alt_bn128_pairing", ActivateAt: genesis.Config.ByzantiumBlock.Uint64(), Pricing: &parityChainSpecPricing{AltBnPairing: &parityChainSpecAltBnPairingPricing{Base: 100000, Pair: 80000}}, 334 } 335 } 336 return spec, nil 337 } 338 339 // pySberexGenesisSpec represents the genesis specification format used by the 340 // Python Sberex implementation. 341 type pySberexGenesisSpec struct { 342 Nonce hexutil.Bytes `json:"nonce"` 343 Timestamp hexutil.Uint64 `json:"timestamp"` 344 ExtraData hexutil.Bytes `json:"extraData"` 345 GasLimit hexutil.Uint64 `json:"gasLimit"` 346 Difficulty *hexutil.Big `json:"difficulty"` 347 Mixhash common.Hash `json:"mixhash"` 348 Coinbase common.Address `json:"coinbase"` 349 Alloc core.GenesisAlloc `json:"alloc"` 350 ParentHash common.Hash `json:"parentHash"` 351 } 352 353 // newPySberexGenesisSpec converts a go-sberex genesis block into a Parity specific 354 // chain specification format. 355 func newPySberexGenesisSpec(network string, genesis *core.Genesis) (*pySberexGenesisSpec, error) { 356 // Only ethash is currently supported between go-sberex and pysberex 357 if genesis.Config.Ethash == nil { 358 return nil, errors.New("unsupported consensus engine") 359 } 360 spec := &pySberexGenesisSpec{ 361 Timestamp: (hexutil.Uint64)(genesis.Timestamp), 362 ExtraData: genesis.ExtraData, 363 GasLimit: (hexutil.Uint64)(genesis.GasLimit), 364 Difficulty: (*hexutil.Big)(genesis.Difficulty), 365 Mixhash: genesis.Mixhash, 366 Coinbase: genesis.Coinbase, 367 Alloc: genesis.Alloc, 368 ParentHash: genesis.ParentHash, 369 } 370 spec.Nonce = (hexutil.Bytes)(make([]byte, 8)) 371 binary.LittleEndian.PutUint64(spec.Nonce[:], genesis.Nonce) 372 373 return spec, nil 374 }