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
UpgradeCapcan 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 upgradeupgrade-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;
}
Once published, the following changes are not allowed:
- Removing a published module
- Changing the name, arguments, or return type of an existing
publicfunction - 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:
- Search for the upgrade transaction digest
- Open the "Object Changes" section
- 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.
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.