Creating and Deploying Smart Contracts on Sui: A Complete Guide

Publishing and updating packages on Sui often turns into a manual pipeline: releases slip, versions diverge across environments. We set up Sui smart contract deployment end to end — from code audit to handover of the environment to your team. The release cycle is reduced several times over, and updates proceed predictably and without manual edits.

Blockchain Development Services

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1375
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1349
  • B2B Advance company logo design
    B2B Advance company logo design
    794
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1087
  • AIDER company logo development
    AIDER company logo development
    1032
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1129

Why Sui smart contract deployment breaks at publication

Publishing a package is the only operation in a contract's lifecycle that cannot be rolled back. A mistake in permissions or dependencies is noticed only after objects have been created on-chain and the state has diverged from the local copy.

We'll examine Sui smart contract deployment through three failures that recur from project to project.

The first is loss of admin rights. Publication creates an object with upgrade rights, and if it ends up at an address whose key is unavailable, releasing a new version under the same identifier is no longer possible — the package policy prohibits it.

The remedy is reissuing with a new address and migrating state manually: an order of magnitude more expensive than checking rights before publication.

The second is a module version conflict: the package is built against one revision of a dependency, while another is deployed on-chain, and the call fails due to a type mismatch.

The third is manual transfer of configuration between environments: package IDs, object addresses, and network parameters are edited in the manifest from memory, and the test environment stops matching mainnet.

The cost of each such failure is not a rebuild but state divergence and hours spent reconciling it. Next, we'll look at how this is addressed: fixing permissions before publication, pinning dependency revisions, and reproducible configuration transfer between environments.

What changes when contract release stops being manual

A manual release depends on a person: the build, upload to the network, address binding, and permission checks are done from memory and in varying order.

While there are few changes, this goes unnoticed; at scale, non-reproducible builds, publications to the wrong network, and forgotten checks appear — classes of failures that recur with every release.

Managed contract release consolidates this into a single cycle from change to publication. In Sui, a package is published once, and updates go through an upgrade permission — so we build the pipeline around the package version, not around the engineer's actions.

The checklist we use to build the pipeline:

  • A single change path: build, type checking, tests on a local network, review by a second engineer — without ad-hoc steps.
  • Upgrade permissions and addresses are kept in secure storage, with access granted by role.
  • Publication first to the test network, then to mainnet — with the same set of commands.
  • The package version and address are recorded in the publication log: it shows what was released and when.
  • The previous version remains available — rollback does not require rewriting and rebuilding code.

We measure the effect before and after: the cycle from change to publication shrinks from days to a single pass, the share of successful publications grows, and failure classes — wrong network, forgotten check, lost permission — leave the process rather than being treated after release.

Package publication and upgrade methods: comparison

A package in Sui is a set of modules published to an address, and after the first publication object identifiers are no longer rebound.

What exactly is allowed to change afterward is set by the contract upgrade policy in the package manifest: it cannot be loosened later, only tightened. Therefore, the publication mode is chosen at project start, not at release time.

Publication to the test network follows the same path as mainnet: the same policy, the same dependencies, the same deployment checks.

State is not transferred in the process — the package is deployed anew at its address, and data migrations have to be described as a separate scenario.

Option When it fits Restrictions
Immutable package Logic is stable, tested, holds assets Fixes are impossible — only a new address and state migration
Upgradeable, "add-only" policy Product evolves without breaking existing logic Existing signatures and structures cannot be rewritten
Upgradeable, full rights Early stages, internal services, fast iterations The package holder can change logic under live objects
Publication to the test network Rehearsal of policy and migrations before mainnet Separate address, state is not transferred to mainnet

In practice: we fix the policy before publication and design upgradeability so that critical structures do not have to be rewritten as load grows.

Workflow: from code audit to pipeline handover

Sui smart contract deployment is not a single publication command but a chain of stages, each closed with an artifact that can be verified before moving on.

If design is skipped, an error in object ownership rights surfaces on mainnet, when fixing it requires state migration and re-verification of all dependencies.

Work stages

  1. Logic analysis and contract audit. We read the requirements together with your team and fix roles, permissions, and rollback scenarios. The output is a list of invariants the code must hold under any call order, and vulnerability classes addressed at the design stage.
  2. Module scheme design. We structure the logic so that module boundaries match areas of responsibility: state storage separately, access rules separately, computations separately. The scheme is agreed before writing code — a change at this stage is cheaper than rewriting finished modules.
  3. Environment setup. We bring up a local node, a test network, and wallets with separate keys for building and for management. Configurations are versioned so the environment can be reproduced from scratch on any machine.
  4. Implementation and local checks. We run unit tests for every public method, including negative scenarios: wrong owner, repeated call, limit exceeded.
  5. Test network verification. We publish the package, measure resource consumption per operation, run scenarios under load, and check behavior under parallel calls to the same object. The result is a report with transactions and identified boundaries.
  6. Pipeline handover. We deliver the sources, module scheme, publication and upgrade scripts, incident response procedure, and the rollback procedure to the previous version.

Each stage closes with acceptance: without it, the next one does not begin. By launch time, your team already has a working copy of the pipeline and an understanding of how to make changes independently.

Deliverables: configurations, schemes, procedures

A working contract on-chain is only part of the result. Without a description of how it is built, who is allowed to change it, and what to do in case of failure, every update turns into sorting out dependencies from memory.

