에이전트 결제 스택: 레퍼런스 아키텍처
4가지 온체인 프리미티브. 3가지 조합 가능한 플로우. 단일 API 호출부터 완전한 커뮤니티 통화까지, Ergo에서 에이전트 간 결제를 구축하는 데 필요한 모든 것.
4가지 프리미티브
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
프로그래밍 가능한 IOU
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
온체인 회계
Reserve에서 발행된 모든 Note에 걸친 누적 잔액, 신용 사용량, 상환 이력을 추적합니다. 누구나 검증할 수 있는 공개 원장으로 생각하세요.
- 발행 대비 상환 총액 추적
- 신용 한도 집행
- 공개 감사 가능
- 다른 컨트랙트와 조합 가능
{
// 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)
}샘플 플로우
3가지 조합 가능한 플로우
플로우 A: 에이전트가 API 호출 구매
한 번의 호출. 하나의 증명. 영구 계정 불필요.
- 1
에이전트가 Note 생성
0.001 ERG 액면가, R4에 프로바이더 주소
- 2
프로바이더가 Predicate 확인
Note 가치, Reserve 담보, 기한 검증
- 3
프로바이더가 응답 전달
API 결과 반환, Note를 사용됨으로 표시
- 4
정산
Note 소각, Reserve에서 프로바이더에게 ERG 해제
// 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 발행
신용 한도까지 Reserve에 대해 Note 생성
- 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
상환
멤버는 언제든 Reserve에서 ERG로 Note 상환 가능
// 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)
}`