github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/genesis.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2014 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package core 26 27 import ( 28 "bytes" 29 "encoding/hex" 30 "encoding/json" 31 "errors" 32 "fmt" 33 "math/big" 34 "strings" 35 36 "github.com/ethereum/go-ethereum/common" 37 "github.com/ethereum/go-ethereum/common/hexutil" 38 "github.com/ethereum/go-ethereum/common/math" 39 "github.com/ethereum/go-ethereum/core/rawdb" 40 "github.com/ethereum/go-ethereum/core/state" 41 "github.com/ethereum/go-ethereum/core/types" 42 "github.com/ethereum/go-ethereum/ethdb" 43 "github.com/ethereum/go-ethereum/log" 44 "github.com/ethereum/go-ethereum/params" 45 "github.com/ethereum/go-ethereum/rlp" 46 "github.com/ethereum/go-ethereum/trie" 47 ) 48 49 //go:生成gencodec-类型genesis-场覆盖genesspecmarshaling-out gen_genesis.go 50 //go:generate gencodec-type genesiaccount-field override genesiaccountmarshaling-out gen_genesis_account.go 51 52 53 //go:生成gencodec-类型genesis-场覆盖genesspecmarshaling-out gen_genesis.go 54 //go:generate gencodec-type genesiaccount-field override genesiaccountmarshaling-out gen_genesis_account.go 55 56 var errGenesisNoConfig = errors.New("genesis has no chain configuration") 57 58 //Genesis指定头字段,Genesis块的状态。它也很难定义 59 //拨叉转换块通过链条配置。 60 type Genesis struct { 61 Config *params.ChainConfig `json:"config"` 62 Nonce uint64 `json:"nonce"` 63 Timestamp uint64 `json:"timestamp"` 64 ExtraData []byte `json:"extraData"` 65 GasLimit uint64 `json:"gasLimit" gencodec:"required"` 66 Difficulty *big.Int `json:"difficulty" gencodec:"required"` 67 Mixhash common.Hash `json:"mixHash"` 68 Coinbase common.Address `json:"coinbase"` 69 Alloc GenesisAlloc `json:"alloc" gencodec:"required"` 70 71 //这些字段用于一致性测试。请不要用它们 72 //在真正的创世纪块体中。 73 Number uint64 `json:"number"` 74 GasUsed uint64 `json:"gasUsed"` 75 ParentHash common.Hash `json:"parentHash"` 76 } 77 78 //genesisalloc指定作为Genesis块一部分的初始状态。 79 type GenesisAlloc map[common.Address]GenesisAccount 80 81 func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { 82 m := make(map[common.UnprefixedAddress]GenesisAccount) 83 if err := json.Unmarshal(data, &m); err != nil { 84 return err 85 } 86 *ga = make(GenesisAlloc) 87 for addr, a := range m { 88 (*ga)[common.Address(addr)] = a 89 } 90 return nil 91 } 92 93 //Genesiaccount是一个处于Genesis区块状态的账户。 94 type GenesisAccount struct { 95 Code []byte `json:"code,omitempty"` 96 Storage map[common.Hash]common.Hash `json:"storage,omitempty"` 97 Balance *big.Int `json:"balance" gencodec:"required"` 98 Nonce uint64 `json:"nonce,omitempty"` 99 PrivateKey []byte `json:"secretKey,omitempty"` //为了测试 100 } 101 102 //gencodec的字段类型重写 103 type genesisSpecMarshaling struct { 104 Nonce math.HexOrDecimal64 105 Timestamp math.HexOrDecimal64 106 ExtraData hexutil.Bytes 107 GasLimit math.HexOrDecimal64 108 GasUsed math.HexOrDecimal64 109 Number math.HexOrDecimal64 110 Difficulty *math.HexOrDecimal256 111 Alloc map[common.UnprefixedAddress]GenesisAccount 112 } 113 114 type genesisAccountMarshaling struct { 115 Code hexutil.Bytes 116 Balance *math.HexOrDecimal256 117 Nonce math.HexOrDecimal64 118 Storage map[storageJSON]storageJSON 119 PrivateKey hexutil.Bytes 120 } 121 122 //storagejson表示一个256位字节数组,但当 123 //从十六进制解组。 124 type storageJSON common.Hash 125 126 func (h *storageJSON) UnmarshalText(text []byte) error { 127 text = bytes.TrimPrefix(text, []byte("0x")) 128 if len(text) > 64 { 129 return fmt.Errorf("too many hex characters in storage key/value %q", text) 130 } 131 offset := len(h) - len(text)/2 //左边的垫子 132 if _, err := hex.Decode(h[offset:], text); err != nil { 133 fmt.Println(err) 134 return fmt.Errorf("invalid hex storage key/value %q", text) 135 } 136 return nil 137 } 138 139 func (h storageJSON) MarshalText() ([]byte, error) { 140 return hexutil.Bytes(h[:]).MarshalText() 141 } 142 143 //尝试覆盖现有的 144 //与不相容的起源块。 145 type GenesisMismatchError struct { 146 Stored, New common.Hash 147 } 148 149 func (e *GenesisMismatchError) Error() string { 150 return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8]) 151 } 152 153 //SetupGenesBlock在数据库中写入或更新Genesis块。 154 //将要使用的块是: 155 // 156 //创世纪=零创世纪!=零 157 //+————————————————————————————————————— 158 //DB没有Genesis主网络默认Genesis 159 //DB有来自DB的Genesis(如果兼容) 160 // 161 //如果存储链配置兼容(即不兼容),则将更新该配置 162 //在本地头块下面指定一个叉块)。如果发生冲突, 163 //错误是一个*params.configcompaterror,并返回新的未写入配置。 164 // 165 //返回的链配置从不为零。 166 func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { 167 if genesis != nil && genesis.Config == nil { 168 return params.DposChainConfig, common.Hash{}, errGenesisNoConfig 169 } 170 171 //如果没有存储的Genesis块,只需提交新块。 172 stored := rawdb.ReadCanonicalHash(db, 0) 173 if (stored == common.Hash{}) { 174 if genesis == nil { 175 log.Info("Writing default main-net genesis block") 176 genesis = DefaultGenesisBlock() 177 } else { 178 log.Info("Writing custom genesis block") 179 } 180 block, err := genesis.Commit(db) 181 return genesis.Config, block.Hash(), err 182 } 183 184 //检查Genesis块是否已经写入。 185 if genesis != nil { 186 hash := genesis.ToBlock(nil).Hash() 187 if hash != stored { 188 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 189 } 190 } 191 192 //获取现有的链配置。 193 newcfg := genesis.configOrDefault(stored) 194 storedcfg := rawdb.ReadChainConfig(db, stored) 195 if storedcfg == nil { 196 log.Warn("Found genesis block without chain config") 197 rawdb.WriteChainConfig(db, stored, newcfg) 198 return newcfg, stored, nil 199 } 200 //特殊情况:如果没有新的,不要更改非主网链的现有配置 201 //提供了配置。这些链将得到所有的协议更改(以及compat错误) 202 //如果我们继续的话。 203 if genesis == nil && stored != params.MainnetGenesisHash { 204 return storedcfg, stored, nil 205 } 206 207 //检查配置兼容性并写入配置。兼容性错误 208 //除非我们已经在零区,否则将返回给调用方。 209 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 210 if height == nil { 211 return newcfg, stored, fmt.Errorf("missing block number for head header hash") 212 } 213 compatErr := storedcfg.CheckCompatible(newcfg, *height) 214 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 215 return newcfg, stored, compatErr 216 } 217 rawdb.WriteChainConfig(db, stored, newcfg) 218 return newcfg, stored, nil 219 } 220 221 func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { 222 switch { 223 case g != nil: 224 return g.Config 225 case ghash == params.MainnetGenesisHash: 226 return params.MainnetChainConfig 227 case ghash == params.TestnetGenesisHash: 228 return params.TestnetChainConfig 229 default: 230 return params.DposChainConfig 231 } 232 } 233 234 //toblock创建genesis块并写入genesis规范的状态 235 //到给定的数据库(如果没有则丢弃它)。 236 func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { 237 if db == nil { 238 db = ethdb.NewMemDatabase() 239 } 240 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 241 for addr, account := range g.Alloc { 242 statedb.AddBalance(addr, account.Balance) 243 statedb.SetCode(addr, account.Code) 244 statedb.SetNonce(addr, account.Nonce) 245 for key, value := range account.Storage { 246 statedb.SetState(addr, key, value) 247 } 248 } 249 root := statedb.IntermediateRoot(false) 250 251 //添加上下文 252 dposContext := initGenesisDposContext(g, statedb.Database().TrieDB()) 253 dposContextProto := dposContext.ToProto() 254 255 head := &types.Header{ 256 Number: new(big.Int).SetUint64(g.Number), 257 Nonce: types.EncodeNonce(g.Nonce), 258 Time: new(big.Int).SetUint64(g.Timestamp), 259 ParentHash: g.ParentHash, 260 Extra: g.ExtraData, 261 GasLimit: g.GasLimit, 262 GasUsed: g.GasUsed, 263 Difficulty: g.Difficulty, 264 MixDigest: g.Mixhash, 265 Coinbase: g.Coinbase, 266 Root: root, 267 DposContext: dposContextProto, 268 MaxValidatorSize: g.Config.Dpos.MaxValidatorSize, 269 BlockInterval: g.Config.Dpos.BlockInterval, 270 } 271 if g.GasLimit == 0 { 272 head.GasLimit = params.GenesisGasLimit 273 } 274 if g.Difficulty == nil { 275 head.Difficulty = params.GenesisDifficulty 276 } 277 statedb.Commit(false) 278 statedb.Database().TrieDB().Commit(root, true) 279 280 block := types.NewBlock(head, nil, nil, nil) 281 block.DposContext = dposContext 282 283 return block 284 } 285 286 //commit将Genesis规范的块和状态写入数据库。 287 //该块作为规范头块提交。 288 func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { 289 block := g.ToBlock(db) 290 if block.Number().Sign() != 0 { 291 return nil, fmt.Errorf("can't commit genesis block with number > 0") 292 } 293 //添加上下文 294 if _, err := block.DposContext.Commit(); err != nil { 295 return nil, err 296 } 297 rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty) 298 rawdb.WriteBlock(db, block) 299 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) 300 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 301 rawdb.WriteHeadBlockHash(db, block.Hash()) 302 rawdb.WriteHeadHeaderHash(db, block.Hash()) 303 304 config := g.Config 305 if config == nil { 306 config = params.DposChainConfig 307 } 308 rawdb.WriteChainConfig(db, block.Hash(), config) 309 return block, nil 310 } 311 312 //mustcommit将genesis块和状态写入db,并在出错时惊慌失措。 313 //该块作为规范头块提交。 314 func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { 315 block, err := g.Commit(db) 316 if err != nil { 317 panic(err) 318 } 319 return block 320 } 321 322 //genesisblockfortesting创建并写入一个块,其中addr具有给定的wei平衡。 323 func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { 324 g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}} 325 return g.MustCommit(db) 326 } 327 328 //defaultgenesisblock返回以太坊主网Genesis块。 329 func DefaultGenesisBlock() *Genesis { 330 return &Genesis{ 331 Config: params.DposChainConfig, 332 Nonce: 66, 333 Timestamp: 1522052340, 334 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), 335 GasLimit: 4712388, 336 Difficulty: big.NewInt(17179869184), 337 Alloc: decodePrealloc(mainnetAllocData), 338 } 339 } 340 341 //DefaultTestNetGenesBlock返回Ropsten Network Genesis块。 342 func DefaultTestnetGenesisBlock() *Genesis { 343 return &Genesis{ 344 Config: params.TestnetChainConfig, 345 Nonce: 66, 346 ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"), 347 GasLimit: 16777216, 348 Difficulty: big.NewInt(1048576), 349 Alloc: decodePrealloc(testnetAllocData), 350 } 351 } 352 353 //defaultrinkebygenesblock返回rinkeby网络genesis块。 354 func DefaultRinkebyGenesisBlock() *Genesis { 355 return &Genesis{ 356 Config: params.RinkebyChainConfig, 357 Timestamp: 1492009146, 358 ExtraData: hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), 359 GasLimit: 4700000, 360 Difficulty: big.NewInt(1), 361 Alloc: decodePrealloc(rinkebyAllocData), 362 } 363 } 364 365 //developergenessblock返回“geth--dev”genesis块。注意,这必须 366 //播种 367 func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { 368 //将默认期间覆盖到用户请求的期间 369 config := *params.AllCliqueProtocolChanges 370 config.Clique.Period = period 371 372 //组装并返回带有预编译和水龙头的Genesis 373 return &Genesis{ 374 Config: &config, 375 ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...), 376 GasLimit: 6283185, 377 Difficulty: big.NewInt(1), 378 Alloc: map[common.Address]GenesisAccount{ 379 common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, //恢复正常 380 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, //沙256 381 common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, //里米德 382 common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, //身份 383 common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, //莫德斯普 384 common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, //埃卡德 385 common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, //蜕皮素 386 common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, //蜕变 387 faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, 388 }, 389 } 390 } 391 392 func decodePrealloc(data string) GenesisAlloc { 393 var p []struct{ Addr, Balance *big.Int } 394 if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { 395 panic(err) 396 } 397 ga := make(GenesisAlloc, len(p)) 398 for _, account := range p { 399 ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance} 400 } 401 return ga 402 } 403 404 func initGenesisDposContext(g *Genesis, db *trie.Database) *types.DposContext { 405 dc, err := types.NewDposContextFromProto(db, &types.DposContextProto{}) 406 if err != nil { 407 log.Error("initGenesisDposContext-NewDposContextFromProto-new", "DposContext", dc, "error", err) 408 return nil 409 } 410 if g.Config != nil && g.Config.Dpos != nil && g.Config.Dpos.Validators != nil { 411 dc.SetValidators(g.Config.Dpos.Validators) 412 for _, validator := range g.Config.Dpos.Validators { 413 dc.DelegateTrie().TryUpdate(append(validator.Bytes(), validator.Bytes()...), validator.Bytes()) 414 dc.CandidateTrie().TryUpdate(validator.Bytes(), validator.Bytes()) 415 } 416 } 417 return dc 418 }