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  }