github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/params/config.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:42</date> 10 //</624450107558858752> 11 12 13 package params 14 15 import ( 16 "fmt" 17 "math/big" 18 19 "github.com/ethereum/go-ethereum/common" 20 ) 21 22 //Genesis散列以强制执行下面的配置。 23 var ( 24 MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") 25 TestnetGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d") 26 RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") 27 ) 28 29 var ( 30 //mainnetchainconfig是在主网络上运行节点的链参数。 31 MainnetChainConfig = &ChainConfig{ 32 ChainID: big.NewInt(1), 33 HomesteadBlock: big.NewInt(1150000), 34 DAOForkBlock: big.NewInt(1920000), 35 DAOForkSupport: true, 36 EIP150Block: big.NewInt(2463000), 37 EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), 38 EIP155Block: big.NewInt(2675000), 39 EIP158Block: big.NewInt(2675000), 40 ByzantiumBlock: big.NewInt(4370000), 41 ConstantinopleBlock: nil, 42 Ethash: new(EthashConfig), 43 } 44 45 //mainnettrustedcheckpoint包含主网络的轻型客户端受信任检查点。 46 MainnetTrustedCheckpoint = &TrustedCheckpoint{ 47 Name: "mainnet", 48 SectionIndex: 208, 49 SectionHead: common.HexToHash("0x5e9f7696c397d9df8f3b1abda857753575c6f5cff894e1a3d9e1a2af1bd9d6ac"), 50 CHTRoot: common.HexToHash("0x954a63134f6897f015f026387c59c98c4dae7b336610ff5a143455aac9153e9d"), 51 BloomRoot: common.HexToHash("0x8006c5e44b14d90d7cc9cd5fa1cb48cf53697ee3bbbf4b76fdfa70b0242500a9"), 52 } 53 54 //testNetChainConfig包含在Ropsten测试网络上运行节点的链参数。 55 TestnetChainConfig = &ChainConfig{ 56 ChainID: big.NewInt(3), 57 HomesteadBlock: big.NewInt(0), 58 DAOForkBlock: nil, 59 DAOForkSupport: true, 60 EIP150Block: big.NewInt(0), 61 EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), 62 EIP155Block: big.NewInt(10), 63 EIP158Block: big.NewInt(10), 64 ByzantiumBlock: big.NewInt(1700000), 65 ConstantinopleBlock: big.NewInt(4230000), 66 Ethash: new(EthashConfig), 67 } 68 69 //TestNetTrustedCheckpoint包含用于Ropsten测试网络的轻型客户端受信任检查点。 70 TestnetTrustedCheckpoint = &TrustedCheckpoint{ 71 Name: "testnet", 72 SectionIndex: 139, 73 SectionHead: common.HexToHash("0x9fad89a5e3b993c8339b9cf2cbbeb72cd08774ea6b71b105b3dd880420c618f4"), 74 CHTRoot: common.HexToHash("0xc815833881989c5d2035147e1a79a33d22cbc5313e104ff01e6ab405bd28b317"), 75 BloomRoot: common.HexToHash("0xd94ee9f3c480858f53ec5d059aebdbb2e8d904702f100875ee59ec5f366e841d"), 76 } 77 78 //rinkebychainconfig包含在rinkeby测试网络上运行节点的链参数。 79 RinkebyChainConfig = &ChainConfig{ 80 ChainID: big.NewInt(4), 81 HomesteadBlock: big.NewInt(1), 82 DAOForkBlock: nil, 83 DAOForkSupport: true, 84 EIP150Block: big.NewInt(2), 85 EIP150Hash: common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"), 86 EIP155Block: big.NewInt(3), 87 EIP158Block: big.NewInt(3), 88 ByzantiumBlock: big.NewInt(1035301), 89 ConstantinopleBlock: big.NewInt(3660663), 90 Clique: &CliqueConfig{ 91 Period: 15, 92 Epoch: 30000, 93 }, 94 } 95 96 //rinkeby trusted checkpoint包含rinkeby测试网络的轻型客户端信任检查点。 97 RinkebyTrustedCheckpoint = &TrustedCheckpoint{ 98 Name: "rinkeby", 99 SectionIndex: 105, 100 SectionHead: common.HexToHash("0xec8147d43f936258aaf1b9b9ec91b0a853abf7109f436a23649be809ea43d507"), 101 CHTRoot: common.HexToHash("0xd92703b444846a3db928e87e450770e5d5cbe193131dc8f7c4cf18b4de925a75"), 102 BloomRoot: common.HexToHash("0xff45a6f807138a2cde0cea0c209d9ce5ad8e43ccaae5a7c41af801bb72a1ef96"), 103 } 104 105 //AllethashProtocolChanges包含所有引入的协议更改(EIP) 106 //并被以太坊核心开发者接受进入了ethash共识。 107 // 108 //此配置有意不使用键字段强制任何人 109 //向配置中添加标志也必须设置这些字段。 110 AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} 111 112 //AllCliqueProtocolChanges包含引入的每个协议更改(EIP) 113 //并被以太坊核心开发者接纳为集团共识。 114 // 115 //此配置有意不使用键字段强制任何人 116 //向配置中添加标志也必须设置这些字段。 117 AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} 118 119 TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil} 120 TestRules = TestChainConfig.Rules(new(big.Int)) 121 ) 122 123 //trustedcheckpoint表示一组后处理的trie根(cht和 124 //与适当的节索引和头散列关联的。它是 125 //用于从此检查点开始灯光同步,并避免下载 126 //整个收割台链,同时仍然能够安全地访问旧的收割台/日志。 127 type TrustedCheckpoint struct { 128 Name string `json:"-"` 129 SectionIndex uint64 `json:"sectionIndex"` 130 SectionHead common.Hash `json:"sectionHead"` 131 CHTRoot common.Hash `json:"chtRoot"` 132 BloomRoot common.Hash `json:"bloomRoot"` 133 } 134 135 //chainconfig是决定区块链设置的核心配置。 136 // 137 //chainconfig以块为单位存储在数据库中。这意味着 138 //任何一个网络,通过它的起源块来识别,都可以有它自己的 139 //一组配置选项。 140 type ChainConfig struct { 141 ChainID *big.Int `json:"chainId"` //chainID标识当前链并用于重播保护 142 143 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` //宅基地开关块(零=无叉,0=已宅基地) 144 145 DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` //道硬叉开关块(零=无叉) 146 DAOForkSupport bool `json:"daoForkSupport,omitempty"` //节点是支持还是反对DAO硬叉 147 148 //EIP150实施天然气价格变化(https://github.com/ethereum/eips/issues/150) 149 EIP150Block *big.Int `json:"eip150Block,omitempty"` //EIP150 HF模块(零=无拨叉) 150 EIP150Hash common.Hash `json:"eip150Hash,omitempty"` //EIP150 HF哈希(仅限于标题客户,因为只有天然气价格发生变化) 151 152 EIP155Block *big.Int `json:"eip155Block,omitempty"` //EIP155高频阻滞 153 EIP158Block *big.Int `json:"eip158Block,omitempty"` //EIP158高频阻滞 154 155 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` //拜占庭开关块(nil=无分叉,0=已在拜占庭) 156 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` //君士坦丁堡开关块(nil=无叉,0=已激活) 157 EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` //ewasm开关块(nil=无分叉,0=已激活) 158 159 //各种共识引擎 160 Ethash *EthashConfig `json:"ethash,omitempty"` 161 Clique *CliqueConfig `json:"clique,omitempty"` 162 } 163 164 //ethashconfig是基于工作证明的密封的共识引擎配置。 165 type EthashConfig struct{} 166 167 //字符串实现Stringer接口,返回共识引擎详细信息。 168 func (c *EthashConfig) String() string { 169 return "ethash" 170 } 171 172 //cliqueconfig是基于权威的密封证明的共识引擎配置。 173 type CliqueConfig struct { 174 Period uint64 `json:"period"` //要强制执行的块之间的秒数 175 Epoch uint64 `json:"epoch"` //重置投票和检查点的epoch长度 176 } 177 178 //字符串实现Stringer接口,返回共识引擎详细信息。 179 func (c *CliqueConfig) String() string { 180 return "clique" 181 } 182 183 //字符串实现fmt.Stringer接口。 184 func (c *ChainConfig) String() string { 185 var engine interface{} 186 switch { 187 case c.Ethash != nil: 188 engine = c.Ethash 189 case c.Clique != nil: 190 engine = c.Clique 191 default: 192 engine = "unknown" 193 } 194 return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Engine: %v}", 195 c.ChainID, 196 c.HomesteadBlock, 197 c.DAOForkBlock, 198 c.DAOForkSupport, 199 c.EIP150Block, 200 c.EIP155Block, 201 c.EIP158Block, 202 c.ByzantiumBlock, 203 c.ConstantinopleBlock, 204 engine, 205 ) 206 } 207 208 //is homestead返回num是否等于homestead块或更大。 209 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 210 return isForked(c.HomesteadBlock, num) 211 } 212 213 //IsDaoFork返回num是否等于或大于dao fork块。 214 func (c *ChainConfig) IsDAOFork(num *big.Int) bool { 215 return isForked(c.DAOForkBlock, num) 216 } 217 218 //ISEIP150返回num是否等于eip150 fork块或更大。 219 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 220 return isForked(c.EIP150Block, num) 221 } 222 223 //ISEIP155返回num是否等于eip155 fork块或更大。 224 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 225 return isForked(c.EIP155Block, num) 226 } 227 228 //ISEIP158返回num是否等于eip158 fork块或更大。 229 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 230 return isForked(c.EIP158Block, num) 231 } 232 233 //IsByzantium返回num是否等于或大于Byzantium fork块。 234 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 235 return isForked(c.ByzantiumBlock, num) 236 } 237 238 //is constantinople返回num是否等于或大于constantinople fork块。 239 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 240 return isForked(c.ConstantinopleBlock, num) 241 } 242 243 //isewasm返回num是否表示ewasm fork之后的块号 244 func (c *ChainConfig) IsEWASM(num *big.Int) bool { 245 return isForked(c.EWASMBlock, num) 246 } 247 248 //Gastable返回与当前阶段(宅基地或宅基地重印)对应的气体表。 249 // 250 //在任何情况下,返回的加斯塔布尔的字段都不应该更改。 251 func (c *ChainConfig) GasTable(num *big.Int) GasTable { 252 if num == nil { 253 return GasTableHomestead 254 } 255 switch { 256 case c.IsConstantinople(num): 257 return GasTableConstantinople 258 case c.IsEIP158(num): 259 return GasTableEIP158 260 case c.IsEIP150(num): 261 return GasTableEIP150 262 default: 263 return GasTableHomestead 264 } 265 } 266 267 //检查兼容检查是否已导入计划的分叉转换 268 //链配置不匹配。 269 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { 270 bhead := new(big.Int).SetUint64(height) 271 272 //迭代checkCompatible以查找最低的冲突。 273 var lasterr *ConfigCompatError 274 for { 275 err := c.checkCompatible(newcfg, bhead) 276 if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { 277 break 278 } 279 lasterr = err 280 bhead.SetUint64(err.RewindTo) 281 } 282 return lasterr 283 } 284 285 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { 286 if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { 287 return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 288 } 289 if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) { 290 return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) 291 } 292 if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport { 293 return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) 294 } 295 if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) { 296 return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 297 } 298 if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) { 299 return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 300 } 301 if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) { 302 return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 303 } 304 if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) { 305 return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 306 } 307 if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { 308 return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 309 } 310 if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { 311 return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 312 } 313 if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) { 314 return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock) 315 } 316 return nil 317 } 318 319 //如果无法将在s1上计划的分叉重新计划为,则IsForkCompatible返回true 320 //阻塞s2,因为头已经过了分叉。 321 func isForkIncompatible(s1, s2, head *big.Int) bool { 322 return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) 323 } 324 325 //isforked返回在块S调度的分叉在给定的头块是否处于活动状态。 326 func isForked(s, head *big.Int) bool { 327 if s == nil || head == nil { 328 return false 329 } 330 return s.Cmp(head) <= 0 331 } 332 333 func configNumEqual(x, y *big.Int) bool { 334 if x == nil { 335 return y == nil 336 } 337 if y == nil { 338 return x == nil 339 } 340 return x.Cmp(y) == 0 341 } 342 343 //如果本地存储的区块链初始化为 344 //可以改变过去的chainconfig。 345 type ConfigCompatError struct { 346 What string 347 //存储和新配置的块编号 348 StoredConfig, NewConfig *big.Int 349 //要更正错误,必须将本地链重绕到的块编号 350 RewindTo uint64 351 } 352 353 func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 354 var rew *big.Int 355 switch { 356 case storedblock == nil: 357 rew = newblock 358 case newblock == nil || storedblock.Cmp(newblock) < 0: 359 rew = storedblock 360 default: 361 rew = newblock 362 } 363 err := &ConfigCompatError{what, storedblock, newblock, 0} 364 if rew != nil && rew.Sign() > 0 { 365 err.RewindTo = rew.Uint64() - 1 366 } 367 return err 368 } 369 370 func (err *ConfigCompatError) Error() string { 371 return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) 372 } 373 374 //规则包装了chainconfig,只是语法上的糖分,也可以用于函数 375 //不包含或不需要有关块的信息的。 376 // 377 //规则是一次性接口,这意味着不应在转换之间使用它 378 //阶段。 379 type Rules struct { 380 ChainID *big.Int 381 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 382 IsByzantium, IsConstantinople bool 383 } 384 385 //规则确保C的chainID不为零。 386 func (c *ChainConfig) Rules(num *big.Int) Rules { 387 chainID := c.ChainID 388 if chainID == nil { 389 chainID = new(big.Int) 390 } 391 return Rules{ 392 ChainID: new(big.Int).Set(chainID), 393 IsHomestead: c.IsHomestead(num), 394 IsEIP150: c.IsEIP150(num), 395 IsEIP155: c.IsEIP155(num), 396 IsEIP158: c.IsEIP158(num), 397 IsByzantium: c.IsByzantium(num), 398 IsConstantinople: c.IsConstantinople(num), 399 } 400 } 401