Стек платежей агентов: Эталонная архитектура
Четыре ончейн-примитива. Три компонуемых потока. Всё, что нужно для построения платежей между агентами на Ergo — от одного вызова API до полноценной общественной валюты.
Четыре примитива
Reserve · Note · Tracker · Predicate
Reserve
Обеспечение капиталом
Ончейн-контракт, хранящий ERG или токены в качестве залога. Любой может проверить коэффициент резерва в любое время. Reserve — это банк, без посредников.
- Хранит ERG / нативные токены
- Проверяем в любое время
- Обеспечивает выпуск Note 1:1 или частично
- Погашение обеспечивается контрактом
{
// 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
Программируемая долговая расписка
Токен на предъявителя, представляющий требование к Reserve. Note можно передавать, разделять и погашать. Predicate приёмки определяет, кто может получить или погасить Note.
- Инструмент на предъявителя — идентификация не требуется
- Передаваемый одноранговым способом
- Погашаемый против контракта Reserve
- Номинал в любом токене
{
// 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
Ончейн-бухгалтерия
Отслеживает кумулятивные балансы, использование кредита и историю погашений по всем Note, выпущенным из Reserve. Думайте о нём как о публичном реестре, который может проверить любой.
- Отслеживает общий объём выпуска vs погашения
- Применяет кредитные лимиты
- Публично проверяем
- Компонуем с другими контрактами
{
// 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
Программируемое правило доверия
Условие, при котором агент примет Note в качестве оплаты. Условия могут включать верификацию хеша задачи, проверку дедлайнов, доказательства полномочий или любые ончейн-данные.
- Произвольные условия приёмки
- Верификация хеша задачи
- Применение дедлайнов
- Компонуем с Sigma-доказательствами
{
// 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)
}Примеры потоков
Три компонуемых потока
Поток A: Агент покупает вызов API
Один вызов. Одно доказательство. Без постоянного аккаунта.
- 1
Агент создаёт Note
Номинал 0.001 ERG, адрес провайдера в R4
- 2
Провайдер проверяет Predicate
Проверяет стоимость Note, обеспечение Reserve, дедлайн
- 3
Провайдер доставляет ответ
Возвращает результат API, помечает Note как использованный
- 4
Расчёт
Note сожжён, ERG освобождён из Reserve провайдеру
// 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()Поток B: Агент платит в кредит
Reserve развёрнут. Note выпущены. Tracker мониторит.
- 1
Развернуть Reserve
Заблокировать ERG в контракте Reserve с кредитным лимитом
- 2
Выпустить Note
Создать Note против Reserve в пределах кредитного лимита
- 3
Агент тратит Note
Note переданы провайдерам, Tracker обновлён
- 4
Авто-расчёт
При достижении порога Reserve погашает непогашенные Note
// 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
})Поток C: Общественный Reserve + Tracker
Локальный маркетплейс, вычислительный кооператив, сеть агентов.
- 1
Сообщество разворачивает Reserve
ERG объединены участниками сообщества
- 2
Выпуск общественных Note
Участники получают Note пропорционально вкладу
- 3
Локальная торговля
Note принимаются в сообществе, Predicate определяют правила
- 4
Погашение
Участники погашают Note за ERG из Reserve в любое время
// 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)
}`SDK и инструменты
Начните строить сегодня
Fleet SDK
TypeScript / JS
Создавайте транзакции в браузере или Node.js. Лучшая отправная точка для платежей агентов.
sigma-rust
Rust
Высокопроизводительное подписание и сериализация. Идеально для продакшн-инфраструктуры агентов.
Текущий статус
Статус стека
Пять слоёв работают. Два — открытые проблемы. Присоединяйтесь к обсуждению на GitHub — это самые интересные нерешённые проблемы в деньгах агентов.