github.com/Gessiux/neatchain@v1.3.1/chain/core/genesis1.go (about) 1 package core 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "io/ioutil" 8 9 "github.com/Gessiux/neatchain/chain/core/rawdb" 10 "github.com/Gessiux/neatchain/chain/core/types" 11 "github.com/Gessiux/neatchain/chain/log" 12 "github.com/Gessiux/neatchain/neatdb" 13 "github.com/Gessiux/neatchain/params" 14 "github.com/Gessiux/neatchain/utilities/common" 15 ) 16 17 // WriteGenesisBlock writes the genesis block to the database as block number 0 18 //func WriteGenesisBlock(chainDb neatdb.Database, reader io.Reader) (*types.Block, error) { 19 // contents, err := ioutil.ReadAll(reader) 20 // if err != nil { 21 // return nil, err 22 // } 23 // 24 // var genesis = Genesis{} 25 // 26 // if err := json.Unmarshal(contents, &genesis); err != nil { 27 // return nil, err 28 // } 29 // 30 // return SetupGenesisBlockEx(chainDb, &genesis) 31 //} 32 33 func WriteGenesisBlock(chainDb neatdb.Database, reader io.Reader) (*types.Block, error) { 34 contents, err := ioutil.ReadAll(reader) 35 if err != nil { 36 return nil, err 37 } 38 39 var ( 40 genesis Genesis 41 genesisW GenesisWrite 42 ) 43 44 genesis.Alloc = GenesisAlloc{} 45 46 if err := json.Unmarshal(contents, &genesisW); err != nil { 47 return nil, err 48 } 49 50 genesis = Genesis{ 51 Config: genesisW.Config, 52 Nonce: genesisW.Nonce, 53 Timestamp: genesisW.Timestamp, 54 ParentHash: genesisW.ParentHash, 55 ExtraData: genesisW.ExtraData, 56 GasLimit: genesisW.GasLimit, 57 Difficulty: genesisW.Difficulty, 58 Mixhash: genesisW.Mixhash, 59 Coinbase: common.StringToAddress(genesisW.Coinbase), 60 Alloc: GenesisAlloc{}, 61 } 62 63 for k, v := range genesisW.Alloc { 64 genesis.Alloc[common.StringToAddress(k)] = v 65 } 66 67 return SetupGenesisBlockEx(chainDb, &genesis) 68 } 69 70 func SetupGenesisBlockEx(db neatdb.Database, genesis *Genesis) (*types.Block, error) { 71 72 if genesis != nil && genesis.Config == nil { 73 return nil, errGenesisNoConfig 74 } 75 76 var block *types.Block = nil 77 var err error = nil 78 79 // Just commit the new block if there is no stored genesis block. 80 stored := rawdb.ReadCanonicalHash(db, 0) 81 if (stored == common.Hash{}) { 82 if genesis == nil { 83 log.Info("Writing default main-net genesis block") 84 genesis = DefaultGenesisBlock() 85 } else { 86 log.Info("Writing custom genesis block") 87 } 88 block, err = genesis.Commit(db) 89 return block, err 90 } 91 92 // Check whether the genesis block is already written. 93 if genesis != nil { 94 block = genesis.ToBlock(nil) 95 hash := block.Hash() 96 if hash != stored { 97 return nil, &GenesisMismatchError{stored, hash} 98 } 99 } 100 101 // Get the existing chain configuration. 102 newcfg := genesis.configOrDefault(stored) 103 storedcfg := rawdb.ReadChainConfig(db, stored) 104 if storedcfg == nil { 105 log.Warn("Found genesis block without chain config") 106 rawdb.WriteChainConfig(db, stored, newcfg) 107 return block, err 108 } 109 // Special case: don't change the existing config of a non-mainnet chain if no new 110 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 111 // if we just continued here. 112 if genesis == nil && stored != params.MainnetGenesisHash { 113 return block, nil 114 } 115 116 // Check config compatibility and write the config. Compatibility errors 117 // are returned to the caller unless we're already at block zero. 118 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 119 if height == nil { 120 return nil, fmt.Errorf("missing block number for head header hash") 121 } 122 compatErr := storedcfg.CheckCompatible(newcfg, *height) 123 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 124 return nil, compatErr 125 } 126 return block, err 127 } 128 129 // SetupGenesisBlock writes or updates the genesis block in db. 130 // The block that will be used is: 131 // 132 // genesis == nil genesis != nil 133 // +------------------------------------------ 134 // db has no genesis | main-net default | genesis 135 // db has genesis | from DB | genesis (if compatible) 136 // 137 // The stored chain configuration will be updated if it is compatible (i.e. does not 138 // specify a fork block below the local head block). In case of a conflict, the 139 // error is a *params.ConfigCompatError and the new, unwritten config is returned. 140 // 141 // The returned chain configuration is never nil. 142 func SetupGenesisBlockWithDefault(db neatdb.Database, genesis *Genesis, isMainChain, isTestnet bool) (*params.ChainConfig, common.Hash, error) { 143 if genesis != nil && genesis.Config == nil { 144 //fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 1\n") 145 return nil, common.Hash{}, errGenesisNoConfig 146 } 147 148 // Just commit the new block if there is no stored genesis block. 149 stored := rawdb.ReadCanonicalHash(db, 0) 150 if (stored == common.Hash{} && isMainChain) { 151 if genesis == nil { 152 log.Info("Writing default main-net genesis block") 153 if isTestnet { 154 genesis = DefaultGenesisBlockFromJson(DefaultTestnetGenesisJSON) 155 } else { 156 genesis = DefaultGenesisBlockFromJson(DefaultMainnetGenesisJSON) 157 } 158 } else { 159 log.Info("Writing custom genesis block") 160 } 161 block, err := genesis.Commit(db) 162 //fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 2\n") 163 return genesis.Config, block.Hash(), err 164 } 165 166 // Check whether the genesis block is already written. 167 if genesis != nil { 168 hash := genesis.ToBlock(nil).Hash() 169 if hash != stored { 170 //fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 3\n") 171 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 172 } 173 } 174 175 // Get the existing chain configuration. 176 newcfg := genesis.configOrDefault(stored) 177 storedcfg := rawdb.ReadChainConfig(db, stored) 178 if storedcfg == nil { 179 log.Warn("Found genesis block without chain config") 180 rawdb.WriteChainConfig(db, stored, newcfg) 181 //fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 4\n") 182 return newcfg, stored, nil 183 } 184 // Special case: don't change the existing config of a non-mainnet chain if no new 185 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 186 // if we just continued here. 187 if genesis == nil && stored != params.MainnetGenesisHash { 188 //fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 5\n") 189 return storedcfg, stored, nil 190 } 191 192 // Check config compatibility and write the config. Compatibility errors 193 // are returned to the caller unless we're already at block zero. 194 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 195 if height == nil { 196 //fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 6\n") 197 return newcfg, stored, fmt.Errorf("missing block number for head header hash") 198 } 199 compatErr := storedcfg.CheckCompatible(newcfg, *height) 200 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 201 //fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 7\n") 202 return newcfg, stored, compatErr 203 } 204 rawdb.WriteChainConfig(db, stored, newcfg) 205 //fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 8\n") 206 return newcfg, stored, nil 207 } 208 209 // DefaultGenesisBlock returns the Ethereum main net genesis block. 210 func DefaultGenesisBlockFromJson(genesisJson string) *Genesis { 211 212 var ( 213 genesis Genesis 214 genesisW GenesisWrite 215 ) 216 217 genesis.Alloc = GenesisAlloc{} 218 if err := json.Unmarshal([]byte(genesisJson), &genesisW); err != nil { 219 return nil 220 } 221 222 genesis = Genesis{ 223 Config: genesisW.Config, 224 Nonce: genesisW.Nonce, 225 Timestamp: genesisW.Timestamp, 226 ParentHash: genesisW.ParentHash, 227 ExtraData: genesisW.ExtraData, 228 GasLimit: genesisW.GasLimit, 229 Difficulty: genesisW.Difficulty, 230 Mixhash: genesisW.Mixhash, 231 Coinbase: common.StringToAddress(genesisW.Coinbase), 232 Alloc: GenesisAlloc{}, 233 } 234 235 for i, v := range genesisW.Alloc { 236 genesis.Alloc[common.StringToAddress(i)] = v 237 } 238 239 return &genesis 240 } 241 242 var DefaultMainnetGenesisJSON = `{ 243 "config": { 244 "NeatChainId": "neatchain", 245 "chainId": 1, 246 "homesteadBlock": 0, 247 "eip150Block": 0, 248 "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", 249 "eip155Block": 0, 250 "eip158Block": 0, 251 "byzantiumBlock": 0, 252 "neatcon": { 253 "epoch": 30000, 254 "policy": 0 255 } 256 }, 257 "nonce": "0xdeadbeefdeadbeef", 258 "timestamp": "0x610055f7", 259 "extraData": "0x", 260 "gasLimit": "0x7270e00", 261 "difficulty": "0x1", 262 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 263 "coinbase": "NEATAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 264 "alloc": { 265 "NEATbNkySqxehp2vT1AmPhNqoMTciv1B": { 266 "balance": "0x33b2e3c9fd0803ce8000000", 267 "amount": "0x152d02c7e14af6800000" 268 } 269 }, 270 "number": "0x0", 271 "gasUsed": "0x0", 272 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 273 }` 274 275 var DefaultTestnetGenesisJSON = `{ 276 "config": { 277 "NeatChainId": "testnet", 278 "chainId": 2, 279 "homesteadBlock": 0, 280 "eip150Block": 0, 281 "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", 282 "eip155Block": 0, 283 "eip158Block": 0, 284 "byzantiumBlock": 0, 285 "neatcon": { 286 "epoch": 30000, 287 "policy": 0 288 } 289 }, 290 "nonce": "0xdeadbeefdeadbeef", 291 "timestamp": "0x5fa278cc", 292 "extraData": "0x", 293 "gasLimit": "0x7270e00", 294 "difficulty": "0x1", 295 "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", 296 "coinbase": "NEATAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 297 "alloc": { 298 "NEATcfoFiNW3i5pBxPpjSs6m1YJzjQMU": { 299 "balance": "0x29569e2db20e16b46000000", 300 "amount": "0x54b40b1f852bda000000" 301 } 302 }, 303 "number": "0x0", 304 "gasUsed": "0x0", 305 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" 306 } 307 `