github.com/klaytn/klaytn@v1.10.2/cmd/homi/genesis/options.go (about) 1 // Copyright 2018 The klaytn Authors 2 // Copyright 2017 AMIS Technologies 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 18 package genesis 19 20 import ( 21 "math/big" 22 "strings" 23 24 "github.com/klaytn/klaytn/cmd/homi/extra" 25 "github.com/klaytn/klaytn/consensus/clique" 26 "github.com/klaytn/klaytn/contracts/reward/contract" 27 "github.com/klaytn/klaytn/log" 28 "github.com/klaytn/klaytn/params" 29 30 "github.com/klaytn/klaytn/blockchain" 31 "github.com/klaytn/klaytn/common" 32 "github.com/klaytn/klaytn/common/hexutil" 33 ) 34 35 type Option func(*blockchain.Genesis) 36 37 var logger = log.NewModuleLogger(log.CMDIstanbul) 38 39 func Validators(addrs ...common.Address) Option { 40 return func(genesis *blockchain.Genesis) { 41 extraData, err := extra.Encode("0x00", addrs) 42 if err != nil { 43 logger.Error("Failed to encode extra data", "err", err) 44 return 45 } 46 genesis.ExtraData = hexutil.MustDecode(extraData) 47 } 48 } 49 50 func ValidatorsOfClique(signers ...common.Address) Option { 51 return func(genesis *blockchain.Genesis) { 52 genesis.ExtraData = make([]byte, clique.ExtraVanity+len(signers)*common.AddressLength+clique.ExtraSeal) 53 for i, signer := range signers { 54 copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) 55 } 56 } 57 } 58 59 func makeGenesisAccount(addrs []common.Address, balance *big.Int) map[common.Address]blockchain.GenesisAccount { 60 alloc := make(map[common.Address]blockchain.GenesisAccount) 61 for _, addr := range addrs { 62 alloc[addr] = blockchain.GenesisAccount{Balance: balance} 63 } 64 return alloc 65 } 66 67 func Alloc(addrs []common.Address, balance *big.Int) Option { 68 return func(genesis *blockchain.Genesis) { 69 alloc := makeGenesisAccount(addrs, balance) 70 genesis.Alloc = alloc 71 } 72 } 73 74 func AllocWithPrecypressContract(addrs []common.Address, balance *big.Int) Option { 75 return func(genesis *blockchain.Genesis) { 76 alloc := makeGenesisAccount(addrs, balance) 77 alloc[common.HexToAddress(contract.CypressCreditContractAddress)] = blockchain.GenesisAccount{ 78 Code: common.FromHex(CypressCreditBin), 79 Balance: big.NewInt(0), 80 } 81 alloc[common.HexToAddress(contract.AddressBookContractAddress)] = blockchain.GenesisAccount{ 82 Code: common.FromHex(PreCypressAddressBookBin), 83 Balance: big.NewInt(0), 84 } 85 genesis.Alloc = alloc 86 } 87 } 88 89 func AllocWithCypressContract(addrs []common.Address, balance *big.Int) Option { 90 return func(genesis *blockchain.Genesis) { 91 alloc := makeGenesisAccount(addrs, balance) 92 alloc[common.HexToAddress(contract.CypressCreditContractAddress)] = blockchain.GenesisAccount{ 93 Code: common.FromHex(CypressCreditBin), 94 Balance: big.NewInt(0), 95 } 96 alloc[common.HexToAddress(contract.AddressBookContractAddress)] = blockchain.GenesisAccount{ 97 Code: common.FromHex(CypressAddressBookBin), 98 Balance: big.NewInt(0), 99 } 100 genesis.Alloc = alloc 101 } 102 } 103 104 func AllocWithPrebaobabContract(addrs []common.Address, balance *big.Int) Option { 105 return func(genesis *blockchain.Genesis) { 106 alloc := makeGenesisAccount(addrs, balance) 107 alloc[common.HexToAddress(contract.AddressBookContractAddress)] = blockchain.GenesisAccount{ 108 Code: common.FromHex(PrebaobabAddressBookBin), 109 Balance: big.NewInt(0), 110 } 111 genesis.Alloc = alloc 112 } 113 } 114 115 func AllocWithBaobabContract(addrs []common.Address, balance *big.Int) Option { 116 return func(genesis *blockchain.Genesis) { 117 alloc := makeGenesisAccount(addrs, balance) 118 alloc[common.HexToAddress(contract.AddressBookContractAddress)] = blockchain.GenesisAccount{ 119 Code: common.FromHex(BaobabAddressBookBin), 120 Balance: big.NewInt(0), 121 } 122 genesis.Alloc = alloc 123 } 124 } 125 126 // Patch the hardcoded line in AddressBook.sol:constructContract(). 127 func PatchAddressBook(addr common.Address) Option { 128 return func(genesis *blockchain.Genesis) { 129 contractAddr := common.HexToAddress(contract.AddressBookContractAddress) 130 contractAccount, ok := genesis.Alloc[contractAddr] 131 if !ok { 132 log.Fatalf("No AddressBook to patch") 133 } 134 135 codeHex := hexutil.Encode(contractAccount.Code) 136 var oldAddr string 137 switch codeHex { 138 case CypressAddressBookBin: 139 oldAddr = "854ca8508c8be2bb1f3c244045786410cb7d5d0a" 140 case BaobabAddressBookBin: 141 oldAddr = "88bb3838aa0a140acb73eeb3d4b25a8d3afd58d4" 142 case PreCypressAddressBookBin, PrebaobabAddressBookBin: 143 oldAddr = "fe1ffd5293fc94857a33dcd284fe82bc106be4c7" 144 } 145 146 // The hardcoded address appears exactly once, hence Replace(.., 1) 147 newAddr := strings.ToLower(addr.Hex()[2:]) 148 codeHex = strings.Replace(codeHex, oldAddr, newAddr, 1) 149 150 genesis.Alloc[contractAddr] = blockchain.GenesisAccount{ 151 Code: common.FromHex(codeHex), 152 Balance: contractAccount.Balance, 153 } 154 } 155 } 156 157 func AddressBookMock() Option { 158 return func(genesis *blockchain.Genesis) { 159 contractAddr := common.HexToAddress(contract.AddressBookContractAddress) 160 contractAccount, ok := genesis.Alloc[contractAddr] 161 if !ok { 162 log.Fatalf("No AddressBook to patch") 163 } 164 165 code := contract.AddressBookMockBinRuntime 166 genesis.Alloc[contractAddr] = blockchain.GenesisAccount{ 167 Code: common.FromHex(code), 168 Balance: contractAccount.Balance, 169 } 170 } 171 } 172 173 func ChainID(chainID *big.Int) Option { 174 return func(genesis *blockchain.Genesis) { 175 genesis.Config.ChainID = chainID 176 } 177 } 178 179 func UnitPrice(price uint64) Option { 180 return func(genesis *blockchain.Genesis) { 181 genesis.Config.UnitPrice = price 182 } 183 } 184 185 func Istanbul(config *params.IstanbulConfig) Option { 186 return func(genesis *blockchain.Genesis) { 187 genesis.Config.Istanbul = config 188 } 189 } 190 191 func DeriveShaImpl(impl int) Option { 192 return func(genesis *blockchain.Genesis) { 193 genesis.Config.DeriveShaImpl = impl 194 } 195 } 196 197 func Governance(config *params.GovernanceConfig) Option { 198 return func(genesis *blockchain.Genesis) { 199 genesis.Config.Governance = config 200 } 201 } 202 203 func Clique(config *params.CliqueConfig) Option { 204 return func(genesis *blockchain.Genesis) { 205 genesis.Config.Clique = config 206 } 207 } 208 209 func StakingInterval(interval uint64) Option { 210 return func(genesis *blockchain.Genesis) { 211 genesis.Config.Governance.Reward.StakingUpdateInterval = interval 212 } 213 } 214 215 func ProposerInterval(interval uint64) Option { 216 return func(genesis *blockchain.Genesis) { 217 genesis.Config.Governance.Reward.ProposerUpdateInterval = interval 218 } 219 }