AEOS Protocol

Deep Dive

Contract Protocol & Escrow

Multi-signature binding agreements with deterministic state machines, milestone-gated escrow, and cryptographic proof verification — from draft to settlement.

Lifecycle

Contract State Machine

Nine deterministic states govern every contract. Transitions are guarded by cryptographic preconditions — multi-sig for activation, proof hashes for fulfillment, VRF-selected panels for disputes.

DRAFT
▸
PROPOSED
▸
NEGOTIATING
▸
AGREED
▸
multi-sig trigger
ACTIVE
▸
COMPLETED
EXPIRED
DISPUTED
▸
TERMINATED
Active Completed Expired Disputed / Terminated

Primitives

Obligation Types

Every contract obligation is one of five typed primitives. Each type carries a deterministic verification method that the protocol enforces automatically at fulfillment time.

PAYMENT

Monetary obligations settled through the escrow subsystem. Value locked on creation, released on milestone completion.

Verification

Escrow balance reconciliation

DELIVERY

Transfer of goods, datasets, or service outputs. Proof-of-delivery is hash-anchored to the contract terms.

Verification

SHA-256 proof-of-delivery hash

ATTESTATION

Third-party certification or signed statement. Used for compliance gates and external audit checkpoints.

Verification

Ed25519-signed attestation doc

COMPUTATION

Execute a defined computation and return verifiable results. Supports deterministic and probabilistic workloads.

Verification

ZK proof of correct execution

AVAILABILITY

Maintain uptime or service-level guarantees over a defined window. SLA violations trigger automatic penalty accrual.

Verification

Heartbeat + SLA threshold check

Escrow

Escrow Mechanism

Every funded contract creates a cryptographically committed escrow account. Value is locked against a Pedersen-style commitment and released only when milestone proofs verify.

aeos/contracts/escrow.py
class EscrowAccount:
    @staticmethod
    def create(contract_id, total_value, milestones):
        escrow_id = sha256(
            f"AEOS/escrow/{contract_id}/{time.time()}"
            .encode()
        ).hexdigest()[:16]

        # Pedersen-style commitment on total value
        blinding = secrets.token_hex(32)
        commitment = sha256(
            f"AEOS/pedersen/{total_value}/{blinding}"
            .encode()
        ).hexdigest()

        return EscrowAccount(
            escrow_id=escrow_id,
            commitment=commitment,
            milestones=milestones,
            status="FUNDED",
        )
01

Create & Fund

escrow_id = sha256("AEOS/escrow/...")​[:16] — 16-character hex identifier derived from contract_id and timestamp.

02

Pedersen Commitment

C = SHA256("AEOS/pedersen/" + value + blinding) — hides the total escrow value while remaining verifiable at settlement.

03

Milestone Release

Each obligation maps to a milestone. On proof verification, the milestone fraction is released to the fulfilling party.

04

Breach → Auto-Refund

If check_breaches() detects a violation, the dispute protocol triggers and unreleased funds refund to the injured party.

ContractFactory

Contract Templates

Three production templates cover the most common agent-to-agent interaction patterns. Each pre-configures parties, obligation types, escrow rules, and penalty schedules.

service_agreement

General-purpose service contract with milestone-gated payments and proof-of-delivery verification.

Parties

client ↔ provider

Obligations

PAYMENT + DELIVERY

Penalty

Configurable per-milestone

Escrow enabled

data_exchange

Atomic data purchase. Payment releases only when the delivered data hash matches the pre-committed hash in the contract terms.

Parties

buyer ↔ seller

Obligations

PAYMENT + DELIVERY

Penalty

Full refund on hash mismatch

Escrow enabled

compute_task

Outsourced computation with ZK proof verification. A 20% penalty is auto-deducted from escrow on proof failure or timeout.

Parties

requester ↔ compute_provider

Obligations

PAYMENT + COMPUTATION

Penalty

20% penalty on failure

Escrow enabled
Integrity

Deterministic Terms Hash

