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