메인 콘텐츠로 건너뛰기

목적 및 범위

이 문서는 StableNet에서 네이티브 스테이블코인을 민팅하고 소각하는 End to End 프로토콜의 동작을 설명합니다.
민터 멤버와 금융 기관 간의 오프체인 조정, 법정화폐 이동을 검증하기 위한 증명 구조, 그리고 GovMinter 거버넌스 컨트랙트와 정족수(quorum) 기반 승인 절차를 포함합니다.
이 프로토콜을 구현하는 거버넌스 컨트랙트에 대한 상세 내용은 민팅 거버넌스 (GovMasterMinter 및 GovMinter)를 참고하세요.
민트 및 소각이 실제로 수행되는 토큰 레이어는 NativeCoinAdapter 컨트랙트을 참고하세요.
전체 거버넌스 구조는 시스템 컨트랙트 개요에 설명되어 있습니다.

프로토콜 개요

민트 및 소각 프로토콜은 검증 가능한 법정화폐 예금 및 인출에 의해 뒷받침되는 스테이블코인 발행을 목표로 합니다.
프로토콜은 다음 세 가지 핵심 원칙을 따릅니다.
  1. 정족수 없는 단독 실행 금지: 민트·소각 작업은 GovMinter 제안과 정족수 기반 승인을 거친 뒤에만 실행되도록 설계됩니다
  2. 증명 기반 검증: 모든 민트 및 소각은 오프체인 법정화폐 이동을 참조하는 증명과 함께 제안됩니다
  3. 쿼럼 기반 합의: GovMinter 제네시스에서 정의한 민터 정족수에 도달한 경우에만 작업이 실행됩니다
프로토콜은 다음 주체 간의 협력을 전제로 합니다.
  • 민터 멤버: 증명을 검증하고 민트/소각 제안에 투표하는 거버넌스 참여자
  • 담보 계정: 법정화폐 예금과 인출이 실제로 발생하는 은행 계정
  • GovMinter 컨트랙트: 민트/소각 제안과 투표를 관리하는 온체인 거버넌스 컨트랙트
    (0x0000000000000000000000000000000000001003)
  • NativeCoinAdapter 컨트랙트: 승인된 민트/소각을 실행하여 네이티브 잔액을 수정하는 시스템 컨트랙트
    (0x0000000000000000000000000000000000001000)

시스템 아키텍처

민팅 및 소각 프로토콜은 오프체인 검증 + 온체인 합의 + 네이티브 잔액 수정의 세 계층으로 구성됩니다.
오프체인 계층은 법정화폐 이동의 사실 여부를 확인하고, 온체인 계층은 이를 집단 합의로 검증하며, 실행 계층은 NativeCoinAdapter를 통해 잔액과 총 공급량을 일관되게 갱신합니다.

민팅 프로토콜

민팅 워크플로우

민팅 프로토콜은 다음 4단계 흐름을 따릅니다.
  1. 예금 감지: 담보 계정으로의 법정화폐 예금이 감지됨
  2. 증명 구성: 예금 정보를 포함하는 민팅 증명 생성
  3. 제안 및 검증: GovMinter를 통한 제안 제출 및 민터 간 검증
  4. 온체인 실행: 정족수 도달 시 NativeCoinAdapter를 통한 민트 실행

민팅 증명 구조

민팅 증명은 토큰 발행 요청을 특정 법정화폐 예금에 바인딩하는 데이터 구조입니다.
온체인에서는 GovMinter의 MintProof 구조체로 표현됩니다.
FieldTypeDescription
beneficiaryaddress민팅된 토큰을 수령할 주소
amountuint256민팅할 토큰 수량(최소 단위 기준)
timestampuint256예금 발생 시점의 Unix 타임스탬프
depositIdstring은행 시스템 내 예금의 고유 식별자
bankReferencestring은행 거래 참고 번호(입금 내역과 1:1 대응)
memostring선택적 메모, 내부 회계·감사를 위한 부가 정보
이 구조와 GovMinter의 상태(usedProofHashes, depositIdToProposalId, executedDepositIds)는 다음을 보장합니다.
  • 고유성: 각 depositId는 한 번만 사용되어 이중 민팅을 방지
  • 추적성: 온체인 토큰 발행을 특정 오프체인 예금과 연결
  • 시의성: 타임스탬프를 기반으로 오래된 증명 거부 가능

민팅 중 민터 책임

민터 멤버는 민팅 과정에서 다음 책임을 집니다.
  1. 담보 계정 연계: 민터는 사전에 지정된 담보 계정과 연계되어야 하며, 이 관계는 GovMasterMinter를 통해 관리됩니다
  2. 예금 모니터링: 담보 계정의 법정화폐 예금을 오프체인에서 지속적으로 감시
  3. 증명 생성: 예금 감지 시 관련 정보를 포함한 민팅 증명 생성
  4. 제안 제출: 하나의 민터가 GovMinter에 민트 제안 제출
    동일한 depositId에 대한 중복 제안은 거부됨
  5. 독립 검증: 다른 민터가 각자 기록을 기준으로 증명 검증
    • 예금 발생 여부
    • 금액 일치 여부
    • 수혜자 주소 정확성
    • 이미 사용된 예금인지 여부
  6. 승인 투표: 검증이 완료되면 승인, 실패 시 거부 또는 기권

