ERGO
Architecture Technique

Stack de Paiement Agent : Architecture de Référence

Quatre primitives on-chain. Trois flux composables. Tout ce dont vous avez besoin pour construire des paiements agent-à-agent sur Ergo — d'un simple appel API à une monnaie communautaire complète.

Les Quatre Primitives

Reserve · Note · Tracker · Predicate

Reserve

Garantie de capital

Un contrat on-chain qui détient des ERG ou des tokens en garantie. N'importe qui peut vérifier le ratio de réserve à tout moment. La Reserve est la banque — pas d'intermédiaire.

  • Détient des ERG / tokens natifs
  • Auditable à tout moment
  • Garantit l'émission de Note 1:1 ou fractionnellement
  • Remboursement imposé par le contrat
ErgoScript
{
  // Reserve contract: allow withdrawal only
  // if redemption note is burned
  val noteBox = INPUTS(1)
  val burnCheck = noteBox.tokens.size == 0
  sigmaProp(burnCheck && SELF.R4[Long].get > 0)
}

Note

Reconnaissance de dette programmable

Un token au porteur représentant une créance contre une Reserve. Les Note peuvent être transférés, divisés et remboursés. Le Predicate d'acceptation définit qui peut recevoir ou rembourser le Note.

  • Instrument au porteur — aucune identité requise
  • Transférable de pair à pair
  • Remboursable contre le contrat de Reserve
  • Dénomination dans n'importe quel token
ErgoScript
{
  // Note: transferable by holder,
  // redeemable against reserve
  val holder = SELF.R4[GroupElement].get
  val isHolder = proveDlog(holder)
  val isRedemption = INPUTS.exists { box =>
    box.tokens.exists(_._1 == reserveId)
  }
  isHolder || isRedemption
}

Tracker

Comptabilité on-chain

Suit les soldes cumulés, l'utilisation du crédit et l'historique des remboursements pour tous les Note émis depuis une Reserve. Pensez-y comme un registre public que n'importe qui peut vérifier.

  • Suit le total émis vs remboursé
  • Applique les limites de crédit
  • Auditable publiquement
  • Composable avec d'autres contrats
ErgoScript
{
  // Tracker: ensure running total
  // doesn't exceed credit limit
  val limit = SELF.R4[Long].get
  val used  = SELF.R5[Long].get
  val newUsed = used + INPUTS(0).value
  sigmaProp(newUsed <= limit)
}

Acceptance Predicate

Règle de confiance programmable

La condition sous laquelle un agent acceptera un Note comme paiement. Les conditions peuvent inclure la vérification du hash de tâche, les contrôles de délai, les preuves d'accréditation ou toute donnée on-chain.

  • Conditions d'acceptation arbitraires
  • Vérification du hash de tâche
  • Application des délais
  • Composable avec les preuves Sigma
ErgoScript
{
  // Accept note only if:
  // 1. Task hash matches R4
  // 2. Deadline not passed
  val taskHash  = SELF.R4[Coll[Byte]].get
  val deadline  = SELF.R5[Int].get
  val inputHash = INPUTS(0).R4[Coll[Byte]].get
  val onTime    = HEIGHT <= deadline
  sigmaProp(taskHash == inputHash && onTime)
}

Flux d'Exemple

Trois flux composables

Flux A : L'agent achète un appel API

Un appel. Une preuve. Pas de compte permanent.

  1. 1

    L'agent crée un Note

    Valeur nominale de 0,001 ERG, adresse du fournisseur dans R4

  2. 2

    Le fournisseur vérifie le Predicate

    Vérifie la valeur du Note, la garantie Reserve, le délai

  3. 3

    Le fournisseur livre la réponse

    Retourne le résultat API, marque le Note comme dépensé

  4. 4

    Règlement

    Note brûlé, ERG libéré de la Reserve vers le fournisseur

Fleet SDK (TypeScript)
// Fleet SDK: create a note for API payment
import { TransactionBuilder, OutputBuilder, SAFE_MIN_BOX_VALUE } from "@fleet-sdk/core"

