MoveAS Contracts
Move Attestation Service Smart Contracts - Move language contracts for creating, managing, and verifying attestations on Sui and Aptos blockchains.
Overview
MoveAS Contracts provide a comprehensive set of smart contracts for attestation services across multiple Move-based blockchains. The contracts support:
- Schema Registration: Define and register data schemas for attestations
- Attestation Creation: Issue attestations with flexible storage options
- Privacy Protection: Seal encryption integration for sensitive data (Sui only)
- Decentralized Storage: Off-chain storage support via Walrus (Sui only)
- Resolver Pattern: Custom access control and validation logic
- Registry Management: Centralized registries for schemas and attestations
Supported Chains
| Chain | Status | Features |
|---|---|---|
| Sui | Testnet ✅ | On-chain storage, Off-chain storage (Walrus), Seal encryption, Resolver pattern |
| Aptos | Testnet ✅ | On-chain storage, Resolver pattern |
Note: Off-chain storage and Seal encryption are currently only available for Sui.
Sui Attestation Service (SAS)
Architecture
The Sui Attestation Service is built on Sui's object-centric model and supports dual storage mechanisms:
Storage Types
On-Chain Storage (
STORAGE_TYPE_ON_CHAIN = 0)- Data stored directly on-chain
- Fully transparent and verifiable
- Suitable for small data
Off-Chain Storage (
STORAGE_TYPE_OFF_CHAIN = 1)- Data stored in Walrus decentralized storage
- Only metadata and hash stored on-chain
- Supports Seal encryption for privacy protection
- Suitable for large or sensitive data
Core Modules
1. sas::sas
Main entry point for attestation operations.
Key Functions:
register_schema(): Register a new schemaregister_schema_with_resolver(): Register schema with resolver for custom validationattest(): Create on-chain attestationattest_off_chain(): Create off-chain attestation with Walrus storageattest_with_resolver(): Create attestation with resolver validationattest_multi(): Batch create multiple attestationsrevoke(): Revoke an attestationrevoke_with_resolver(): Revoke with resolver validation
Example:
// Register schema
let admin_cap = sas::register_schema(
&mut schema_registry,
schema_bytes,
name_bytes,
description_bytes,
url_bytes,
true, // revokable
ctx
);
// Create on-chain attestation
let attestation_id = sas::attest(
&mut schema_record,
&mut attestation_registry,
@0x0, // ref_attestation
recipient,
expiration_time,
data,
name_bytes,
description_bytes,
url_bytes,
&clock,
ctx
);
// Create off-chain attestation (with Walrus)
let attestation_id = sas::attest_off_chain(
&mut schema_record,
&mut attestation_registry,
@0x0, // ref_attestation
recipient,
expiration_time,
walrus_sui_object_id, // Walrus Sui Object ID
walrus_blob_id, // Walrus Blob ID (base64url as bytes)
data_hash, // Blake2b-256 hash of original data
encrypted, // Whether data is encrypted
seal_nonce, // Option<vector<u8>>: Seal nonce for encrypted data
seal_policy_id, // Option<address>: Seal policy ID (optional)
name_bytes,
description_bytes,
url_bytes,
&clock,
ctx
);2. sas::attestation
Core attestation data structure and operations.
Struct Fields:
storage_type: u8: Storage type identifier (0 = ON_CHAIN, 1 = OFF_CHAIN)data: vector<u8>: On-chain data (used whenstorage_type == ON_CHAIN)walrus_sui_object_id: address: Walrus Sui Object ID (for OFF_CHAIN)walrus_blob_id: vector<u8>: Walrus Blob ID as bytes (for OFF_CHAIN)data_hash: vector<u8>: Blake2b-256 hash of original data (for integrity verification)encrypted: bool: Whether data is encrypted (for OFF_CHAIN)seal_nonce: Option<vector<u8>>: Seal encryption nonce (for encrypted OFF_CHAIN)seal_policy_id: Option<address>: Seal access policy ID (optional)
Key Functions:
create_attestation_on_chain(): Create on-chain attestation (internal)create_attestation_off_chain(): Create off-chain attestation (internal)verify_data_integrity(): Verify data hash matches stored hashis_encrypted(): Check if attestation data is encryptedseal_nonce(): Get Seal nonce for encrypted attestations- Public view functions:
schema(),attestor(),recipient(),time(), etc.
Events:
AttestationCreated: Emitted when a new attestation is created
3. sas::seal_access
Seal access control for encrypted attestations (Private Data pattern).
Key Functions:
compute_key_id(attestor: address, nonce: vector<u8>): vector<u8>- Computes Seal key ID:
[attestor bytes][nonce bytes] - Must match SDK's
computeSealKeyIdfunction - Full Seal ID:
[package_id][attestor][nonce]
- Computes Seal key ID:
seal_approve(id: vector<u8>, attestation: &Attestation)(entry)- Called by Seal key servers to verify access permissions
- Access control: Only the owner of the
Attestationobject (recipient) can call - Validates that Seal ID matches computed key ID:
[attestor][nonce]
Access Control:
- Only the recipient (owner of the Attestation object) can authorize decryption
- Seal key servers verify access by calling
seal_approveviadry_run_transaction_block - Sui's object ownership ensures only the owner can pass the object in a transaction
Example:
// Seal key server verifies access (called via dry_run_transaction_block)
entry public fun seal_approve(
id: vector<u8>, // Seal ID: [attestor][nonce]
attestation: &attestation::Attestation // Must be owned by recipient
) {
assert!(check_policy(id, attestation), ENoAccess);
// If this succeeds, Seal key server will return decryption keys
}4. sas::schema
Schema registration and management.
Key Functions:
new(): Create new schemanew_with_resolver(): Create schema with resolverstart_attest(): Start attestation request (resolver pattern)finish_attest(): Finish attestation request (resolver pattern)start_revoke(): Start revocation request (resolver pattern)finish_revoke(): Finish revocation request (resolver pattern)
Structs:
Schema: Schema data structureResolver: Resolver configuration and rulesResolverBuilder: Builder for creating resolversRequest: Attestation/revocation request for resolver validation
5. sas::attestation_registry
Centralized registry for all attestations.
Key Functions:
registry(): Register an attestationrevoke(): Mark attestation as revokedis_exist(): Check if attestation existsis_revoked(): Check if attestation is revokedupdate_allowed_versions(): Update registry version
Structs:
AttestationRegistry: Main registry objectStatus: Attestation status (schema, revoked flag, timestamp)
6. sas::schema_registry
Centralized registry for all schemas.
Key Functions:
register(): Register a schemais_exist(): Check if schema existsupdate_allowed_versions(): Update registry version
7. sas::admin
Administrative capabilities for schema management.
Key Functions:
- Schema creators receive
Admincapability - Used to revoke attestations (if schema is revokable)
Resolver Pattern
SAS supports a resolver pattern for custom validation logic:
- Create Schema with Resolver:
let (resolver_builder, admin_cap, schema) = sas::register_schema_with_resolver(
&mut schema_registry,
schema_bytes,
name_bytes,
description_bytes,
url_bytes,
true, // revokable
ctx
);
// Configure resolver rules and module
// ...- Attest with Resolver:
// Step 1: Start attestation request
let request = schema::start_attest(&schema);
// Step 2: Call resolver module to approve
resolver_module::approve(&schema, request);
// Step 3: Finish attestation
schema::finish_attest(&mut schema, request);
let attestation_id = sas::attest_with_resolver(
&mut schema,
&mut attestation_registry,
// ... other parameters
request
);- Example Resolvers: See
sas/resolvers/directory:blocklist: Blocklist-based access controlwhitelist: Whitelist-based access control
Data Integrity Verification
For off-chain storage, data integrity is verified using Blake2b-256 hashes:
// Hash calculation (matches Sui's hash::blake2b256)
let data_hash = hash::blake2b256(&data);
// Verification (in attestation module)
public fun verify_data_integrity(
self: &Attestation,
data: vector<u8>
): bool {
assert!(self.storage_type == STORAGE_TYPE_OFF_CHAIN, 0);
let computed_hash = hash::blake2b256(&data);
computed_hash == *&self.data_hash
}Testing
Run tests:
cd sas
sui move testTest files:
tests/sas_tests.move: Comprehensive tests for on-chain, off-chain, and encrypted storage
Aptos Attestation Service (AAS)
Architecture
The Aptos Attestation Service uses Aptos's account-based model with object support.
Core Modules
1. aas::aas
Main entry point for attestation operations.
Key Functions:
create_schema(): Create a new schemacreate_schema_and_get_schema_address(): Create schema and return addresscreate_attestation(): Create a new attestation (on-chain only)create_multi_attestations(): Batch create multiple attestationsrevoke_attestation(): Revoke an attestation
Example:
// Create schema
aas::create_schema(
creator,
schema_bytes,
name,
description,
url,
revokable,
resolver_address
);
// Create attestation
aas::create_attestation(
attestor,
recipient,
schema_address,
ref_attestation,
expiration_time,
revokable,
data
);2. aas::attestation
Core attestation data structure and operations.
Struct Fields:
schema: address: Schema addressattestor: address: Attestor addressrecipient: address: Recipient addressdata: vector<u8>: Attestation data (on-chain only)time: u64: Creation timestampexpiration_time: u64: Expiration timestamprevocation_time: u64: Revocation timestamprevokable: bool: Whether attestation can be revoked
Events:
AttestationCreated: Emitted when a new attestation is createdAttestationRevoked: Emitted when an attestation is revoked
3. aas::schema
Schema registration and management.
Structs:
Schema: Schema data structure
4. aas::resolver_dispatcher
Resolver dispatcher for custom validation logic.
Key Functions:
on_attest(): Validate attestation request via resolveron_revoke(): Validate revocation request via resolverregister_dispatchable(): Register resolver module
Example Resolver: See aas/resolver_example/ directory:
schema_resolver.move: Example resolver implementation
5. aas::package_manager
Package manager for contract deployment.
Testing
Run tests:
cd aas
aptos move testTest files:
tests/aas_tests.move: Tests for schema and attestation operations
Contract Deployment
Sui
- Build:
cd sas
sui move build- Publish:
sui client publish --gas-budget 100000000- Initialize Registries: After publishing, initialize the schema and attestation registries.
Aptos
- Build:
cd aas
aptos move build- Publish:
aptos move publish --named-addresses aas=<your_address>Versioning
Both Sui and Aptos contracts support versioning through registries:
- Schema Registry: Tracks allowed package versions
- Attestation Registry: Tracks allowed package versions
- Upgrade Path: Update registries to allow new versions while maintaining backward compatibility
Security Considerations
Access Control
- Schema Ownership: Only schema creators (via
Admincap) can revoke attestations - Object Ownership: In Sui, only object owners can pass objects in transactions
- Seal Access: Only attestation recipients can authorize Seal decryption
- Resolver Pattern: Custom validation logic can enforce additional rules
Data Integrity
- On-Chain: Data is directly stored on-chain and verifiable
- Off-Chain: Blake2b-256 hash stored on-chain for integrity verification
- Encrypted: Hash is calculated on original data before encryption
Best Practices
- Schema Design: Use well-defined schemas with appropriate field types
- Revocation: Set
revokableflag appropriately for your use case - Expiration: Always set reasonable expiration times
- Resolver Validation: Use resolvers for complex access control requirements
- Privacy: Use Seal encryption for sensitive attestation data (Sui only)
Development
Directory Structure
contracts/
├── sas/ # Sui Attestation Service
│ ├── sources/
│ │ ├── sas.move # Main entry point
│ │ ├── attestation.move # Attestation core logic
│ │ ├── schema.move # Schema management
│ │ ├── seal_access.move # Seal access control
│ │ └── ...
│ ├── resolvers/ # Example resolvers
│ │ ├── blocklist.move
│ │ └── whitelist.move
│ └── tests/
│ └── sas_tests.move
├── aas/ # Aptos Attestation Service
│ ├── sources/
│ │ ├── aas.move # Main entry point
│ │ ├── attestation.move # Attestation core logic
│ │ ├── schema.move # Schema management
│ │ └── ...
│ └── tests/
│ └── aas_tests.move
└── README.md # This fileDependencies
Sui:
- Sui Framework (testnet-v1.57.2)
- Move Stdlib
Aptos:
- Aptos Framework (mainnet)
- Aptos Token Framework
- Aptos Stdlib
References
License
See LICENSE file in the repository root.