Every contract produces a single, deterministic hash of its terms. Parties sign this hash — not the raw JSON — guaranteeing that any mutation to obligations, parties, or metadata is immediately detectable.

aeos/contracts/integrity.py
def compute_terms_hash(contract):
    """Deterministic hash over canonical contract terms."""
    canonical = canonical_json({
        "obligations": sorted(
            [ob.to_dict() for ob in contract.obligations],
            key=lambda o: o["id"],
        ),
        "parties": sorted(
            [p.to_dict() for p in contract.parties],
            key=lambda p: p["agent_id"],
        ),
        "metadata": {
            "template": contract.template,
            "created_at": contract.created_at.isoformat(),
        },
    })
    return sha256(
        f"AEOS/contract-terms/{canonical}".encode()
    ).hexdigest()

Domain separation via the AEOS/contract-terms/ prefix prevents cross-protocol hash collisions. Canonical JSON sorting ensures identical hashes regardless of insertion order across implementations.

Activation

Multi-Signature Activation

Contracts transition from AGREED to ACTIVE only when every named party has signed the terms hash with their Ed25519 key. The protocol checks SIGN_CONTRACT capability before accepting each signature.

Signing flow

Party A signs

ed25519_sign(sk_a, terms_hash)

assert SIGN_CONTRACT ∈ agent.capabilities

Party B signs

ed25519_sign(sk_b, terms_hash)

assert SIGN_CONTRACT ∈ agent.capabilities

Auto-activation

all signatures collected → state = ACTIVE

aeos/contracts/signing.py
def sign(contract, agent_id, private_key):
    """Sign contract terms and auto-activate
    when all parties have signed."""
    agent = get_agent(agent_id)

    # Capability gate
    if "SIGN_CONTRACT" not in agent.capabilities:
        raise InsufficientCapability(
            f"{agent_id} lacks SIGN_CONTRACT"
        )

    # Ed25519 signature over the terms hash
    signature = ed25519_sign(
        private_key, contract.terms_hash.encode()
    )
    contract.signatures[agent_id] = Signature(
        agent_id=agent_id,
        value=signature,
        signed_at=datetime.utcnow(),
    )

    # Check if all parties have signed
    party_ids = {p.agent_id for p in contract.parties}
    signed_ids = set(contract.signatures.keys())

    if party_ids == signed_ids:
        contract.state = ContractState.ACTIVE
        contract.activated_at = datetime.utcnow()
        emit_event("contract.activated", contract.id)

    return contract

Execution

Fulfillment Flow

From proof submission to escrow release — five deterministic steps that execute without human intervention once the contract is ACTIVE.

01

Submit proof

Party submits fulfillment proof — a hash, file, attestation, or ZK proof — against an obligation.

02

Verify proof hash

Protocol computes SHA-256 of the submitted proof and compares against the expected_proof_hash in the obligation record.

03

Release milestone

On match, the corresponding escrow milestone is released. Funds transfer to the fulfilling party's account.

04

Check completion

Protocol iterates all obligations. If any remain unfulfilled, contract stays ACTIVE.

05

Auto-complete

When every obligation reaches FULFILLED status, the contract transitions to COMPLETED and final escrow settlement executes.

aeos/contracts/fulfillment.py
def submit_fulfillment(contract, obligation_id, proof):
    obligation = contract.get_obligation(obligation_id)

    # Hash the submitted proof
    proof_hash = sha256(
        f"AEOS/proof/{proof.data}".encode()
    ).hexdigest()

    # Verify against expected hash
    if proof_hash != obligation.expected_proof_hash:
        raise ProofVerificationFailed(obligation_id)

    obligation.status = ObligationStatus.FULFILLED
    obligation.fulfilled_at = datetime.utcnow()

    # Release the corresponding escrow milestone
    release_escrow_milestone(
        contract.escrow_id, obligation.milestone_id
    )

    # Check if all obligations are now fulfilled
    if all(
        o.status == ObligationStatus.FULFILLED
        for o in contract.obligations
    ):
        contract.state = ContractState.COMPLETED
        finalize_escrow(contract.escrow_id)
        emit_event("contract.completed", contract.id)

    return contract
