github.com/gnc-project/gnc@v1.0.0/core/genesis.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser 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 // The go-ethereum library 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 Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "encoding/json" 23 "errors" 24 "fmt" 25 "math/big" 26 "strings" 27 28 "github.com/gnc-project/gnc/common" 29 "github.com/gnc-project/gnc/common/hexutil" 30 "github.com/gnc-project/gnc/common/math" 31 "github.com/gnc-project/gnc/core/rawdb" 32 "github.com/gnc-project/gnc/core/state" 33 "github.com/gnc-project/gnc/core/types" 34 "github.com/gnc-project/gnc/crypto" 35 "github.com/gnc-project/gnc/ethdb" 36 "github.com/gnc-project/gnc/log" 37 "github.com/gnc-project/gnc/params" 38 "github.com/gnc-project/gnc/rlp" 39 ) 40 41 //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go 42 //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go 43 44 var errGenesisNoConfig = errors.New("genesis has no chain configuration") 45 46 // Genesis specifies the header fields, state of a genesis block. It also defines hard 47 // fork switch-over blocks through the chain configuration. 48 type Genesis struct { 49 Config *params.ChainConfig `json:"config"` 50 Nonce uint64 `json:"nonce"` 51 Timestamp uint64 `json:"timestamp"` 52 ExtraData []byte `json:"extraData"` 53 GasLimit uint64 `json:"gasLimit" gencodec:"required"` 54 Difficulty *big.Int `json:"baseTarget" gencodec:"required"` 55 Mixhash common.Hash `json:"mixHash"` 56 Coinbase common.Address `json:"coinbase"` 57 Alloc GenesisAlloc `json:"alloc" gencodec:"required"` 58 59 // These fields are used for consensus tests. Please don't use them 60 // in actual genesis blocks. 61 Number uint64 `json:"number"` 62 GasUsed uint64 `json:"gasUsed"` 63 ParentHash common.Hash `json:"parentHash"` 64 //linzhaojie TheFates code 65 TheFates common.Address `json:"theFates"` 66 // Difficulty *big.Int `json:"baseTarget" gencodec:"required"` 67 } 68 69 // GenesisAlloc specifies the initial state that is part of the genesis block. 70 type GenesisAlloc map[common.Address]GenesisAccount 71 72 func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { 73 m := make(map[common.UnprefixedAddress]GenesisAccount) 74 if err := json.Unmarshal(data, &m); err != nil { 75 return err 76 } 77 *ga = make(GenesisAlloc) 78 for addr, a := range m { 79 (*ga)[common.Address(addr)] = a 80 } 81 return nil 82 } 83 84 // GenesisAccount is an account in the state of the genesis block. 85 type GenesisAccount struct { 86 Code []byte `json:"code,omitempty"` 87 Storage map[common.Hash]common.Hash `json:"storage,omitempty"` 88 Balance *big.Int `json:"balance" gencodec:"required"` 89 Nonce uint64 `json:"nonce,omitempty"` 90 PrivateKey []byte `json:"secretKey,omitempty"` // for tests 91 } 92 93 // field type overrides for gencodec 94 type genesisSpecMarshaling struct { 95 Nonce math.HexOrDecimal64 96 Timestamp math.HexOrDecimal64 97 ExtraData hexutil.Bytes 98 GasLimit math.HexOrDecimal64 99 GasUsed math.HexOrDecimal64 100 Number math.HexOrDecimal64 101 Difficulty *math.HexOrDecimal256 102 Alloc map[common.UnprefixedAddress]GenesisAccount 103 } 104 105 type genesisAccountMarshaling struct { 106 Code hexutil.Bytes 107 Balance *math.HexOrDecimal256 108 Nonce math.HexOrDecimal64 109 Storage map[storageJSON]storageJSON 110 PrivateKey hexutil.Bytes 111 } 112 113 // storageJSON represents a 256 bit byte array, but allows less than 256 bits when 114 // unmarshaling from hex. 115 type storageJSON common.Hash 116 117 func (h *storageJSON) UnmarshalText(text []byte) error { 118 text = bytes.TrimPrefix(text, []byte("0x")) 119 if len(text) > 64 { 120 return fmt.Errorf("too many hex characters in storage key/value %q", text) 121 } 122 offset := len(h) - len(text)/2 // pad on the left 123 if _, err := hex.Decode(h[offset:], text); err != nil { 124 fmt.Println(err) 125 return fmt.Errorf("invalid hex storage key/value %q", text) 126 } 127 return nil 128 } 129 130 func (h storageJSON) MarshalText() ([]byte, error) { 131 return hexutil.Bytes(h[:]).MarshalText() 132 } 133 134 // GenesisMismatchError is raised when trying to overwrite an existing 135 // genesis block with an incompatible one. 136 type GenesisMismatchError struct { 137 Stored, New common.Hash 138 } 139 140 func (e *GenesisMismatchError) Error() string { 141 return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New) 142 } 143 144 // SetupGenesisBlock writes or updates the genesis block in db. 145 // The block that will be used is: 146 // 147 // genesis == nil genesis != nil 148 // +------------------------------------------ 149 // db has no genesis | main-net default | genesis 150 // db has genesis | from DB | genesis (if compatible) 151 // 152 // The stored chain configuration will be updated if it is compatible (i.e. does not 153 // specify a fork block below the local head block). In case of a conflict, the 154 // error is a *params.ConfigCompatError and the new, unwritten config is returned. 155 // 156 // The returned chain configuration is never nil. 157 func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { 158 return SetupGenesisBlockWithOverride(db, genesis, nil) 159 } 160 161 func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideIstanbul *big.Int) (*params.ChainConfig, common.Hash, error) { 162 if genesis != nil && genesis.Config == nil { 163 return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig 164 } 165 // Just commit the new block if there is no stored genesis block. 166 stored := rawdb.ReadCanonicalHash(db, 0) 167 if (stored == common.Hash{}) { 168 if genesis == nil { 169 log.Info("Writing default main-net genesis block") 170 genesis = DefaultGenesisBlock() 171 } else { 172 log.Info("Writing custom genesis block") 173 } 174 block, err := genesis.Commit(db) 175 if err != nil { 176 return genesis.Config, common.Hash{}, err 177 } 178 return genesis.Config, block.Hash(), nil 179 } 180 181 // We have the genesis block in database(perhaps in ancient database) 182 // but the corresponding state is missing. 183 header := rawdb.ReadHeader(db, stored, 0) 184 if _, err := state.New(header.Root, state.NewDatabaseWithCache(db, 0)); err != nil { 185 if genesis == nil { 186 genesis = DefaultGenesisBlock() 187 } 188 // Ensure the stored genesis matches with the given one. 189 hash := genesis.ToBlock(nil).Hash() 190 if hash != stored { 191 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 192 } 193 block, err := genesis.Commit(db) 194 if err != nil { 195 return genesis.Config, hash, err 196 } 197 return genesis.Config, block.Hash(), nil 198 } 199 200 // Check whether the genesis block is already written. 201 if genesis != nil { 202 hash := genesis.ToBlock(nil).Hash() 203 if hash != stored { 204 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 205 } 206 } 207 208 // Get the existing chain configuration. 209 newcfg := genesis.configOrDefault(stored) 210 if overrideIstanbul != nil { 211 newcfg.IstanbulBlock = overrideIstanbul 212 } 213 if err := newcfg.CheckConfigForkOrder(); err != nil { 214 return newcfg, common.Hash{}, err 215 } 216 storedcfg := rawdb.ReadChainConfig(db, stored) 217 if storedcfg == nil { 218 log.Warn("Found genesis block without chain config") 219 rawdb.WriteChainConfig(db, stored, newcfg) 220 return newcfg, stored, nil 221 } 222 // Special case: don't change the existing config of a non-mainnet chain if no new 223 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 224 // if we just continued here. 225 if genesis == nil && stored != params.MainnetGenesisHash { 226 return storedcfg, stored, nil 227 } 228 229 // Check config compatibility and write the config. Compatibility errors 230 // are returned to the caller unless we're already at block zero. 231 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 232 if height == nil { 233 return newcfg, stored, fmt.Errorf("missing block number for head header hash") 234 } 235 compatErr := storedcfg.CheckCompatible(newcfg, *height) 236 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 237 return newcfg, stored, compatErr 238 } 239 rawdb.WriteChainConfig(db, stored, newcfg) 240 return newcfg, stored, nil 241 } 242 243 func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { 244 switch { 245 case g != nil: 246 return g.Config 247 case ghash == params.MainnetGenesisHash: 248 return params.MainnetChainConfig 249 case ghash == params.TestnetGenesisHash: 250 return params.TestnetChainConfig 251 default: 252 return params.AllEthashProtocolChanges 253 } 254 } 255 256 // ToBlock creates the genesis block and writes state of a genesis specification 257 // to the given database (or discards it if nil). 258 func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { 259 if db == nil { 260 db = rawdb.NewMemoryDatabase() 261 } 262 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 263 for addr, account := range g.Alloc { 264 statedb.AddBalance(addr, account.Balance) 265 statedb.SetCode(addr, account.Code) 266 statedb.SetNonce(addr, account.Nonce) 267 for key, value := range account.Storage { 268 statedb.SetState(addr, key, value) 269 } 270 } 271 root := statedb.IntermediateRoot(false) 272 head := &types.Header{ 273 Number: new(big.Int).SetUint64(g.Number), 274 Nonce: types.EncodeNonce(g.Nonce), 275 Time: g.Timestamp, 276 ParentHash: g.ParentHash, 277 Extra: g.ExtraData, 278 GasLimit: g.GasLimit, 279 GasUsed: g.GasUsed, 280 Difficulty: g.Difficulty, 281 MixDigest: g.Mixhash, 282 Coinbase: g.Coinbase, 283 TheFates: g.TheFates, 284 // Difficulty: g.Difficulty, 285 Root: root, 286 } 287 if g.GasLimit == 0 { 288 head.GasLimit = params.GenesisGasLimit 289 } 290 if g.Difficulty == nil { 291 head.Difficulty = params.GenesisDifficulty 292 } 293 statedb.Commit(false) 294 statedb.Database().TrieDB().Commit(root, true) 295 296 return types.NewBlock(head, nil, nil) 297 } 298 299 // Commit writes the block and state of a genesis specification to the database. 300 // The block is committed as the canonical head block. 301 func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { 302 block := g.ToBlock(db) 303 if block.Number().Sign() != 0 { 304 return nil, fmt.Errorf("can't commit genesis block with number > 0") 305 } 306 config := g.Config 307 if config == nil { 308 config = params.AllEthashProtocolChanges 309 } 310 if err := config.CheckConfigForkOrder(); err != nil { 311 return nil, err 312 } 313 rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty) 314 rawdb.WriteBlock(db, block) 315 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) 316 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 317 rawdb.WriteHeadBlockHash(db, block.Hash()) 318 rawdb.WriteHeadFastBlockHash(db, block.Hash()) 319 rawdb.WriteHeadHeaderHash(db, block.Hash()) 320 rawdb.WriteChainConfig(db, block.Hash(), config) 321 return block, nil 322 } 323 324 // MustCommit writes the genesis block and state to db, panicking on error. 325 // The block is committed as the canonical head block. 326 func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { 327 block, err := g.Commit(db) 328 if err != nil { 329 panic(err) 330 } 331 return block 332 } 333 334 // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. 335 func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { 336 g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}} 337 return g.MustCommit(db) 338 } 339 340 // DefaultGenesisBlock returns the Ethereum main net genesis block. 341 func DefaultGenesisBlock() *Genesis { 342 return &Genesis{ 343 Config: params.MainnetChainConfig, 344 Nonce: 0x0, 345 ExtraData: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000"), 346 GasLimit: 0x47b760, 347 Difficulty: big.NewInt(0xb60b60b60), 348 Alloc: decodePrealloc(mainnetAllocData), 349 Coinbase: common.HexToAddress("GNC2ba50f4b463930fdbb7c647878f3ada5fa1b36bf"), 350 TheFates: common.HexToAddress("GNC378555a3558bad1bb43282e5554d9c0cf5ca3126"), 351 Timestamp: 1600135200, 352 } 353 } 354 355 // DefaultTestnetGenesisBlock returns the Ropsten network genesis block. 356 func DefaultTestnetGenesisBlock() *Genesis { 357 return &Genesis{ 358 Config: params.TestnetChainConfig, 359 Nonce: 66, 360 ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"), 361 GasLimit: 16777216, 362 Difficulty: big.NewInt(1048576), 363 Alloc: decodePrealloc(testnetAllocData), 364 } 365 } 366 367 // DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block. 368 func DefaultRinkebyGenesisBlock() *Genesis { 369 return &Genesis{ 370 Config: params.RinkebyChainConfig, 371 Timestamp: 1492009146, 372 ExtraData: hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), 373 GasLimit: 4700000, 374 Difficulty: big.NewInt(1), 375 Alloc: decodePrealloc(rinkebyAllocData), 376 } 377 } 378 379 // DefaultGoerliGenesisBlock returns the Görli network genesis block. 380 func DefaultGoerliGenesisBlock() *Genesis { 381 return &Genesis{ 382 Config: params.GoerliChainConfig, 383 Timestamp: 1548854791, 384 ExtraData: hexutil.MustDecode("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), 385 GasLimit: 10485760, 386 Difficulty: big.NewInt(1), 387 Alloc: decodePrealloc(goerliAllocData), 388 } 389 } 390 391 // DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must 392 // be seeded with the 393 func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { 394 // Override the default period to the user requested one 395 config := *params.AllCliqueProtocolChanges 396 config.Clique.Period = period 397 398 // Assemble and return the genesis with the precompiles and faucet pre-funded 399 return &Genesis{ 400 Config: &config, 401 ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...), 402 GasLimit: 6283185, 403 Difficulty: big.NewInt(1), 404 Alloc: map[common.Address]GenesisAccount{ 405 common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover 406 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 407 common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD 408 common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity 409 common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp 410 common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd 411 common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul 412 common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing 413 faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, 414 }, 415 } 416 } 417 418 func decodePrealloc(data string) GenesisAlloc { 419 var p []struct{ Addr, Balance *big.Int } 420 if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { 421 panic(err) 422 } 423 ga := make(GenesisAlloc, len(p)) 424 for _, account := range p { 425 ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance} 426 } 427 return ga 428 }