Deploying Move modules in Aptos: turnkey smart contract deployment

Releasing modules to mainnet fails because of haste and fragmented access. We deploy Aptos smart contracts turnkey: build, verification, controlled release, and rollback in one procedure. Our engineers hand over a ready release pipeline to your team so updates ship predictably.

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 Aptos smart contract deployment fails in production

Deploying Move modules to Aptos fails not at the stage of writing logic, but at release.

Locally the module compiles and passes tests, but on the network the transaction is rejected — because the environment configuration, resource account, and publication address have diverged from what is actually deployed.

The node logs won't reveal the cause: the network returns a generic failure code, not the location of the discrepancy.

The second bottleneck is signing key management. When publication is done manually from a local wallet, the private key lives on the developer's machine, and each transaction is signed separately.

When the person responsible changes, there is no one to hand the key over to, rotation turns into downtime, and the release order is restored from someone's memory.

The third is the absence of bytecode verification before publication. The module goes to mainnet without a run on testnet, without comparing the resulting bytecode with the expected one, and without validating access rights.

A module publication error in this mode costs not a rebuild, but an irreversible change to the account state.

And lastly: manual module release leaves no way back. A published module cannot be rolled back — you can only issue a new version, and if the upgrade mechanism was not built in in advance, recovery becomes a separate task. Let's break down how this is closed.

What managed module release provides: build, verification, rollback

Managed release is a pipeline where each version is built from a pinned source, goes through the same set of checks, and reaches mainnet only after confirmation on testnet.

Publishing a package to Aptos is irreversible, so the module version rollback is prepared in advance: the previous version remains operational and is restored via a proven procedure, rather than assembled at the moment of failure.

  • Build in a clean isolated environment: modules are compiled from source without manual edits — any discrepancy between the local and release version is excluded.
  • Build automation on repository changes: the same set of commands produces a reproducible result, and release does not depend on who runs it.
  • Pre-publication checks: static analysis, logic and access rights tests — the share of successful first-time publications grows.
  • Testnet run: the same package goes through key scenarios, including access and limit failures, and behavior matches mainnet.
  • Storage compatibility check: changes to the resource structure are tested for migration so that already created accounts continue to work.
  • Prepared module version rollback: a pinned previous version and a return procedure — recovery takes minutes instead of a rebuild.

Time to release a version is reduced manyfold: manual steps are replaced with reproducible ones.

The class of failures caused by the human factor — an edit in the built artifact, a missed approval, publishing the wrong version — goes away because the pipeline does not let it through.

Module deployment options: comparison of approaches and constraints

In Aptos, a module is published to an account and remains in the network state: publication cannot be canceled, only the code can be replaced on the next upgrade.

Therefore, the deployment mode is chosen not by convenience, but by the structure of the release process — who holds the keys, how many environments are needed, and how often the logic changes after release.

The network adds its own constraints: the account needs a balance for gas, the module size is limited by the protocol, and an upgrade is available only if the upgrade policy was enabled at first publication.

This condition cannot be influenced later — it is fixed at the moment of deployment. Below are three deployment modes and the boundaries of applicability for each.

Mode When it fits Constraints
Direct module publication Single environment, early logic checks, short edit cycle The key remains with the engineer, there is no release history or build reproducibility, rollback is impossible — the new version replaces the code in the same account
Release pipeline A team of several developers, regular releases, test and prod Requires build and signing infrastructure, secure key storage, and running checks before publication
Managed environment Product in production, roles, audit, and environment separation are needed Without an access policy, key rotation, and a separate verification environment it loses its point; maintenance is more complex

In practice, modes are combined: draft builds are published directly to an isolated environment, and only a version that has passed the pipeline goes to production.

The choice is fixed at the design stage — the first deployment determines which upgrades and roles will be available later.

Order of work: from module audit to handover of control

Each stage is closed with a recorded result — we do not start the next step until the previous one is accepted. This way, at any point in the project it is clear what has already been verified and where the work stands.

Below is the route that Aptos smart contract deployment follows: from reading the source code to handing control over to your team.

  1. Module audit. We review the source code: who owns the resources, which functions are public, where state changes, and whether there are rights to mint and burn assets.
  2. Dependency map. We record the links between modules, shared structures, and publication order — an error in the sequence brings down the entire deployment.
  3. Environment design. We determine what is deployed to testnet and what to mainnet, and which parameters change between them: addresses, roles, limits.
  4. Environment setup. We prepare keys and rights, publish modules, initialize state, and verify addresses and links on testnet.
  5. Checks. We run scenarios at boundary values: insufficient rights, repeated call, exceeding limits — before moving to mainnet.
  6. Acceptance. We demonstrate control operations on mainnet and compare the result with the dependency map recorded at the second stage.
  7. Handover of control. We hand over the repository, environment schema, key access policy, and module upgrade procedure.

The result at each step is recorded in writing, so by acceptance you have the full deployment picture, not a set of disconnected transactions.

What we hand over: configurations, schemas, policies, procedures

A project is considered delivered not when the modules are published to mainnet, but when your team can upgrade them without us.