Therefore, the documentation set is assembled in parallel with the code and handed over with it, rather than being "written later."

  • Package and dependency map: which modules are included in the build, what is connected externally, in what order it is published, and which addresses are already taken.
  • Package and inter-module relationship diagrams — diagrams with entry points that let a new engineer join the project without calls.
  • Environment configurations: profiles for the test network and mainnet, registry addresses, operation limits, build parameters.
  • Access policies: who can upgrade modules and through which keys, which operations require multiple signatures, and how roles are separated.
  • Key management procedure: generation, storage, rotation, and the procedure for restoring access if the owner leaves.
  • Upgrade procedure: the path from a change in a branch to publication, who approves the release, and how to roll back to the previous version.
  • Contract monitoring guide: which events are tracked, which are considered failures, and who receives notifications.

We review each artifact together with your team before handover — questions about the composition are best resolved at this stage. Describe the task, and we will return with an estimate and plan: deployment of Sui smart contracts will stop depending on a single contractor.

Case study: how we shortened the contract release cycle fourfold

Before: release depended on one person

The product: several interconnected contract packages on Sui, a distributed team, and four engineers in different time zones.

Publishing an update took up to three days: builds were launched from local machines, the package upgrade right was held in a single wallet, and the sequence of steps lived in chat.

Every third publication failed — dependency versions diverged, and the contracts had to be rebuilt and published again.

What we changed

We moved the release into an automated build: the same set of steps for everyone, a test network run before mainnet, and pinned dependency versions.

The upgrade right was moved to multisignature — three keys out of five — and the package policy was set to a compatible upgrade mode so that addresses and objects were not recreated with every release.

Tests and static code analysis are now mandatory before publication, and the check results are visible to the whole team.

The result

The release cycle was cut fourfold — from three days to eighteen hours, including checks. The share of successful publications grew from two-thirds to 98%: discrepancies are caught on the test network, not on mainnet.

Upgrade rights are no longer tied to one person — an engineer leaving does not mean losing control over the package, and rolling back to the previous state takes minutes instead of a repeated publication.

What to do if a contract is already deployed in Sui and needs changes?

Published code in Sui is immutable: a contract is deployed as a package object, not as a file on a server, so "edit a couple of lines and reupload" does not work here.

Any logic change goes through the package upgrade procedure, and what is allowed in it is determined by the upgrade policy fixed at the moment of first publication.

The upgrade mode sets the boundary of what is possible: compatible allows adding functions and changing the body of existing ones, but prohibits breaking signatures and removing public interfaces; additive allows only supplementing the package with new modules; dependency-only mode allows only replacing versions of external packages.

If the policy is too narrow from the outset, the only path is publication at a new address, and that already means state migration and switching all integrations to the new contract.

Data lives in objects, not in the package code, so a logic upgrade by itself does not touch state.

But if the field structure has changed, the new code will not read old objects: state migration is needed — parsing the old object, creating a new one with the current structure and a version marker, so that the migration can be run in parts. For shared objects, this is separate work with upgrade rights and a strict call order.

Therefore, the choice of mode is calculated from the scope of changes: fixing a bug in a function body is covered by a standard package upgrade, while changing the data model and public interfaces requires a new version plus migration.

Before any option, we capture the current state, check dependent packages and external callers, and prepare a rollback plan and tests on real data.

The usual workflow is: inventory of interfaces and objects, verification of upgrade rights, selection of the least risky mode, state migration, and decommissioning of the old code.

Describe what is already deployed and what changes are needed — we will return with an estimate and plan.

Common technical doubts before starting

Doubts before starting are usually the same: who holds admin rights, how to ensure the logic is secure, what to do if a bug is found in the new version, and whether the documentation is sufficient.

Below are short answers to each, in the form in which we address them before publishing a contract to Sui mainnet.

Who gets access to admin keys?

We build key management on a threshold signature scheme: a sensitive operation passes only when confirmed by several independent storages, and each party has its own hardware wallet.

No single engineer has full access alone, so compromising one key pair does not allow funds to be withdrawn.

How is contract logic security verified?

Contract security audit takes place before deployment: static analysis, scenarios with object reuse, verification of permissions to call sensitive functions, and a test network run. The output is a report with findings classified by severity and a list of resolved issues.

What happens if a bug is found in the new version?

We choose the upgrade policy before release. For an upgradeable contract, versions are published one at a time, and rolling back a version means returning the previous package without losing accumulated data.

If the contract is immutable, we move the business logic into a separate layer that can be replaced.

How detailed should contract documentation be?

Contract documentation describes the modules and their relationships, roles and the permission matrix, entry points, the new version release procedure, and the incident response procedure.

This is enough for your team to maintain the contract without us, and for a third-party auditor to understand it in one pass.

Let's discuss the task and return with an estimate and plan

For the estimate to be based on facts, we need a minimum of inputs: a description of the contract logic and roles, access to the current code or prototype, a list of scenarios that must work, and requirements for the target network — test or mainnet.

If the contract is already deployed, add the change history and known limitations: this removes half the questions about compatibility and state migration.

The deployment plan comes as a document with stages, timelines, owners, and points where your decision is needed. As a separate section — contract support after launch and the incident response procedure.

The first stage of cooperation includes:

  • analysis of the contract logic and verification of the access rights model for its functions;
  • description of the data storage scheme and an estimate of on-chain operation costs;
  • deployment plan: the sequence of steps from test network to mainnet;
  • upgrade and rollback strategy — how the contract will survive a logic change;
  • a set of automated tests for key scenarios and pre-release checks;
  • support procedure: how requests are handed over and who responds to them;
  • contract documentation and instructions for your team on working with it.

Describe the task in free form and attach what already exists — we will return with a work estimate and a plan for the first step.