Voltar para Documentação

Docs Técnicas

On-Chain Module Registry

Base modules (stdlib and custom) live on-chain as regular contract artifacts. A child contract resolves its impl dependencies against the registry at ContractCall time.

O conteúdo abaixo vem das fontes técnicas do repositório e é prerenderizado no site para leitura direta por pessoas, crawlers e agentes.

Base modules (stdlib and custom) live on-chain as regular contract artifacts. A child contract resolves its impl dependencies against the registry at ContractCall time.

Overview

PublishContractArtifact(BasicToken source)   → artifact_id_A
PublishContractArtifact(Ownable source)      → artifact_id_B
PublishContractArtifact(child source)        → artifact_id_C  (stores source only)

InstantiateContract(artifact_id_C)           → contract_id
ContractCall(contract_id, "initialize", …)   # `initialize` is decorated with @construct
  └─ ledger re-parses child source
  └─ resolves BasicToken → artifact_id_A → source
  └─ resolves Ownable    → artifact_id_B → source
  └─ flattens + executes

The child artifact stores its raw source. Flattening happens on every call, not at publish time. Constructor calls follow the same resolution path as ordinary calls; the runtime enforces one-shot @construct execution after the module is flattened.

Publishing A Module

Publish a base module exactly like any other contract. No special flag is needed — any published artifact can be used as a base module:

json
{
  "type": "PublishContractArtifact",
  "name": "std.token.BasicToken",
  "source": "contract BasicToken:\n  storage:\n    total: u128 = 0\n  ..."
}

The name field becomes the canonical registry key. Use the full dotted path (std.token.BasicToken, com.i<institution-uuid-simple>.CreditModule) to avoid collisions.

Naming Convention

| Namespace | Purpose | |-----------|---------| | std.token.* | Stdlib token modules | | std.access.* | Stdlib access control modules | | com.i<institution-uuid-simple>.* | Institution-specific modules | | user.<publisher-address>.* | User-published modules |

The stdlib modules (std.token.BasicToken, std.access.Ownable, std.token.Pausable, std.access.Roles) are bootstrapped by the platform at genesis and are always available.

How The Ledger Resolves Dependencies

At publish time, the ledger resolves every imported canonical name to an immutable artifact and records the artifact ID and code hash in the child artifact. At ContractCall time, the ledger loads those pinned artifacts and rejects any missing or hash-mismatched dependency.

Updating A Base Module

The original publisher may update a non-stdlib canonical name to a new immutable artifact. Existing child artifacts remain pinned to the version they resolved at publish time; newly published children resolve the updated alias. Reserved std.* names are canonical and cannot be remapped.

Institution namespaces use com.i<institution-uuid-simple>.* and may only be registered by the public key recorded for that institution.

Custom Modules

Institutions can publish their own reusable modules:

python
# com.i123e4567e89b12d3a456426614174000.KYCRegistry — published by that institution
contract KYCRegistry:
    storage:
        approved: Map[Address, bool, 8192]

    @tx
    def approve(account: Address):
        require(ctx.caller == self.admin, "only_admin")
        self.approved = map_set(self.approved, account, True)

    @view
    def is_approved(account: Address) -> bool:
        return map_get(self.approved, account)
python
# A child contract from Acme Bank
import com.i123e4567e89b12d3a456426614174000.KYCRegistry

contract AcmeToken impl KYCRegistry:
    ...

Testing With The Rust API

In tests, pass a local closure as the registry instead of hitting the ledger:

rust
use atlas_trea::{parse_contract, resolve_module_sources, compile_contract_with_modules};
use std::collections::BTreeMap;

let basic_token_src = atlas_trea::BASIC_TOKEN_SRC;

let child_src = r#"
    import std.token.BasicToken
    contract MyToken impl BasicToken:
        ...
"#;

let module = parse_contract(child_src)?;

let sources = resolve_module_sources(&module, |path| {
    match path {
        "std.token.BasicToken" => Some(basic_token_src.to_string()),
        _ => None,
    }
})?;

let refs: BTreeMap<String, &str> =
    sources.iter().map(|(k, v)| (k.clone(), v.as_str())).collect();

let compiled = compile_contract_with_modules(child_src, &refs, 1)?;