github.com/klaytn/klaytn@v1.12.1/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/blockchain/system" 25 "github.com/klaytn/klaytn/cmd/homi/extra" 26 "github.com/klaytn/klaytn/consensus/clique" 27 "github.com/klaytn/klaytn/contracts/reward/contract" 28 "github.com/klaytn/klaytn/log" 29 "github.com/klaytn/klaytn/params" 30 31 "github.com/klaytn/klaytn/blockchain" 32 "github.com/klaytn/klaytn/common" 33 "github.com/klaytn/klaytn/common/hexutil" 34 ) 35 36 type Option func(*blockchain.Genesis) 37 38 var logger = log.NewModuleLogger(log.CMDIstanbul) 39 40 func Validators(addrs ...common.Address) Option { 41 return func(genesis *blockchain.Genesis) { 42 extraData, err := extra.Encode("0x00", addrs) 43 if err != nil { 44 logger.Error("Failed to encode extra data", "err", err) 45 return 46 } 47 genesis.ExtraData = hexutil.MustDecode(extraData) 48 } 49 } 50 51 func ValidatorsOfClique(signers ...common.Address) Option { 52 return func(genesis *blockchain.Genesis) { 53 genesis.ExtraData = make([]byte, clique.ExtraVanity+len(signers)*common.AddressLength+clique.ExtraSeal) 54 for i, signer := range signers { 55 copy(genesis.ExtraData[32+i*common.AddressLength:], signer[:]) 56 } 57 } 58 } 59 60 func makeGenesisAccount(addrs []common.Address, balance *big.Int) map[common.Address]blockchain.GenesisAccount { 61 alloc := make(map[common.Address]blockchain.GenesisAccount) 62 for _, addr := range addrs { 63 alloc[addr] = blockchain.GenesisAccount{Balance: balance} 64 } 65 return alloc 66 } 67 68 func Alloc(addrs []common.Address, balance *big.Int) Option { 69 return func(genesis *blockchain.Genesis) { 70 alloc := makeGenesisAccount(addrs, balance) 71 genesis.Alloc = alloc 72 } 73 } 74 75 func AllocWithPrecypressContract(addrs []common.Address, balance *big.Int) Option { 76 return func(genesis *blockchain.Genesis) { 77 alloc := makeGenesisAccount(addrs, balance) 78 alloc[common.HexToAddress(contract.CypressCreditContractAddress)] = blockchain.GenesisAccount{ 79 Code: common.FromHex(CypressCreditBin), 80 Balance: big.NewInt(0), 81 } 82 alloc[common.HexToAddress(contract.AddressBookContractAddress)] = blockchain.GenesisAccount{ 83 Code: common.FromHex(PreCypressAddressBookBin), 84 Balance: big.NewInt(0), 85 } 86 genesis.Alloc = alloc 87 } 88 } 89 90 func AllocWithCypressContract(addrs []common.Address, balance *big.Int) Option { 91 return func(genesis *blockchain.Genesis) { 92 alloc := makeGenesisAccount(addrs, balance) 93 alloc[common.HexToAddress(contract.CypressCreditContractAddress)] = blockchain.GenesisAccount{ 94 Code: common.FromHex(CypressCreditBin), 95 Balance: big.NewInt(0), 96 } 97 alloc[common.HexToAddress(contract.AddressBookContractAddress)] = blockchain.GenesisAccount{ 98 Code: common.FromHex(CypressAddressBookBin), 99 Balance: big.NewInt(0), 100 } 101 genesis.Alloc = alloc 102 } 103 } 104 105 func AllocWithPrebaobabContract(addrs []common.Address, balance *big.Int) Option { 106 return func(genesis *blockchain.Genesis) { 107 alloc := makeGenesisAccount(addrs, balance) 108 alloc[common.HexToAddress(contract.AddressBookContractAddress)] = blockchain.GenesisAccount{ 109 Code: common.FromHex(PrebaobabAddressBookBin), 110 Balance: big.NewInt(0), 111 } 112 genesis.Alloc = alloc 113 } 114 } 115 116 func AllocWithBaobabContract(addrs []common.Address, balance *big.Int) Option { 117 return func(genesis *blockchain.Genesis) { 118 alloc := makeGenesisAccount(addrs, balance) 119 alloc[common.HexToAddress(contract.AddressBookContractAddress)] = blockchain.GenesisAccount{ 120 Code: common.FromHex(BaobabAddressBookBin), 121 Balance: big.NewInt(0), 122 } 123 genesis.Alloc = alloc 124 } 125 } 126 127 // Patch the hardcoded line in AddressBook.sol:constructContract(). 128 func PatchAddressBook(addr common.Address) Option { 129 return func(genesis *blockchain.Genesis) { 130 contractAddr := common.HexToAddress(contract.AddressBookContractAddress) 131 contractAccount, ok := genesis.Alloc[contractAddr] 132 if !ok { 133 log.Fatalf("No AddressBook to patch") 134 } 135 136 codeHex := hexutil.Encode(contractAccount.Code) 137 var oldAddr string 138 switch codeHex { 139 case CypressAddressBookBin: 140 oldAddr = "854ca8508c8be2bb1f3c244045786410cb7d5d0a" 141 case BaobabAddressBookBin: 142 oldAddr = "88bb3838aa0a140acb73eeb3d4b25a8d3afd58d4" 143 case PreCypressAddressBookBin, PrebaobabAddressBookBin: 144 oldAddr = "fe1ffd5293fc94857a33dcd284fe82bc106be4c7" 145 } 146 147 // The hardcoded address appears exactly once, hence Replace(.., 1) 148 newAddr := strings.ToLower(addr.Hex()[2:]) 149 codeHex = strings.Replace(codeHex, oldAddr, newAddr, 1) 150 151 genesis.Alloc[contractAddr] = blockchain.GenesisAccount{ 152 Code: common.FromHex(codeHex), 153 Balance: contractAccount.Balance, 154 } 155 } 156 } 157 158 func AddressBookMock() Option { 159 return func(genesis *blockchain.Genesis) { 160 contractAddr := common.HexToAddress(contract.AddressBookContractAddress) 161 contractAccount, ok := genesis.Alloc[contractAddr] 162 if !ok { 163 log.Fatalf("No AddressBook to patch") 164 } 165 166 code := contract.AddressBookMockBinRuntime 167 genesis.Alloc[contractAddr] = blockchain.GenesisAccount{ 168 Code: common.FromHex(code), 169 Balance: contractAccount.Balance, 170 } 171 } 172 } 173 174 func AllocateRegistry(storage map[common.Hash]common.Hash) Option { 175 return func(genesis *blockchain.Genesis) { 176 registryCode := system.RegistryCode 177 registryAddr := system.RegistryAddr 178 179 genesis.Alloc[registryAddr] = blockchain.GenesisAccount{ 180 Code: registryCode, 181 Storage: storage, 182 Balance: big.NewInt(0), 183 } 184 } 185 } 186 187 func RegistryMock() Option { 188 return func(genesis *blockchain.Genesis) { 189 registryMockCode := system.RegistryMockCode 190 registryAddr := system.RegistryAddr 191 192 registry, ok := genesis.Alloc[registryAddr] 193 if !ok { 194 log.Fatalf("No registry to patch") 195 } 196 197 genesis.Alloc[registryAddr] = blockchain.GenesisAccount{ 198 Code: registryMockCode, 199 Storage: registry.Storage, 200 Balance: big.NewInt(0), 201 } 202 } 203 } 204 205 func AllocateKip113(kip113ProxyAddr, kip113LogicAddr common.Address, proxyStorage, logicStorage map[common.Hash]common.Hash) Option { 206 return func(genesis *blockchain.Genesis) { 207 proxyCode := system.ERC1967ProxyCode 208 logicCode := system.Kip113Code 209 210 genesis.Alloc[kip113ProxyAddr] = blockchain.GenesisAccount{ 211 Code: proxyCode, 212 Storage: proxyStorage, 213 Balance: big.NewInt(0), 214 } 215 genesis.Alloc[kip113LogicAddr] = blockchain.GenesisAccount{ 216 Code: logicCode, 217 Storage: logicStorage, 218 Balance: big.NewInt(0), 219 } 220 } 221 } 222 223 func Kip113Mock(kip113LogicAddr common.Address) Option { 224 return func(genesis *blockchain.Genesis) { 225 kip113MockCode := system.Kip113MockCode 226 227 _, ok := genesis.Alloc[kip113LogicAddr] 228 if !ok { 229 log.Fatalf("No kip113 to patch") 230 } 231 232 genesis.Alloc[kip113LogicAddr] = blockchain.GenesisAccount{ 233 Code: kip113MockCode, 234 Balance: big.NewInt(0), 235 } 236 } 237 } 238 239 func ChainID(chainID *big.Int) Option { 240 return func(genesis *blockchain.Genesis) { 241 genesis.Config.ChainID = chainID 242 } 243 } 244 245 func UnitPrice(price uint64) Option { 246 return func(genesis *blockchain.Genesis) { 247 genesis.Config.UnitPrice = price 248 } 249 } 250 251 func Istanbul(config *params.IstanbulConfig) Option { 252 return func(genesis *blockchain.Genesis) { 253 genesis.Config.Istanbul = config 254 } 255 } 256 257 func DeriveShaImpl(impl int) Option { 258 return func(genesis *blockchain.Genesis) { 259 genesis.Config.DeriveShaImpl = impl 260 } 261 } 262 263 func Governance(config *params.GovernanceConfig) Option { 264 return func(genesis *blockchain.Genesis) { 265 genesis.Config.Governance = config 266 } 267 } 268 269 func Clique(config *params.CliqueConfig) Option { 270 return func(genesis *blockchain.Genesis) { 271 genesis.Config.Clique = config 272 } 273 } 274 275 func StakingInterval(interval uint64) Option { 276 return func(genesis *blockchain.Genesis) { 277 genesis.Config.Governance.Reward.StakingUpdateInterval = interval 278 } 279 } 280 281 func ProposerInterval(interval uint64) Option { 282 return func(genesis *blockchain.Genesis) { 283 genesis.Config.Governance.Reward.ProposerUpdateInterval = interval 284 } 285 }