Smart Contract Documentation (NatSpec)

Without documenting smart contract logic, audits drag on and post-launch changes cost more. We provide turnkey smart contract documentation: we assemble call diagrams, function registries, and description templates so the team and reviewers see the same picture. Logic analysis and audit preparation accelerate dramatically.

Blockchain Development Services

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1376
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1350
  • B2B Advance company logo design
    B2B Advance company logo design
    798
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1088
  • AIDER company logo development
    AIDER company logo development
    1034
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1130

Smart contract documentation: where context is lost

Smart contract documentation captures not syntax but a description of contract logic: why access checks occur before state changes, which data combinations are allowed, and what happens to balances on a repeated call.

Code answers the question "how" but not "why"—and this knowledge is the first thing lost when the person who wrote the contract leaves the project.

While one engineer maintains the contract, the gap is invisible. As soon as the task arises to hand the code over to another contractor or onboard a new team, context reconstruction begins from indirect evidence: variable names, call order, transaction history.

Analyzing someone else's contract without a logic description stretches over weeks, and all that time development stalls: every change requires rechecking the entire contract.

The gap costs most during an audit.

Reviewers check not only code correctness but also alignment with intent: if the intent is not recorded anywhere, contentious points turn into guesses and questions to the author, and some risks remain outside the report—there is nothing to compare expected behavior against.

Edits after such analysis are made blindly: the engineer either does not touch the function at all or touches an invariant that no one documented.

This is closed by documentation discipline: comments live next to the code, change with it, and are reviewed alongside logic. We examine how such documentation is structured.

What changes after documentation: edits, audit, releases

Smart contract documentation changes not reporting but the timeline of work on it. While logic lives in the author's head, every new engineer reconstructs connections between contracts from code, and the reviewer reconstructs them from questions to the team.

After documentation, the same operations follow a ready specification: function purpose, parameters, role permissions, and invariants are recorded next to the code.

What we measure Without documentation With documentation
Onboarding a new engineer into a module 2–3 weeks to understand connections 3–5 days until first edit
Re-check after changes full cycle again targeted review of changed functions
Release of an update gathering context from code author edit by specification, review by change list
Incident analysis reconstructing logic from code lookup by function purpose

This rests on three things. Specification comments per the NatSpec standard for each public function—purpose, arguments, return values, events; from them human-readable documentation is assembled as a single artifact.

Second—recorded roles and invariants: who is allowed to call a method and which states are unacceptable. Third—check in the build: a function without documentation halts the release, so documentation does not lag behind code.

A separate effect is repeat audit. The reviewer does not need to rediscover the intent: they compare behavior with the specification and immediately see whether it changed together with the code.

Therefore a change in the contract and a change in the documentation are one change, not two tasks separated in time.

Documentation formats: comments, registries, autogeneration

Contract documentation lives in one of three places, and this determines whether it becomes outdated or remains reliable.

Comments in code are read by whoever opens the source, an external registry by the analyst and auditor, and autogeneration builds a reference from code and keeps both audiences on a single source of truth.

Option When it fits Limitations
Comments in code per NatSpec One contract, small team, logic changes often Documentation is unavailable to those without repository access; the format is not checked until generation is enabled
External documentation registry Multiple contracts, requirements change separately from code Diverges from code at the first release without a synchronization procedure; versions are maintained manually
Autogeneration of a reference from code Public protocol, external integrators, audit Covers only what is documented in code; texts for non-technical readers are written separately

The working combination is markup in code as the single source, reference build on every release, and an external registry only for scenarios and roles. Then a logic change and a documentation change land in one change, and divergence is caught during review, not during audit.

Stages of smart contract documentation and checks

Divergence between documentation and code is the most expensive documentation defect: an integrator reads one thing, the contract does another, and you have to sort it out on a live network.

That is why our stages of smart contract documentation are structured as an engineering process with a check at every step, not as a one-time comment edit. Below is the workflow every contract goes through before handover to the client.

  1. Function inventory. We assemble the complete external interface: public and external methods, receiving funds, events, modifiers, calls to other contracts. The output is a list of everything that requires documentation at all, with no omissions.
  2. Standard-based markup. For each function and event, we write the user-facing purpose, an engineer-facing explanation, parameters, return values, and failure conditions. The wording is about the meaning of the operation, not a retelling of the code.
  3. Verification of documentation against behavior. We run scenarios on a test network, trace calls, and compare actual effects with what is written: state changes, fund transfers, role restrictions, value bounds. A divergence is either a text error or a logic defect.
  4. Recording invariants and risks. We separately mark irreversible operations, pause points, limits, and what is prohibited from being done with the contract. This is the part most often lost during handover.
  5. Handover of documentation. We assemble the document next to the code, walk through it with the client's team, and answer questions on each method—so the documentation is read, not filed away.
  6. Maintaining currency. We agree on a rule: a logic change without updated documentation does not pass review before release.

Call graphs, update procedures, documentation templates

