Skip to content

Smart contracts

Planned contract architecture: registry, names, royalties, upgrades.

  • 6 min read
  • Page 13 of 24

Asteria's contracts are designed, not deployed. This page documents the planned architecture so that collectors, developers and auditors can review the approach before any code goes live. Everything here may change after the legal review and the security audit.

Token standard
ERC-721
With ERC-2981 royalties and ERC-4906 updates
Network
TBA
EVM-compatible; chosen in Phase 1
Upgradeability
Immutable core
Versioned metadata instead of proxies
Status
Specification draft
Testnet and audit before any launch

Architecture#

The design centres on a single core contract, AsteriaRegistry. It is an ERC-721 token in which every token is one registry entry, with the name registry built in rather than bolted on.

AsteriaRegistry — planned components
AsteriaRegistry
├── ERC-721            token holders and transfers
├── Name registry      tokenId → registry ID, registry name, designation hash
├── ERC-2981           royalty information for marketplaces
├── ERC-4906           metadata-update events
├── Metadata URI       versioned IPFS base URI + registry ID
└── Access control     admin · minter · verifier, held by multisig wallets

Keeping the core small is deliberate. The marketplace, checkout and holder dashboard will live outside it, so they can evolve without touching the contract that records who holds each entry.

The on-chain name registry#

For every token the contract stores a compact entry:

FieldTypePurpose
registryIdstringThe permanent Asteria ID, e.g. ASR-0001
registryNamestringThe Asteria registry name, stored as UTF-8
designationHashbytes32keccak256 of the asteroid's normalised MPC designation; zero until verified
statusenumPending or Verified — a one-way switch

Why a hash for the designation? It is a fixed 32 bytes whatever the designation looks like, and it lets the contract enforce a simple rule: one token per asteroid. Recording a designation hash that is already linked to another token reverts. For a numbered minor planet the hashed value is its permanent number, which never changes — even if the asteroid later receives an official name. Anyone can recompute the hash from the published designation and compare.

Registry names are unique too. Unicode normalisation is impractical on-chain, so the minter computes a normalised name key off-chain (lower case, diacritics removed — see the naming guidelines) and the contract rejects any key it has already seen.

Roles and permissions#

RoleCanHeld by
AdminGrant and revoke roles; set the royalty receiver and rate (within a hard cap); update the metadata base URIA multisig wallet, behind a timelock
MinterMint a token for a verified catalogue entry, once per registry IDA multisig-controlled minting process
VerifierRecord a designation hash and mark an entry VerifiedA separate multisig

Planned safeguards:

  • Multisig everywhere. Each privileged role is held by a multisig wallet that needs several independent signers, each using a hardware wallet. No single person can act alone.
  • Timelock on sensitive changes. Royalty and base-URI changes are queued publicly before they take effect.
  • No custody powers. No role can move, burn or freeze a holder's token, and no role can rewrite a registry name after mint.

Royalties (ERC-2981)#

The contract implements ERC-2981 (opens in a new tab): given a token and a sale price, royaltyInfo returns a receiver address and a royalty amount. The planned rate is described in Fees & royalties; on-chain it is capped by a constant, so it can never be raised past a published maximum.

ERC-2981 is a signal, not an enforcement mechanism. Marketplaces read it and decide for themselves whether to honour it.

Metadata URI strategy#

tokenURI resolves to a base URI plus the registry ID — for example ipfs://<cid>/ASR-0001.json. The base URI points to an IPFS directory, and directories are content-addressed: any change produces a new CID.

  1. Metadata for all entries is published as one versioned directory.
  2. When something changes — a verification, a refined measurement, a new schema version — a complete new directory is published.
  3. The admin multisig queues the new base URI through the timelock.
  4. On execution the contract emits BatchMetadataUpdate, and wallets and marketplaces refresh.

Every previous directory remains a valid, retrievable snapshot. A one-way switch that freezes the base URI permanently, once the catalogue is fully verified, is under consideration.