온체인 실행

민트 제안이 정족수에 도달하면 GovBase.executeProposal()이 GovMinter의 _executeMint()를 호출하고, 내부적으로 fiatToken.mint(beneficiary, amount)를 통해 토큰을 발행합니다. 일반적인 네트워크에서는 이 fiatTokenNativeCoinAdapter입니다. 실행 단계는 다음과 같습니다.
  1. 쿼럼 확인: GovBase가 충분한 승인 수를 충족했는지 확인
  2. Allowance 검증: fiatToken.minterAllowance(GovMinter)에서 사용 가능한 한도가 충분한지 확인
  3. 민트 실행: fiatToken.mint(beneficiary, amount) 호출
    NativeCoinAdapter의 경우 내부 ICoinManager.mint()를 통해 네이티브 잔액이 증가
  4. 증명 소진 표시: executedDepositIds[depositId] = true로 기록하여 재사용 방지
  5. 총 공급량 갱신: Fiat 토큰 총 공급량 증가
  6. 이벤트 발생: Mint 이벤트 및 Transfer(address(0), beneficiary, amount) 로그 기록

소각 프로토콜

소각 워크플로우

소각 프로토콜은 민팅의 역순으로 동작합니다.
토큰이 온체인에서 소각된 이후, 동일 수량의 법정화폐가 오프체인에서 반환됩니다.

소각 증명 구조

소각 증명은 토큰 소각 요청이 유효한 인출 요청임을 나타냅니다.
온체인에서는 GovMinter의 BurnProof 구조체로 표현됩니다.
FieldTypeDescription
fromaddress토큰을 소유한 주소
amountuint256소각할 토큰 수량
timestampuint256인출 요청 수신 시각
withdrawalIdstring인출 요청의 고유 식별자
referenceIdstring외부 정산 시스템 참고 ID
memostring선택적 메모, 내부 회계·감사용 정보
GovMinter는 withdrawalIdToProposalId, executedWithdrawalIds, usedProofHashes 상태를 사용해 다음을 보장합니다.
  • ID 고유성: withdrawalId는 한 번만 사용 가능
  • 사용자 명시성: 소각은 특정 from 주소에 대해 수행
  • 멱등성 보장: 동일 인출 요청의 중복 소각 방지

소각 중 민터 책임

  1. 인출 요청 수신
  2. 인출 ID 생성
  3. 오프체인 공유
  4. 증명 생성
  5. 제안 제출 및 예치: proposeBurn{value: amount} 호출로 동일 금액의 네이티브 코인 예치
  6. 독립 검증
  7. 승인 투표
  8. 법정화폐 반환

온체인 소각 실행

정족수 도달 시 GovBase.executeProposal()이 GovMinter의 _safeBurn()을 호출합니다. 실행 단계:
  1. 쿼럼 검증
  2. 비상 중지 상태 확인
  3. 예치 잔액 차감
  4. 소각 실행: fiatToken.burn(amount)
  5. 인출 ID 소진 표시
  6. 이벤트 기록

쿼럼 요구사항 및 거버넌스

쿼럼 구성

민트 및 소각에 필요한 쿼럼은 GovMinter 제네시스 파라미터로 설정됩니다.
systemContracts.govMinter.params:
- members: "comma-separated list of minter addresses"
- quorum: "minimum approvals required"
- expiry: "proposal expiration time in seconds"
- memberVersion: "version identifier"
- fiatToken: "0x0000000000000000000000000000000000001000"
권장 기준:
  • 최소값: 1
  • 최대값: 민터 수
  • 일반값: ceil((members.length * 2) / 3)

제안 라이프사이클

  1. 제안됨
  2. 투표 중
  3. 쿼럼 도달
  4. 실행됨
  5. 만료됨

보안 고려사항

비잔틴 장애 허용

정족수를 ceil((N * 2) / 3)으로 설정할 경우 최대 floor((N - 1) / 3)개의 악의적 민터를 허용합니다.

오프체인 종속성

오프체인 조정 실패는 지연 또는 거부로 이어질 수 있으나, 다중 민터 구조와 온체인 이벤트 감사로 완화됩니다.

제안 만료

만료 메커니즘은 오래된 증명 실행, 거버넌스 그리핑, 무한 제안 누적을 방지합니다.

NativeCoinAdapter와의 통합

민트 실행 경로

GovBase.executeProposal()
→ GovMinter._executeMint(...)
→ fiatToken.mint(...)
→ CoinManager.mint(...) precompile
→ Transfer(0x0, beneficiary, amount)

소각 실행 경로

GovBase.executeProposal()
→ GovMinter._safeBurn(...)
→ fiatToken.burn(...)
→ CoinManager.burn(...) precompile
→ Transfer(from, 0x0, amount)
이 실행 경로를 통해 네이티브 잔액, Fiat 토큰, 이벤트 로그가 일관되게 유지되며 온체인·오프체인 감사가 모두 가능합니다.