github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/core/genesis.go (about) 1 package core 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "fmt" 7 "math/big" 8 9 "github.com/unicornultrafoundation/go-u2u/common" 10 "github.com/unicornultrafoundation/go-u2u/common/hexutil" 11 "github.com/unicornultrafoundation/go-u2u/common/math" 12 "github.com/unicornultrafoundation/go-u2u/core/rawdb" 13 "github.com/unicornultrafoundation/go-u2u/core/state" 14 "github.com/unicornultrafoundation/go-u2u/core/types" 15 "github.com/unicornultrafoundation/go-u2u/crypto" 16 "github.com/unicornultrafoundation/go-u2u/ethdb" 17 "github.com/unicornultrafoundation/go-u2u/params" 18 "github.com/unicornultrafoundation/go-u2u/trie" 19 ) 20 21 // Genesis specifies the header fields, state of a genesis block. It also defines hard 22 // fork switch-over blocks through the chain configuration. 23 type Genesis struct { 24 Config *params.ChainConfig `json:"config"` 25 Nonce uint64 `json:"nonce"` 26 Timestamp uint64 `json:"timestamp"` 27 ExtraData []byte `json:"extraData"` 28 GasLimit uint64 `json:"gasLimit" gencodec:"required"` 29 Difficulty *big.Int `json:"difficulty" gencodec:"required"` 30 Mixhash common.Hash `json:"mixHash"` 31 Coinbase common.Address `json:"coinbase"` 32 Alloc GenesisAlloc `json:"alloc" gencodec:"required"` 33 34 // These fields are used for consensus tests. Please don't use them 35 // in actual genesis blocks. 36 Number uint64 `json:"number"` 37 GasUsed uint64 `json:"gasUsed"` 38 ParentHash common.Hash `json:"parentHash"` 39 BaseFee *big.Int `json:"baseFeePerGas"` // EIP-1559 40 ExcessBlobGas *uint64 `json:"excessBlobGas"` // EIP-4844 41 BlobGasUsed *uint64 `json:"blobGasUsed"` // EIP-4844 42 } 43 44 // ToBlock creates the genesis block and writes state of a genesis specification 45 // to the given database (or discards it if nil). 46 func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { 47 if db == nil { 48 db = rawdb.NewMemoryDatabase() 49 } 50 statedb, err := state.New(common.Hash{}, state.NewDatabase(db), nil) 51 if err != nil { 52 panic(err) 53 } 54 for addr, account := range g.Alloc { 55 statedb.AddBalance(addr, account.Balance) 56 statedb.SetCode(addr, account.Code) 57 statedb.SetNonce(addr, account.Nonce) 58 for key, value := range account.Storage { 59 statedb.SetState(addr, key, value) 60 } 61 } 62 root := statedb.IntermediateRoot(false) 63 head := &types.Header{ 64 Number: new(big.Int).SetUint64(g.Number), 65 Nonce: types.EncodeNonce(g.Nonce), 66 Time: g.Timestamp, 67 ParentHash: g.ParentHash, 68 Extra: g.ExtraData, 69 GasLimit: g.GasLimit, 70 GasUsed: g.GasUsed, 71 BaseFee: g.BaseFee, 72 Difficulty: g.Difficulty, 73 MixDigest: g.Mixhash, 74 Coinbase: g.Coinbase, 75 Root: root, 76 } 77 if g.GasLimit == 0 { 78 head.GasLimit = params.GenesisGasLimit 79 } 80 if g.Difficulty == nil { 81 head.Difficulty = params.GenesisDifficulty 82 } 83 if g.Config != nil && g.Config.IsLondon(common.Big0) { 84 if g.BaseFee != nil { 85 head.BaseFee = g.BaseFee 86 } else { 87 head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee) 88 } 89 } 90 statedb.Commit(false) 91 statedb.Database().TrieDB().Commit(root, true, nil) 92 93 return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)) 94 } 95 96 // Commit writes the block and state of a genesis specification to the database. 97 // The block is committed as the canonical head block. 98 func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { 99 block := g.ToBlock(db) 100 if block.Number().Sign() != 0 { 101 return nil, fmt.Errorf("can't commit genesis block with number > 0") 102 } 103 config := g.Config 104 if config == nil { 105 config = params.AllProtocolChanges 106 } 107 if err := config.CheckConfigForkOrder(); err != nil { 108 return nil, err 109 } 110 rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty) 111 rawdb.WriteBlock(db, block) 112 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) 113 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 114 rawdb.WriteHeadBlockHash(db, block.Hash()) 115 rawdb.WriteHeadFastBlockHash(db, block.Hash()) 116 rawdb.WriteHeadHeaderHash(db, block.Hash()) 117 rawdb.WriteChainConfig(db, block.Hash(), config) 118 return block, nil 119 } 120 121 // MustCommit writes the genesis block and state to db, panicking on error. 122 // The block is committed as the canonical head block. 123 func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { 124 block, err := g.Commit(db) 125 if err != nil { 126 panic(err) 127 } 128 return block 129 } 130 131 // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. 132 func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { 133 g := Genesis{ 134 Alloc: GenesisAlloc{addr: {Balance: balance}}, 135 BaseFee: big.NewInt(params.InitialBaseFee), 136 } 137 return g.MustCommit(db) 138 } 139 140 // DeveloperGenesisBlock returns the 'geth --dev' genesis block. 141 func DeveloperGenesisBlock(faucet common.Address) *Genesis { 142 // Assemble and return the genesis with the precompiles and faucet pre-funded 143 return &Genesis{ 144 Config: params.AllProtocolChanges, 145 ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...), 146 GasLimit: 11500000, 147 BaseFee: big.NewInt(params.InitialBaseFee), 148 Difficulty: big.NewInt(1), 149 Alloc: map[common.Address]GenesisAccount{ 150 common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover 151 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 152 common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD 153 common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity 154 common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp 155 common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd 156 common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul 157 common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing 158 common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b 159 faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, 160 }, 161 } 162 } 163 164 // GenesisAlloc specifies the initial state that is part of the genesis block. 165 type GenesisAlloc map[common.Address]GenesisAccount 166 167 // GenesisAccount is an account in the state of the genesis block. 168 type GenesisAccount struct { 169 Code []byte `json:"code,omitempty"` 170 Storage map[common.Hash]common.Hash `json:"storage,omitempty"` 171 Balance *big.Int `json:"balance" gencodec:"required"` 172 Nonce uint64 `json:"nonce,omitempty"` 173 PrivateKey []byte `json:"secretKey,omitempty"` // for tests 174 } 175 176 // field type overrides for gencodec 177 type genesisSpecMarshaling struct { 178 Nonce math.HexOrDecimal64 179 Timestamp math.HexOrDecimal64 180 ExtraData hexutil.Bytes 181 GasLimit math.HexOrDecimal64 182 GasUsed math.HexOrDecimal64 183 Number math.HexOrDecimal64 184 Difficulty *math.HexOrDecimal256 185 BaseFee *math.HexOrDecimal256 186 Alloc map[common.UnprefixedAddress]GenesisAccount 187 } 188 189 type genesisAccountMarshaling struct { 190 Code hexutil.Bytes 191 Balance *math.HexOrDecimal256 192 Nonce math.HexOrDecimal64 193 Storage map[storageJSON]storageJSON 194 PrivateKey hexutil.Bytes 195 } 196 197 // storageJSON represents a 256 bit byte array, but allows less than 256 bits when 198 // unmarshaling from hex. 199 type storageJSON common.Hash 200 201 func (h *storageJSON) UnmarshalText(text []byte) error { 202 text = bytes.TrimPrefix(text, []byte("0x")) 203 if len(text) > 64 { 204 return fmt.Errorf("too many hex characters in storage key/value %q", text) 205 } 206 offset := len(h) - len(text)/2 // pad on the left 207 if _, err := hex.Decode(h[offset:], text); err != nil { 208 fmt.Println(err) 209 return fmt.Errorf("invalid hex storage key/value %q", text) 210 } 211 return nil 212 } 213 214 func (h storageJSON) MarshalText() ([]byte, error) { 215 return hexutil.Bytes(h[:]).MarshalText() 216 }