github.com/koko1123/flow-go-1@v0.29.6/fvm/systemcontracts/system_contracts.go (about)

     1  // Package systemcontracts stores canonical address locations for all system
     2  // smart contracts and service events.
     3  //
     4  // System contracts are special smart contracts controlled by the service account,
     5  // a Flow account with special privileges to administer the network.
     6  //
     7  // Service events are special events defined within system contracts which
     8  // are included within execution receipts and processed by the consensus committee
     9  // to enable message-passing to the protocol state.
    10  //
    11  // For transient networks, all system contracts can be deployed to the service
    12  // account. For long-lived networks, system contracts are spread across several
    13  // accounts for historical reasons.
    14  package systemcontracts
    15  
    16  import (
    17  	"fmt"
    18  
    19  	"github.com/koko1123/flow-go-1/model/flow"
    20  )
    21  
    22  const (
    23  
    24  	// Unqualified names of system smart contracts (not including address prefix)
    25  
    26  	ContractNameEpoch        = "FlowEpoch"
    27  	ContractNameClusterQC    = "FlowClusterQC"
    28  	ContractNameDKG          = "FlowDKG"
    29  	ContractServiceAccount   = "FlowServiceAccount"
    30  	ContractNameFlowFees     = "FlowFees"
    31  	ContractStorageFees      = "FlowStorageFees"
    32  	ContractDeploymentAudits = "FlowContractAudits"
    33  
    34  	// Unqualified names of service events (not including address prefix or contract name)
    35  
    36  	EventNameEpochSetup  = "EpochSetup"
    37  	EventNameEpochCommit = "EpochCommit"
    38  
    39  	//  Unqualified names of service event contract functions (not including address prefix or contract name)
    40  
    41  	ContractServiceAccountFunction_setupNewAccount                            = "setupNewAccount"
    42  	ContractServiceAccountFunction_defaultTokenBalance                        = "defaultTokenBalance"
    43  	ContractServiceAccountFunction_deductTransactionFee                       = "deductTransactionFee"
    44  	ContractServiceAccountFunction_verifyPayersBalanceForTransactionExecution = "verifyPayersBalanceForTransactionExecution"
    45  	ContractStorageFeesFunction_calculateAccountCapacity                      = "calculateAccountCapacity"
    46  	ContractStorageFeesFunction_getAccountsCapacityForTransactionStorageCheck = "getAccountsCapacityForTransactionStorageCheck"
    47  	ContractStorageFeesFunction_defaultTokenAvailableBalance                  = "defaultTokenAvailableBalance"
    48  	ContractDeploymentAuditsFunction_useVoucherForDeploy                      = "useVoucherForDeploy"
    49  )
    50  
    51  // SystemContract represents a system contract on a particular chain.
    52  type SystemContract struct {
    53  	Address flow.Address
    54  	Name    string
    55  }
    56  
    57  // ServiceEvent represents a service event on a particular chain.
    58  type ServiceEvent struct {
    59  	Address      flow.Address
    60  	ContractName string
    61  	Name         string
    62  }
    63  
    64  // QualifiedIdentifier returns the Cadence qualified identifier of the service
    65  // event, which includes the contract name and the event type name.
    66  func (se ServiceEvent) QualifiedIdentifier() string {
    67  	return fmt.Sprintf("%s.%s", se.ContractName, se.Name)
    68  }
    69  
    70  // EventType returns the full event type identifier, including the address, the
    71  // contract name, and the event type name.
    72  func (se ServiceEvent) EventType() flow.EventType {
    73  	return flow.EventType(fmt.Sprintf("A.%s.%s.%s", se.Address, se.ContractName, se.Name))
    74  }
    75  
    76  // SystemContracts is a container for all system contracts on a particular chain.
    77  type SystemContracts struct {
    78  	Epoch     SystemContract
    79  	ClusterQC SystemContract
    80  	DKG       SystemContract
    81  }
    82  
    83  // ServiceEvents is a container for all service events on a particular chain.
    84  type ServiceEvents struct {
    85  	EpochSetup  ServiceEvent
    86  	EpochCommit ServiceEvent
    87  }
    88  
    89  // All returns all service events as a slice.
    90  func (se ServiceEvents) All() []ServiceEvent {
    91  	return []ServiceEvent{
    92  		se.EpochSetup,
    93  		se.EpochCommit,
    94  	}
    95  }
    96  
    97  // SystemContractsForChain returns the system contract configuration for the given chain.
    98  func SystemContractsForChain(chainID flow.ChainID) (*SystemContracts, error) {
    99  	addresses, ok := contractAddressesByChainID[chainID]
   100  	if !ok {
   101  		return nil, fmt.Errorf("unknown chain id (%s)", chainID.String())
   102  	}
   103  
   104  	contracts := &SystemContracts{
   105  		Epoch: SystemContract{
   106  			Address: addresses[ContractNameEpoch],
   107  			Name:    ContractNameEpoch,
   108  		},
   109  		ClusterQC: SystemContract{
   110  			Address: addresses[ContractNameClusterQC],
   111  			Name:    ContractNameClusterQC,
   112  		},
   113  		DKG: SystemContract{
   114  			Address: addresses[ContractNameDKG],
   115  			Name:    ContractNameDKG,
   116  		},
   117  	}
   118  
   119  	return contracts, nil
   120  }
   121  
   122  // ServiceEventsForChain returns the service event confirmation for the given chain.
   123  func ServiceEventsForChain(chainID flow.ChainID) (*ServiceEvents, error) {
   124  	addresses, ok := contractAddressesByChainID[chainID]
   125  	if !ok {
   126  		return nil, fmt.Errorf("unknown chain id (%s)", chainID.String())
   127  	}
   128  
   129  	events := &ServiceEvents{
   130  		EpochSetup: ServiceEvent{
   131  			Address:      addresses[ContractNameEpoch],
   132  			ContractName: ContractNameEpoch,
   133  			Name:         EventNameEpochSetup,
   134  		},
   135  		EpochCommit: ServiceEvent{
   136  			Address:      addresses[ContractNameEpoch],
   137  			ContractName: ContractNameEpoch,
   138  			Name:         EventNameEpochCommit,
   139  		},
   140  	}
   141  
   142  	return events, nil
   143  }
   144  
   145  // contractAddressesByChainID stores the default system smart contract
   146  // addresses for each chain.
   147  var contractAddressesByChainID map[flow.ChainID]map[string]flow.Address
   148  
   149  // Well-known addresses for system contracts on long-running networks.
   150  // For now, all system contracts tracked by this package are deployed to the same
   151  // address (per chain) as the staking contract.
   152  //
   153  // Ref: https://docs.onflow.org/core-contracts/staking-contract-reference/
   154  var (
   155  	// stakingContractAddressMainnet is the address of the FlowIDTableStaking contract on Mainnet
   156  	stakingContractAddressMainnet = flow.HexToAddress("8624b52f9ddcd04a")
   157  	// stakingContractAddressTestnet is the address of the FlowIDTableStaking contract on Testnet
   158  	stakingContractAddressTestnet = flow.HexToAddress("9eca2b38b18b5dfe")
   159  )
   160  
   161  func init() {
   162  	contractAddressesByChainID = make(map[flow.ChainID]map[string]flow.Address)
   163  
   164  	// Main Flow network
   165  	// All system contracts are deployed to the account of the staking contract
   166  	mainnet := map[string]flow.Address{
   167  		ContractNameEpoch:     stakingContractAddressMainnet,
   168  		ContractNameClusterQC: stakingContractAddressMainnet,
   169  		ContractNameDKG:       stakingContractAddressMainnet,
   170  	}
   171  	contractAddressesByChainID[flow.Mainnet] = mainnet
   172  
   173  	// Long-lived test networks
   174  	// All system contracts are deployed to the account of the staking contract
   175  	testnet := map[string]flow.Address{
   176  		ContractNameEpoch:     stakingContractAddressTestnet,
   177  		ContractNameClusterQC: stakingContractAddressTestnet,
   178  		ContractNameDKG:       stakingContractAddressTestnet,
   179  	}
   180  	contractAddressesByChainID[flow.Testnet] = testnet
   181  
   182  	// Sandboxnet test network
   183  	// All system contracts are deployed to the service account
   184  	sandboxnet := map[string]flow.Address{
   185  		ContractNameEpoch:     flow.Sandboxnet.Chain().ServiceAddress(),
   186  		ContractNameClusterQC: flow.Sandboxnet.Chain().ServiceAddress(),
   187  		ContractNameDKG:       flow.Sandboxnet.Chain().ServiceAddress(),
   188  	}
   189  	contractAddressesByChainID[flow.Sandboxnet] = sandboxnet
   190  
   191  	// Transient test networks
   192  	// All system contracts are deployed to the service account
   193  	transient := map[string]flow.Address{
   194  		ContractNameEpoch:     flow.Emulator.Chain().ServiceAddress(),
   195  		ContractNameClusterQC: flow.Emulator.Chain().ServiceAddress(),
   196  		ContractNameDKG:       flow.Emulator.Chain().ServiceAddress(),
   197  	}
   198  	contractAddressesByChainID[flow.Emulator] = transient
   199  	contractAddressesByChainID[flow.Localnet] = transient
   200  	contractAddressesByChainID[flow.BftTestnet] = transient
   201  	contractAddressesByChainID[flow.Benchnet] = transient
   202  
   203  }