github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/cmd/util/ledger/migrations/change_contract_code_migration.go (about) 1 package migrations 2 3 import ( 4 "fmt" 5 6 "github.com/onflow/cadence/runtime/common" 7 coreContracts "github.com/onflow/flow-core-contracts/lib/go/contracts" 8 "github.com/rs/zerolog" 9 10 "github.com/onflow/flow-go/cmd/util/ledger/reporters" 11 evm "github.com/onflow/flow-go/fvm/evm/stdlib" 12 "github.com/onflow/flow-go/fvm/systemcontracts" 13 "github.com/onflow/flow-go/model/flow" 14 ) 15 16 func NewSystemContractChange( 17 systemContract systemcontracts.SystemContract, 18 newContractCode []byte, 19 ) StagedContract { 20 return StagedContract{ 21 Address: common.Address(systemContract.Address), 22 Contract: Contract{ 23 Name: systemContract.Name, 24 Code: newContractCode, 25 }, 26 } 27 } 28 29 type EVMContractChange uint8 30 31 const ( 32 EVMContractChangeNone EVMContractChange = iota 33 EVMContractChangeDeploy 34 EVMContractChangeUpdate 35 ) 36 37 type BurnerContractChange uint8 38 39 const ( 40 BurnerContractChangeNone BurnerContractChange = iota 41 BurnerContractChangeDeploy 42 BurnerContractChangeUpdate 43 ) 44 45 func BurnerAddressForChain(chainID flow.ChainID) flow.Address { 46 47 systemContracts := systemcontracts.SystemContractsForChain(chainID) 48 serviceAccountAddress := systemContracts.FlowServiceAccount.Address 49 fungibleTokenAddress := systemContracts.FungibleToken.Address 50 51 switch chainID { 52 case flow.Mainnet, flow.Testnet: 53 return fungibleTokenAddress 54 55 case flow.Emulator, flow.Localnet: 56 return serviceAccountAddress 57 58 default: 59 panic(fmt.Errorf("unsupported chain ID: %s", chainID)) 60 } 61 } 62 63 func SystemContractChanges(chainID flow.ChainID, options SystemContractsMigrationOptions) []StagedContract { 64 systemContracts := systemcontracts.SystemContractsForChain(chainID) 65 66 env := systemContracts.AsTemplateEnv() 67 env.BurnerAddress = BurnerAddressForChain(chainID).Hex() 68 69 switch chainID { 70 case flow.Mainnet: 71 env.StakingCollectionAddress = "0x8d0e87b65159ae63" 72 env.StakingProxyAddress = "0x62430cf28c26d095" 73 74 case flow.Testnet: 75 env.StakingCollectionAddress = "0x95e019a17d0e23d7" 76 env.StakingProxyAddress = "0x7aad92e5a0715d21" 77 78 case flow.Emulator, flow.Localnet: 79 env.StakingCollectionAddress = env.ServiceAccountAddress 80 env.StakingProxyAddress = env.ServiceAccountAddress 81 82 default: 83 panic(fmt.Errorf("unsupported chain ID: %s", chainID)) 84 } 85 86 env.LockedTokensAddress = env.StakingCollectionAddress 87 88 contractChanges := []StagedContract{ 89 // epoch related contracts 90 NewSystemContractChange( 91 systemContracts.Epoch, 92 coreContracts.FlowEpoch( 93 env, 94 ), 95 ), 96 NewSystemContractChange( 97 systemContracts.IDTableStaking, 98 coreContracts.FlowIDTableStaking( 99 env, 100 ), 101 ), 102 NewSystemContractChange( 103 systemContracts.ClusterQC, 104 coreContracts.FlowQC(), 105 ), 106 NewSystemContractChange( 107 systemContracts.DKG, 108 coreContracts.FlowDKG(), 109 ), 110 111 // service account related contracts 112 NewSystemContractChange( 113 systemContracts.FlowServiceAccount, 114 coreContracts.FlowServiceAccount( 115 env, 116 ), 117 ), 118 NewSystemContractChange( 119 systemContracts.NodeVersionBeacon, 120 coreContracts.NodeVersionBeacon(), 121 ), 122 NewSystemContractChange( 123 systemContracts.RandomBeaconHistory, 124 coreContracts.RandomBeaconHistory(), 125 ), 126 NewSystemContractChange( 127 systemContracts.FlowStorageFees, 128 coreContracts.FlowStorageFees( 129 env, 130 ), 131 ), 132 { 133 Address: common.Address(flow.HexToAddress(env.StakingCollectionAddress)), 134 Contract: Contract{ 135 Name: "FlowStakingCollection", 136 Code: coreContracts.FlowStakingCollection(env), 137 }, 138 }, 139 { 140 Address: common.Address(flow.HexToAddress(env.StakingProxyAddress)), 141 Contract: Contract{ 142 Name: "StakingProxy", 143 Code: coreContracts.FlowStakingProxy(), 144 }, 145 }, 146 { 147 Address: common.Address(flow.HexToAddress(env.LockedTokensAddress)), 148 Contract: Contract{ 149 Name: "LockedTokens", 150 Code: coreContracts.FlowLockedTokens(env), 151 }, 152 }, 153 154 // token related contracts 155 NewSystemContractChange( 156 systemContracts.FlowFees, 157 coreContracts.FlowFees( 158 env, 159 ), 160 ), 161 NewSystemContractChange( 162 systemContracts.FlowToken, 163 coreContracts.FlowToken( 164 env, 165 ), 166 ), 167 NewSystemContractChange( 168 systemContracts.FungibleToken, 169 coreContracts.FungibleToken( 170 env, 171 ), 172 ), 173 { 174 Address: common.Address(flow.HexToAddress(env.FungibleTokenMetadataViewsAddress)), 175 Contract: Contract{ 176 Name: "FungibleTokenMetadataViews", 177 Code: coreContracts.FungibleTokenMetadataViews(env), 178 }, 179 }, 180 181 // NFT related contracts 182 NewSystemContractChange( 183 systemContracts.NonFungibleToken, 184 coreContracts.NonFungibleToken( 185 env, 186 ), 187 ), 188 NewSystemContractChange( 189 systemContracts.MetadataViews, 190 coreContracts.MetadataViews( 191 env, 192 ), 193 ), 194 NewSystemContractChange( 195 systemContracts.ViewResolver, 196 coreContracts.ViewResolver(), 197 ), 198 } 199 200 switch chainID { 201 case flow.Emulator, flow.Localnet: 202 // skip 203 204 default: 205 contractChanges = append( 206 contractChanges, 207 StagedContract{ 208 Address: common.Address(flow.HexToAddress(env.FungibleTokenSwitchboardAddress)), 209 Contract: Contract{ 210 Name: "FungibleTokenSwitchboard", 211 Code: coreContracts.FungibleTokenSwitchboard(env), 212 }, 213 }, 214 ) 215 } 216 217 // EVM contract 218 if options.EVM == EVMContractChangeUpdate { 219 contractChanges = append( 220 contractChanges, 221 NewSystemContractChange( 222 systemContracts.EVMContract, 223 evm.ContractCode( 224 systemContracts.NonFungibleToken.Address, 225 systemContracts.FungibleToken.Address, 226 systemContracts.FlowToken.Address, 227 ), 228 ), 229 ) 230 } 231 232 // Burner contract 233 if options.Burner == BurnerContractChangeUpdate { 234 contractChanges = append( 235 contractChanges, 236 StagedContract{ 237 Address: common.Address(flow.HexToAddress(env.BurnerAddress)), 238 Contract: Contract{ 239 Name: "Burner", 240 Code: coreContracts.Burner(), 241 }, 242 }, 243 ) 244 } 245 246 return contractChanges 247 } 248 249 type SystemContractsMigrationOptions struct { 250 StagedContractsMigrationOptions 251 EVM EVMContractChange 252 Burner BurnerContractChange 253 } 254 255 func NewSystemContractsMigration( 256 log zerolog.Logger, 257 rwf reporters.ReportWriterFactory, 258 options SystemContractsMigrationOptions, 259 ) *StagedContractsMigration { 260 migration := NewStagedContractsMigration( 261 "SystemContractsMigration", 262 "system-contracts-migration", 263 log, 264 rwf, 265 options.StagedContractsMigrationOptions, 266 ) 267 for _, change := range SystemContractChanges(options.ChainID, options) { 268 migration.registerContractChange(change) 269 } 270 return migration 271 }