Therefore, along with the code, we hand over artifacts describing environments, rights, and the release procedure: with them, a new engineer joins the project in a day, not a week.

  • Module environment schema — addresses and profiles of the local stand, testnet, and mainnet, the order of module promotion between them, and data synchronization rules.
  • Access policies — owner of the administrative resource, role separation, multisig thresholds, key storage locations, and rotation procedure.
  • Release procedure — module upgrade policy, approval order, publication windows, who signs, and what to do in case of a failed upgrade.
  • Module documentation — purpose, public functions, events, invariants, and dependencies between modules.
  • Configurations — build and publication parameters, pinned profiles, environment variables, reproducible build from a clean environment.
  • Monitoring and alerts — which module events are tracked, which invariants are checked, and who receives a failure signal.
  • Project handover — address registry, access distribution, team training, and a channel for questions after delivery.

These are working documents, not a report for the shelf: the release procedure is used on every upgrade, and the environment schema is used when onboarding a new engineer.

Case: moving module releases to a managed environment

We were approached by a product team releasing Move modules on Aptos: several services, a shared set of modules, and about ten engineers with publication access. Releases were done from local machines, so a version built by one developer could differ from a colleague's version.

How it was

The share of successful publications stayed at about two-thirds: failures came from mismatched profiles, outdated module addresses, and on-the-fly edits. A full release took several hours — most of it went to reconciliation and approval of the release order.

There were more than ten manual steps, and recovery after a failure depended on which engineer was on call and could take a day.

What we changed and what it became

We built a managed environment: testnet and mainnet environments were separated so they no longer intersect, the build was made reproducible, and publication keys were moved from local machines to secure storage with roles.

Each release step became a verifiable command — module address reconciliation, publication order, and compatibility are checked before sending, not after.

The share of successful publications reached 95% and above, release time dropped from several hours to half an hour, and only two manual steps remained — launch and confirmation.

Recovery after a failure is measured in minutes: the log shows at which step the release stopped, and the previous module version is restored predictably. A new engineer performs the first publication on their own, without supervision.

How does module publication differ from package upgrade in Aptos?

Publication and upgrade in Aptos are the same package publication transaction; the only difference is the state of the publisher account.

The first deployment places the module at the account address and creates a resource there with an upgrade policy; each subsequent publication is checked against that state.

If a module with that name already exists at the address, publication fails with an error about an existing module — only an upgrade with the same set of named addresses in the manifest will succeed.

The upgrade policy is chosen once at first deployment; afterward it can only be tightened, up to burning the upgrade right. Therefore, the account structure is designed before publication, not after.

Option When it is needed Constraints
Module publication First deployment, new product, separate copy under another address The module name at the address must be free; the policy is fixed forever
Package upgrade New functions, logic fixes in a running contract An upgrade right on the account is required; changes pass version compatibility checks

Compatibility is checked by the order and types of struct fields, public function signatures, type parameters, and friend declarations.

It is most often lost when changing the named address in the manifest: the compiler sees a new module and issues a second copy of the contract instead of an upgrade. The second common case is removing a public function that other contracts call.

Code and data are stored separately: an upgrade changes the module, but the resources in accounts remain the same.

If the field structure has changed, the old state is read according to the previous layout, so data migration is moved into a separate function and called together with the upgrade.

Our engineers build in compatibility headroom and a rollback scenario in advance — then an upgrade does not turn into reissuing the contract with loss of address and history.

Technical doubts before start: access, rollback, testnet

Engineering teams ask some questions even before the start — the answers determine the role layout and the composition of the first release.

How do we separate access to a module after publication?

We separate roles immediately: the publication account releases modules, the administrative one changes parameters, the operational one performs routine calls. The administrator key goes into multisig with a threshold so that one engineer cannot release a version alone. We hand control over to the customer — we retain a role only for upgrades under the procedure.

What if the new module version turns out to be unsuccessful?

We fix the upgrade policy before first publication: compatible changes pass automatically, incompatible ones require explicit confirmation. The module address does not change, the state remains in place — a return is done by publishing the previous artifact. Therefore, we design resource schemas with headroom for change.

Where do we verify code before mainnet?

The run takes place on testnet with the same policy parameters as on mainnet. Automated tests cover public functions, and we separately check failures: insufficient rights, repeated call, exceeding the computation limit. The artifact that goes to mainnet matches the verified one by checksum.

How do we account for network limits during deployment?

A transaction has a cap on computation and payload size — if exceeded, publication rolls back. We measure consumption on testnet, split heavy operations into packages, and keep budget headroom so that a peak does not turn into a failure.

Let's discuss the task: how the first stage of work is structured

The first thing we do on an inquiry is break the task down to the module level.

Aptos smart contract deployment begins not with code, but with understanding which Move structures and resources will be affected, who owns the publication account, and whether there are modules on the network with the same address.

An error in the address or in the package upgrade policy means that a new version of the contract can no longer be released later.

To make the first stage of work take days rather than weeks, we need the minimum from you:

  • a link to the repository and the branch with the current code;
  • a description of the business logic: what the contract does on call and which states it changes;
  • account details: who publishes, whether multisig is needed;
  • a list of external dependencies — other contracts and data sources;
  • environment constraints: mainnet or testnet, verification requirements;
  • an engineer on your side who will answer questions about the code.

Our part of this stage is a review of the module and dependency structure, a compatibility check with the current network branch, a draft upgrade policy, and an implementation plan with publication order.

The estimate comes as a document: scope of work by blocks, risks and ways to close them, sequence of steps, and the boundary of the first release. This shows where we could break already running contracts and how to avoid that before publication.

Describe the task in free form — we will come back with an estimate and a plan.