We assemble the documentation package so that an engineer who did not participate in development can pick it up and deploy the contract without messaging us. Below is what remains with you after delivery and lives together with the code, not separately from it.

  • Contract call graph — a graph of external and internal calls: who calls each function, which events are recorded, where the branching points are, and where external dependencies lead.
  • Role matrix — a "role → function → permissions → consequences of error" table: it shows who is granted access to issue, pause, and change parameters, and exactly what breaks when used incorrectly.
  • Documentation templates — NatSpec block templates: contract purpose, parameters and return values, invariants, limitations, examples of correct calls.
  • Documentation update procedure — a rule under which a logic edit and a documentation edit are one change; divergence is considered a defect and blocks branch merge.
  • Version binding — documentation references the deployed contract address and release tag, so an outdated document is not passed off as current.
  • Pre-deployment checklist — whether public functions are covered by documentation, whether the role matrix is updated, whether the call graph matches actual dependencies.
  • Divergence log — where found mismatches between code and documentation are recorded and who is responsible for closing them.

When the contractor changes, the package goes to the new team in full—onboarding into the code takes days, not weeks.

Case study: documenting logic before audit and release

The project is a protocol with payout distribution and a role-based access model being prepared for an external audit.

There was no documentation for the contracts, and code remained the only source of truth: at the start, auditors asked about forty clarifying questions, and each explanation had to be assembled anew—reconstructing the logic of one module took up to three weeks.

What we did

We broke the contracts down by layers and documented every external method in NatSpec: purpose, parameters, value bounds, events, and failure conditions.

In a separate document we recorded invariants—what must remain true after any operation, who can access administrative calls, and how roles are transferred.

Next to it we placed a state diagram and a "business requirement — contract function" table so the reviewer could see the connection between code and intent instead of reconstructing it from guesses.

Metrics before and after

The audit proceeded by comparison with the document, not by questioning the team. The number of clarifying questions from auditors dropped from about forty to six—they concerned no longer the purpose of the code but contentious points in the economics.

Edits based on comments took two days instead of two weeks: the developer did not have to reconstruct the module context; they opened the method documentation and edited only it.

The re-check of changed sections passed without new questions—behavior was documented before the edit, not after.

How does NatSpec differ from external documentation?

NatSpec is comments directly in the code that the Solidity compiler reads. They are tied to a specific function, event, or contract: purpose, parameters, return values, side effects.

Annotations such as @notice and @param go through the build, so they do not diverge from the implementation—when the signature changes, the divergence surfaces at compile time, not for the user.

External documentation answers different questions: why the contract exists, what roles and permissions it has, how it connects to the rest of the system, and which scenarios it supports. This is the architecture and product level—read by the team, auditor, and client. You cannot put that into source code: a different scope and a different audience.

Reference generation links these layers: the technical part—a list of functions, events, and errors with descriptions—is assembled from NatSpec, and the external document references it.

The developer gets the signature next to the implementation; the client gets a description of the logic without reading the source.

The practical rule is simple: everything the compiler can verify, we keep in NatSpec, while the meaning and connections between contracts go in external documentation. Then during refactoring you do not have to manually reconcile two sources.

Common technical doubts about documenting logic

Doubts about contract documentation usually come down to three things: the contract is already deployed, the source code is incomplete, and there is no one to maintain the documentation. We examine each case—the answer determines whether it is worth starting the work at all.

The contract is already deployed—is it too late to document?

No. The logic is reconstructed from bytecode, call signatures, and event logs, and the documentation is created as a separate artifact next to the contract address and implementation address.

The code itself is not rewritten: the documentation records actual behavior, and divergences from expectations are marked directly in the text.

What should be done with lost source code?

Reconstruct from facts, not guesses. Available methods, events, and checks are extracted from the deployed code, and ambiguous branches are honestly marked as unconfirmed.

For critical places—payouts, administrator rights, limits—the documentation is supplemented with the results of test calls on a test network.

How should documentation be maintained going forward?

Documentation in NatSpec format lives in the same repository as the code and is updated by the same edit. A new function without documentation does not pass review, and before a contract update the text and behavior are checked to match. Then documentation does not lag behind code by several releases.

Let's discuss the task: documenting logic for your project

The first analysis is needed so that the work plan and estimate are based on facts, not assumptions. We look at how contract state is structured, who changes what in it, and in what form the documentation should reach integrators, auditors, and your team.

  • Trust boundaries: which addresses and roles are allowed to call functions and what happens if the wrong actor calls a function.
  • External dependencies: calls to other contracts, oracles, bridges—and how the logic behaves when they are unavailable or return unexpected data.
  • Events and return values: whether they are sufficient for monitoring the system and analyzing incidents, and whether they are unambiguous.
  • Invariants: sums, limits, order of state changes, withdrawal rights—what must hold under any scenario.
  • Current state of documentation: where comments diverge from code, and which functions and modifiers are not documented at all.
  • Audience for the documentation: an audit review, instructions for integrators, or project handover for support.
  • Output format: NatSpec annotations in code, assembly of general documentation, change history by version.

After the analysis, we will return with a work plan and estimate: how many descriptions need to be added, in what order, and how we will verify that the text has not diverged from the code.

To discuss the task, a link to the contract export and a short description of what already exists are enough.