Skip to main content

Global Contracts

If you've ever deployed the same contract code to multiple accounts, you’ve likely noticed that each deployment requires you to pay the full storage cost again.

Imagine that you want to deploy the same 500 KB contract to three accounts: each deployment pays 5 NEAR for the storage — a total of 15 NEAR is locked just to hold identical code. Global Contracts eliminates this redundancy by allowing the same contract code to be shared across multiple accounts, so storage cost is paid only once.

In this tutorial you'll learn how to deploy and use a global contract by Account ID or by Hash, depending on your needs.

Global Contract types
  • By Account: an upgradable contract is published globally under a specific account ID.
  • By Hash: an immutable contract is deployed globally and identified by its code hash.

Examples

Let's define two example smart contracts that we can deploy using Global Contracts, and evaluate which alternative (by Account ID or by Hash) is the best for each case.

  • DAO Factory: A tool that allows any user to deploy their own DAO governance instance.
  • NFT Collection Factory: A service that lets users create their own NFT contracts with fixed metadata and royalty values.
Do you need a Global Contract?

Not sure if you need a Global Contract? Check these questions to decide when to use a global contract.

Global Contract by Account ID

For example, let's consider the DAO Factory case.

Since the same contract is deployed many times by end users across different accounts, this clearly meets the threshold where Global Contracts become financially efficient. Also, since upgradeability may be useful down the line (e.g., to patch bugs or extend functionality), it's a great case to use a Global Contract by Account ID.

Global Contract by Hash

Now let's take for example the NFT Collection Factory case.

Since each user deploys the same contract, but once deployed, it should never change (security and immutability are critical), this makes a perfect case to use a Global Contract by Hash.

Deploying a Global Contract

Next, let's see how you can deploy a global contract by Account ID (for the DAO Factory), or by Hash (for the NFT Collection Factory). As stated, Global contracts can be deployed in 2 ways:

Contracts deployed by hash are effectively immutable and cannot be updated. When deployed by account ID the owner can redeploy the contract updating it for all its users.

info

Note that deploying a global contract incurs high storage costs. Tokens are burned to compensate for storing the contract on-chain, unlike regular contracts where tokens are locked based on contract size.

Deployment

Global contracts can be deployed using NEAR CLI or by code using NEAR APIs (JavaScript and Rust).

Since there are two ways to reference a global contract (by account or by hash), the deployment step depends on the type of global contract that you want to store on the blockchain.

The process is similar to deploying a regular contract but deploy-as-global command should be used instead of deploy.

To deploy a global contract by account, you need to use as-global-account-id and pass the source <account_Id> where the contract will be deployed.

near contract deploy-as-global use-file <route_to_wasm> as-global-account-id <account_id> network-config testnet sign-with-keychain send
tip

Check the NEAR API reference documentation for complete code examples.

Usage

Once a global contract has been deployed, it can be attached to any NEAR account using NEAR CLI or by code using NEAR APIs (JavaScript and Rust).

Let’s see how you can reference and use your global contract from another account.

Use near deploy command. Such a contract behaves exactly like a regular contract.

To reference a global contract by account, you need to call the useGlobalContract function and pass the source accountId where the contract was originally deployed.

# Using global contract deployed by <global_contract_account_id> account id
near contract deploy <account_id> use-global-account-id <global_contract_account_id> without-init-call network-config testnet
tip

Check the NEAR API reference documentation for complete code examples.