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  }