const noteBox = new OutputBuilder(
  1_000_000n, // 0.001 ERG
  NOTE_CONTRACT_ADDRESS
)
  .setAdditionalRegisters({
    R4: SGroupElement(providerPubKey),  // recipient
    R5: SLong(BigInt(HEIGHT + 100)),    // deadline
    R6: SColl(SByte, taskHashBytes),    // task identifier
  })

const tx = new TransactionBuilder(currentHeight)
  .from(inputs)
  .to(noteBox)
  .sendChangeTo(agentAddress)
  .payMinFee()
  .build()

Flux B : L'agent paie à crédit

Reserve déployée. Notes émis. Tracker surveille.

  1. 1

    Déployer la Reserve

    Verrouiller des ERG dans le contrat de Reserve avec limite de crédit

  2. 2

    Émettre des Notes

    Créer des Notes contre la Reserve jusqu'à la limite de crédit

  3. 3

    L'agent dépense les Notes

    Notes transférés aux fournisseurs, Tracker mis à jour

  4. 4

    Auto-règlement

    Au seuil atteint, la Reserve règle les Notes en cours

Fleet SDK (TypeScript)
// Deploy a reserve with 10 ERG, 100 ERG credit limit
const reserveBox = new OutputBuilder(
  10_000_000_000n, // 10 ERG collateral
  RESERVE_CONTRACT_ADDRESS
)
  .setAdditionalRegisters({
    R4: SLong(100_000_000_000n), // 100 ERG credit limit
    R5: SLong(0n),               // issued so far
    R6: SGroupElement(ownerKey), // reserve controller
  })

// Issue a note against the reserve
const noteBox = new OutputBuilder(
  1_000_000_000n, // 1 ERG face value
  NOTE_CONTRACT_ADDRESS
)
  .setAdditionalRegisters({
    R4: SGroupElement(agentKey),  // holder
    R5: SColl(SByte, reserveId),  // backing reserve
  })

Flux C : Reserve communautaire + Tracker

Un marché local, une coopérative de calcul, un réseau d'agents.

  1. 1

    La communauté déploie la Reserve

    ERG mutualisés par les membres de la communauté

  2. 2

    Émettre des Notes communautaires

    Les membres reçoivent des Notes proportionnels à leur contribution

  3. 3

    Commerce local

    Notes acceptés au sein de la communauté, les Predicates définissent les règles

  4. 4

    Remboursement

    Les membres remboursent les Notes contre des ERG de la Reserve à tout moment

Fleet SDK (TypeScript)
// Community reserve: multiple funders
const communityReserve = new OutputBuilder(
  TOTAL_POOLED_ERG,
  MULTISIG_RESERVE_CONTRACT
)
  .setAdditionalRegisters({
    R4: SColl(SGroupElement, memberKeys), // governance
    R5: SInt(3),                          // 3-of-5 threshold
    R6: SColl(SByte, communityTokenId),   // community token
  })

// Acceptance predicate: only members of community
const memberPredicate = `{
  val isMember = CONTEXT.dataInputs(0)
    .R4[Coll[GroupElement]].get
    .exists(pk => proveDlog(pk))
  sigmaProp(isMember)
}`

État actuel

Statut du stack

Cinq couches sont en ligne. Deux sont des problèmes ouverts. Rejoignez la conversation sur GitHub — ce sont les problèmes non résolus les plus intéressants de la monnaie d'agents.

En ligne sur mainnet / testnet
Bientôt disponible
Problème de recherche ouvert
Faucet Ergo testnet
Fleet SDK (TypeScript)
AppKit (JVM)
sigma-rust
Serveur ChainCash (Note + Reserve)
Ergo Node REST API
Dépôt agent-economy-starter
bientôt
Couche d'identité d'agent
ouvert

Vous construisez des agents ? Parlons-en.

Réservez une session de conception, obtenez une revue de code ou rejoignez la liste des constructeurs. Nous répondrons sous 24 heures.

Follow for daily updates