Skip to main content

Upgrade a Package

After publishing a contract, you'll often want to fix a bug or add a feature. Sui's package upgrade mechanism lets you update an existing package. It's straightforward — let's walk through it step by step.


What is UpgradeCap?

When you publish a package with sui client publish, the transaction produces an object called UpgradeCap.

This object is the "key" to upgrading your package.

  • Only the entity holding the UpgradeCap can upgrade the package
  • It can be transferred to someone else, or burned (burning makes the package permanently non-upgradeable)
  • Each upgrade produces a new Package ID (the old package ID continues to work)

When sui client publish succeeds, a file called Published.toml is automatically generated at the project root. It records the UpgradeCap object ID, so you don't need to specify it manually when upgrading.

Committing this file to source control is recommended.

Here's what it looks like:

# Generated by Move
# This file SHOULD be committed to source control

[published.devnet]
chain-id = "3d6c67b7"
published-at = "0x36d821b7..."
original-id = "0xbe356beb..."
version = 1
toolchain-version = "1.68.0"
build-config = { flavor = "sui", edition = "2024" }
upgrade-capability = "0xe569f7ab..."
  • published-at: Current package ID (updated to a new ID on each upgrade)
  • original-id: The package ID from the very first publish (never changes)
  • version: Incremented with each upgrade
  • upgrade-capability: Object ID of the UpgradeCap

Modify the Code

As an example upgrade, let's add a reset function. Add the following to the counter module from L16:

entry fun reset(counter: &mut Counter, _ctx: &mut TxContext) {
counter.value = 0;
}
Upgrade Constraints

Once published, the following changes are not allowed:

  • Removing a published module
  • Changing the name, arguments, or return type of an existing public function
  • Adding, removing, reordering, or modifying fields of an existing struct

That said, you are free to add new functions and structs, or change the internal logic of existing functions.


Run the Upgrade

Once your code changes are ready, run:

sui client upgrade

As long as the active address holds the UpgradeCap, this single command is all you need.


Verify the Upgrade

Check Published.toml

After a successful upgrade, Published.toml is updated automatically:

[published.devnet]
published-at = "0xNEW_PACKAGE_ID..." # ← updated to new package ID
original-id = "0xbe356beb..." # ← unchanged
version = 2 # ← incremented
upgrade-capability = "0xe569f7ab..." # ← unchanged

If published-at shows a new Package ID, the upgrade was successful.

Check in Sui Explorer

You can also verify the upgrade on suiscan.xyz:

  1. Search for the upgrade transaction digest
  2. Open the "Object Changes" section
  3. Confirm a new Package ID appears in the type: "published" entry

This new Package ID is the address of the upgraded package. Use this ID going forward when calling the contract.

tip

The old Package ID continues to work. However, existing client code and dependencies are not automatically updated to the new Package ID. If you want to use the new version, you'll need to update any references to the Package ID.


Great work! You now know how to upgrade a package on Sui. In the advanced course, you'll learn how to interact with contracts programmatically using TypeScript.