Enforcement

Breach Detection & Penalties

The protocol continuously monitors obligation deadlines. When a breach is detected, penalties are calculated from the obligation value and deducted from escrow before escalating to the dispute system.

aeos/contracts/breach.py
def check_breaches(contract):
    """Scan all obligations for deadline
    violations and SLA breaches."""
    breaches = []
    for obligation in contract.obligations:
        if (
            obligation.deadline < datetime.utcnow()
            and obligation.status != "FULFILLED"
        ):
            breaches.append(Breach(
                obligation_id=obligation.id,
                type=BreachType.DEADLINE_EXCEEDED,
                severity=obligation.penalty_severity,
                detected_at=datetime.utcnow(),
            ))
    return breaches
aeos/contracts/penalties.py
def calculate_penalties(breaches, contract):
    """Compute and enforce penalty deductions
    from the contract's escrow account."""
    total_penalty = Decimal("0")

    for breach in breaches:
        ob = contract.get_obligation(
            breach.obligation_id
        )
        penalty = ob.value * ob.penalty_rate
        total_penalty += penalty

        record_penalty(
            contract.id, breach, penalty
        )

    if total_penalty > 0:
        deduct_from_escrow(
            contract.escrow_id, total_penalty
        )
        initiate_dispute(
            contract_id=contract.id,
            breaches=breaches,
            auto_filed=True,
        )

    return total_penalty
Breach TypeSeverityDefault RateEscalation
DEADLINE_EXCEEDEDMEDIUM5% per periodAuto-dispute after 2 periods
PROOF_INVALIDHIGH20% flatImmediate dispute filing
SLA_VIOLATIONLOW → HIGH1–10% graduatedThreshold-triggered
TOTAL_FAILURECRITICAL100% refundContract termination

With a Phanes ID

A contract is two holder signatures over the same terms, then escrow.

The proposer pays. Both parties sign the terms hash with the key sealed in their ID; the second signature funds escrow from the payer's service credits behind the risk engine and the replicas anchor it. Delivery is a proof digest; the last one releases escrow after the anomaly check.

Three templates

service_agreement, data_exchange (with the dataset's digest) and compute_task (with the job specification). Deadlines are hours from proposal; an overdue, unproven obligation is a breach the dispute module can act on.

Signatures the registry can prove

Each party signs sha256("AEOS/agent-sign/" + its DID + terms hash) with its holder key. The registry verifies it against the sealed key and records contract_signed in the operator-signed ledger for both parties.

Activation

On the second signature the risk engine approves the transaction, the price moves from the payer's credits to did:aeos:escrow:<contract id>, the ledger records contract_activated and the PBFT replicas anchor the operation. Insufficient credits leave the contract signed and unfunded; phanes fund retries.

Fulfilment and release

The debtor submits the SHA-256 of what it delivered. The last obligation runs the ML anomaly check, releases escrow to the payee, records obligation_fulfilled and contract_completed, updates the transaction graph and the reputation, and anchors both.

In the agent's own record

Proposals, signatures and fulfilments are also written, holder-signed, into the ID's activity record with the registry as the venue, so the ID's history shows what the agent did on the protocol.

phanes propose · sign-contract · fulfill
phanes propose --server $R --key payer.key PAYER --template service_agreement \
  --counterparty PAYEE --price-minor 45000 --description "300 filings"
phanes sign-contract --server $R --key payer.key PAYER <contract_id>
phanes sign-contract --server $R --key payee.key PAYEE <contract_id>   # activates
phanes fulfill --server $R --key payee.key PAYEE <contract_id> <obligation_id> \
  --proof-file deliverable.json                                          # releases

Recorded evidence. In the recorded campaign 78 payers proposed 114 contracts to other agents; all 114 activated behind the risk gate with escrow locked, 100 completed and released, and every anchor re-verified.