github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/core/genesis.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"io"
    23  	"io/ioutil"
    24  	"math/big"
    25  	"strings"
    26  
    27  	"github.com/ethereum/go-ethereum/common"
    28  	"github.com/ethereum/go-ethereum/core/state"
    29  	"github.com/ethereum/go-ethereum/core/types"
    30  	"github.com/ethereum/go-ethereum/logger"
    31  	"github.com/ethereum/go-ethereum/logger/glog"
    32  	"github.com/ethereum/go-ethereum/params"
    33  )
    34  
    35  // WriteGenesisBlock writes the genesis block to the database as block number 0
    36  func WriteGenesisBlock(chainDb common.Database, reader io.Reader) (*types.Block, error) {
    37  	contents, err := ioutil.ReadAll(reader)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	var genesis struct {
    43  		Nonce      string
    44  		Timestamp  string
    45  		ParentHash string
    46  		ExtraData  string
    47  		GasLimit   string
    48  		Difficulty string
    49  		Mixhash    string
    50  		Coinbase   string
    51  		Alloc      map[string]struct {
    52  			Code    string
    53  			Storage map[string]string
    54  			Balance string
    55  		}
    56  	}
    57  
    58  	if err := json.Unmarshal(contents, &genesis); err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	statedb := state.New(common.Hash{}, chainDb)
    63  	for addr, account := range genesis.Alloc {
    64  		address := common.HexToAddress(addr)
    65  		statedb.AddBalance(address, common.String2Big(account.Balance))
    66  		statedb.SetCode(address, common.Hex2Bytes(account.Code))
    67  		for key, value := range account.Storage {
    68  			statedb.SetState(address, common.HexToHash(key), common.HexToHash(value))
    69  		}
    70  	}
    71  	statedb.SyncObjects()
    72  
    73  	difficulty := common.String2Big(genesis.Difficulty)
    74  	block := types.NewBlock(&types.Header{
    75  		Nonce:      types.EncodeNonce(common.String2Big(genesis.Nonce).Uint64()),
    76  		Time:       common.String2Big(genesis.Timestamp),
    77  		ParentHash: common.HexToHash(genesis.ParentHash),
    78  		Extra:      common.FromHex(genesis.ExtraData),
    79  		GasLimit:   common.String2Big(genesis.GasLimit),
    80  		Difficulty: difficulty,
    81  		MixDigest:  common.HexToHash(genesis.Mixhash),
    82  		Coinbase:   common.HexToAddress(genesis.Coinbase),
    83  		Root:       statedb.Root(),
    84  	}, nil, nil, nil)
    85  	block.Td = difficulty
    86  
    87  	if block := GetBlockByHash(chainDb, block.Hash()); block != nil {
    88  		glog.V(logger.Info).Infoln("Genesis block already in chain. Writing canonical number")
    89  		err := WriteCanonNumber(chainDb, block)
    90  		if err != nil {
    91  			return nil, err
    92  		}
    93  		return block, nil
    94  	}
    95  
    96  	statedb.Sync()
    97  
    98  	err = WriteBlock(chainDb, block)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	err = WriteHead(chainDb, block)
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  
   107  	return block, nil
   108  }
   109  
   110  // GenesisBlockForTesting creates a block in which addr has the given wei balance.
   111  // The state trie of the block is written to db.
   112  func GenesisBlockForTesting(db common.Database, addr common.Address, balance *big.Int) *types.Block {
   113  	statedb := state.New(common.Hash{}, db)
   114  	obj := statedb.GetOrNewStateObject(addr)
   115  	obj.SetBalance(balance)
   116  	statedb.SyncObjects()
   117  	statedb.Sync()
   118  	block := types.NewBlock(&types.Header{
   119  		Difficulty: params.GenesisDifficulty,
   120  		GasLimit:   params.GenesisGasLimit,
   121  		Root:       statedb.Root(),
   122  	}, nil, nil, nil)
   123  	block.Td = params.GenesisDifficulty
   124  	return block
   125  }
   126  
   127  func WriteGenesisBlockForTesting(db common.Database, addr common.Address, balance *big.Int) *types.Block {
   128  	testGenesis := fmt.Sprintf(`{
   129  	"nonce":"0x%x",
   130  	"gasLimit":"0x%x",
   131  	"difficulty":"0x%x",
   132  	"alloc": {
   133  		"0x%x":{"balance":"0x%x"}
   134  	}
   135  }`, types.EncodeNonce(0), params.GenesisGasLimit.Bytes(), params.GenesisDifficulty.Bytes(), addr, balance.Bytes())
   136  	block, _ := WriteGenesisBlock(db, strings.NewReader(testGenesis))
   137  	return block
   138  }
   139  
   140  func WriteTestNetGenesisBlock(chainDb common.Database, nonce uint64) (*types.Block, error) {
   141  	testGenesis := fmt.Sprintf(`{
   142  	"nonce":"0x%x",
   143  	"gasLimit":"0x%x",
   144  	"difficulty":"0x%x",
   145  	"alloc": {
   146  		"0000000000000000000000000000000000000001": {"balance": "1"},
   147  		"0000000000000000000000000000000000000002": {"balance": "1"},
   148  		"0000000000000000000000000000000000000003": {"balance": "1"},
   149  		"0000000000000000000000000000000000000004": {"balance": "1"},
   150  		"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": {"balance": "1606938044258990275541962092341162602522202993782792835301376"},
   151  		"e4157b34ea9615cfbde6b4fda419828124b70c78": {"balance": "1606938044258990275541962092341162602522202993782792835301376"},
   152  		"b9c015918bdaba24b4ff057a92a3873d6eb201be": {"balance": "1606938044258990275541962092341162602522202993782792835301376"},
   153  		"6c386a4b26f73c802f34673f7248bb118f97424a": {"balance": "1606938044258990275541962092341162602522202993782792835301376"},
   154  		"cd2a3d9f938e13cd947ec05abc7fe734df8dd826": {"balance": "1606938044258990275541962092341162602522202993782792835301376"},
   155  		"2ef47100e0787b915105fd5e3f4ff6752079d5cb": {"balance": "1606938044258990275541962092341162602522202993782792835301376"},
   156  		"e6716f9544a56c530d868e4bfbacb172315bdead": {"balance": "1606938044258990275541962092341162602522202993782792835301376"},
   157  		"1a26338f0d905e295fccb71fa9ea849ffa12aaf4": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}
   158  	}
   159  }`, types.EncodeNonce(nonce), params.GenesisGasLimit.Bytes(), params.GenesisDifficulty.Bytes())
   160  	return WriteGenesisBlock(chainDb, strings.NewReader(testGenesis))
   161  }