Upgradeability: an immutable core#

The contract will not sit behind an upgradeable proxy. A proxy lets administrators replace the logic of tokens people already hold, which asks collectors for a great deal of trust and adds attack surface. Instead:

  • The core contract is deployed once and cannot be changed.
  • Everything that legitimately evolves — data, media, schema — lives in versioned metadata.
  • New features are built in separate contracts that read from the core.

The trade-off is that a bug in the core cannot be patched in place. That is why the core is small, why testing comes first, and why a public testnet period and an independent audit precede any launch. If a critical flaw were ever found, the fallback would be an opt-in migration to a new contract, with the original left readable on-chain.

Events#

EventOriginEmitted when
TransferERC-721A token is minted or transferred
Approval, ApprovalForAllERC-721A holder grants transfer permission
EntryRegisteredAsteriaA token is minted with its registry ID and name
DesignationVerifiedAsteriaAn entry's designation hash is recorded
MetadataUpdate, BatchMetadataUpdateERC-4906Metadata for one or many tokens changes
RoyaltyUpdatedAsteriaThe royalty receiver or rate changes
RoleGranted, RoleRevokedAccess controlA privileged role changes hands

Draft interface#

IAsteriaRegistry.sol — draft interface, subject to change
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
 
/// @title  Asteria Registry (DRAFT interface, not deployed)
/// @notice Each token is one entry in the Asteria registry. Tokens are digital
///         collectibles and convey no property right in any celestial body.
interface IAsteriaRegistry /* is IERC721Metadata, IERC2981, IERC4906 */ {
    enum Status { Pending, Verified }
 
    struct Entry {
        string registryId;       // e.g. "ASR-0001"
        string registryName;     // Asteria registry name, not an IAU name
        bytes32 designationHash; // keccak256(normalised MPC designation); 0 until verified
        Status status;
    }
 
    event EntryRegistered(uint256 indexed tokenId, string registryId, string registryName);
    event DesignationVerified(uint256 indexed tokenId, bytes32 designationHash);
    event RoyaltyUpdated(address indexed receiver, uint96 feeBps);
 
    /// MINTER_ROLE. Reverts if the registry ID or name key is already used.
    function mint(
        address to,
        string calldata registryId,
        string calldata registryName,
        bytes32 nameKey
    ) external returns (uint256 tokenId);
 
    /// VERIFIER_ROLE. One-way: Pending -> Verified. Reverts if the hash is already registered.
    function verifyDesignation(uint256 tokenId, bytes32 designationHash) external;
 
    function entryOf(uint256 tokenId) external view returns (Entry memory);
    function tokenOfRegistryId(string calldata registryId) external view returns (uint256);
    function isNameKeyTaken(bytes32 nameKey) external view returns (bool);
 
    /// DEFAULT_ADMIN_ROLE, via timelock. Emits BatchMetadataUpdate.
    function setBaseURI(string calldata newBaseURI) external;
 
    /// DEFAULT_ADMIN_ROLE, via timelock. feeBps must not exceed MAX_ROYALTY_BPS.
    function setRoyalty(address receiver, uint96 feeBps) external;
}

Security and audit plan#

  1. Freeze the specification

    The contract specification is finalised during Phase 1, alongside the legal review and the choice of network.

  2. Build on proven foundations

    The implementation uses widely audited open-source building blocks for ERC-721, ERC-2981 and access control, rather than reinventing them.

  3. Test exhaustively

    Unit tests, fuzzing and invariant tests — for example: one token per registry ID, one token per designation, verification can never be reversed.

  4. Public testnet

    The contracts run on a public testnet with test listings, so anyone can inspect and exercise them. Test tokens have no value.

  5. Independent audit

    A third-party security firm audits the code. The report is published in full, together with the fixes.

  6. Mainnet, verified

    Deployment with verified source code on a block explorer; addresses published here; privileged roles handed to the multisig wallets.

Progress on each step is tracked on the roadmap.

Next steps#