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 }