Rand Protocol
문서
가이드

발행과 소각

RAND가 풀에 들어오는 방식(제네시스 예치와 testnet 파우셋)과 풀에서 나가는 방식(수수료와 번들의 소각 워드), 그리고 각 이동이 무엇을 공개하는지 설명합니다.

이 페이지는 테스트 체인에서 faucet을 실행하는 방법, Mint 트랜잭션이 와이어 상에서 무엇인지, 그리고 본드(bond)나 브리지 소각(burn)이 풀(pool)에서 가치를 어떻게 꺼내 가는지를 정확히 보여 줍니다. 모든 진입과 모든 인출은 공개되며, 그 사이의 모든 것은 노트입니다.

faucet 민트

Mint는 체인 20에서 제네시스 이후 RAND가 생성되는 유일한 방법이며, 제네시스에 "faucet": true가 지정된 체인에서만 존재합니다. 이는 검증인이 서명하는, 번들이 없는 트랜잭션입니다.

Action::Mint { cm: Word8, pk: Word8, time: u32, r: Word8, envelope: Envelope, amount: u64,
               minter: PublicKey, signature: Signature }

검증인 노드의 rand_mint(address[, amount])는 주어진 rand1… 주소 앞으로 amount만큼의 노트를 만들고, 일회용 발신자 키로 봉투(envelope)를 봉인하며, 노드 자신의 Dilithium2 키로 민트에 서명한 뒤, 일반 멤풀을 통해 제출합니다. 따라서 민트는 합의를 거치고 모든 노드가 이를 적용합니다. 상한은 호출당 100000000000 단위, 즉 100 RAND이며 기본값이 상한입니다. 체인 14부터 민트는 노트의 오프닝(pk, time, r)을 담고 서명이 이를 포함합니다. 승인 단계에서는 (pk, no sender, amount, asset 0, time, r)의 커밋먼트를 다시 계산하여, 일치하지 않는 cm은 the mint's commitment does not open to its published note and amount로 거부하고, time은 번들 윈도우 안에 있어야 합니다. rand_mint의 매개변수는 바뀌지 않았습니다. 서명 대상 메시지는 체인 14~19에서는 blake3("rand-mint-2" ‖ bincode(chain_id, cm, pk, time, r, envelope, amount))이고, 제네시스에 binding_domain: 1을 지정한 체인 20에서는 제네시스 해시에 같은 필드가 이어지는 rand-mint-3입니다. 따라서 한 체인을 위해 서명된 민트는 체인 ID와 검증인 키가 같은 다른 체인에서도 거부됩니다. 관찰자(observer)는 검증인 키가 없으므로 faucet mints are signed by validators; ask a validator node라고 응답하며, 플래그가 없는 체인은 faucet is disabled on this chain이라고 응답합니다.

체인 20의 faucet은 켜져 있지만 제네시스의 staking 섹션으로 제한되며, 그 값은 체인 19와 같습니다.

규칙체인 20거부
수령인지갑 16개의 허용 목록(staking.faucet_recipients). 민트가 공개한 pk가 목록에 있어야 함the faucet may not mint to this recipient (not in staking.faucet_recipients), 영구적
예산1,000블록 에포크당 10,000 RAND(staking.faucet_budget_per_epoch), 모든 검증인 합산the faucet budget of … for this epoch is exhausted (… minted). 다음 에포크에는 승인됨
민터검증인 26명 중 18명(staking.faucet_minters, 체인 16부터 명시). 민트는 이들 중 한 명이 서명해야 함minter … is not a faucet minter on this chain

따라서 rand faucet은 체인 20에서 목록에 있는 지갑에 대해서만, 그리고 키가 등록된 민터인 검증인 노드에 요청할 때만 동작하며, 그 밖의 주소는 RAND를 보유한 누군가가 대신 지급해야 합니다.

rand faucet                          # 100 RAND to this wallet's address, waits for the commit
rand faucet rand1… --amount 25       # to another address, less than the cap
→ {"method":"rand_mint","params":["rand1…", "100000000000"]}
← "9ab1c0…4f"

공개되는 것은 새 노트의 커밋먼트, 그 봉투, 평문으로 된 금액, 그리고 민트한 검증인의 공개 키(주소로 표시)와 서명입니다. 오프닝은 노트의 소유자 키 pk도 공개하므로, 출금(withdraw)의 지급처가 공개되듯 faucet 노트의 소유자도 공개됩니다. 숨겨지는 것은 그 노트가 이후 언제, 어디에서 사용되는가입니다. “100 RAND가 민트되었다”에서 “100 RAND짜리 노트가 존재한다”로 이어지는 한 단계의 연결은, 어디서든 투명 주소에서 차폐 주소로 입금할 때 드러나는 가시성과 같습니다. 승인 단계에서는 faucet이 활성화되어 있는지, 금액이 상한 미만인지, 에포크 예산에 여유가 있는지, 제네시스에 허용 목록이 있는 경우 수령인이 그 목록에 있는지, 커밋먼트가 공개된 노트로 열리는지, 민터가 검증인이며 제네시스에 민터 목록이 있는 경우 그 목록에 있는지, 그리고 서명이 검증되는지를 확인합니다. 민트에는 수수료가 없습니다.

rand_getTransaction은 이를 { "kind": "mint", "cm": "…", "amount": "100000000000", "minter": "<validator base58>" }와 "bundle": null로 표시합니다. 금액은 체인 14부터 RPC가 제공하는 모든 u64 금액과 마찬가지로 십진 문자열입니다. 익스플로러는 이를 kind=mint 아래에 나열하며, 공개된 amount를 가진 몇 안 되는 종류 중 하나입니다.

제네시스 입금

가치가 들어오는 다른 경로는 제네시스 파일입니다. rand-node genesis에 전달한 각 --alloc rand1<address>=<RAND>는 새로운 커밋먼트 난수를 가진 입금 노트 { cm, envelope, amount, opening } 하나가 되어 트리의 첫 리프가 됩니다. 체인 20에는 제네시스 노트가 아홉 개 있습니다. RAND 노트 일곱 개는 합계 5,184.243719258 RAND(genesis_deposited)로, 체인 19의 스냅샷에서 이월한 운영자 잔액이며, zUSD 노트 두 개는 10 zUSD와 89 zUSD로, 체인 19에서 이월한 브리지 보관분 99 zUSD입니다(Bridge). 이 zUSD 노트는 RAND가 아니므로 genesis_deposited에 포함되지 않습니다. 운영자가 보유하지 않은 지갑이 체인 19에서 보유하던 RAND(약 520 RAND)와 인출되지 않은 검증인 수수료는 이월되지 않았습니다. 이력은 다음과 같습니다. 체인 19에는 노트가 여덟 개 있었는데, 5,294.644359629 RAND짜리 RAND 노트 일곱 개와 10 zUSD짜리 한 개였습니다. 체인 18에는 RAND 노트 여섯 개가 있었는데, 1,000 RAND짜리 다섯 개와 300 RAND짜리 한 개였습니다. 체인 14와 15에는 1,000 RAND짜리 다섯 개가 있었습니다. 금액은 누구나 초기 공급량을 합산할 수 있도록 공개되며, 체인 14부터 노트가 오프닝도 함께 담으므로 제네시스 노트의 소유자는 설계상 공개됩니다. 같은 할당으로 다시 제네시스를 만들면 노트와 제네시스 해시가 달라지며, 이는 의도된 동작입니다.

소각

모든 트랜잭션은 네 슬롯짜리 숨김 자산 번들을 하나 가지며, 번들에는 두 개의 소각 워드가 있습니다. burn_r은 풀에서 공개된 곳으로 나가는 RAND이고, burn_a는 burn_asset이 지정하는 토큰의 금액입니다. 번들 게스트는 두 그룹을 하나의 증명 안에서 균형 맞추며, 승인 단계에서는 다음 동작을 제외하고 세 값이 모두 0일 것을 요구합니다.

소각규칙가치의 행선지
Bond의 번들burn_r == amount레지스터에 있는 검증인의 공개 stake
BridgeBurn의 번들burn_asset == asset, burn_a == amount, burn_r == 0, asset != 0Rand에서 파기됨. 원천 체인의 컨트랙트가 가디언이 서명한 소각 메시지에 대응하여 지정된 코인 amount만큼을 해제함. 체인 20에서는 체인이 10 bps의 수수료를 재무부(treasury) 앞으로의 zUSD 노트로 받으며, 해제액은 amount − fee임
TokenBurn의 번들브리지 소각과 같은 형태파기됨. RPL 토큰의 공개 total_supply가 정확히 그만큼 줄어듦
Invoke의 번들(RPL-2, 체인 20)프로그램의 전이(transition)가 선언한 대로 burn_r, 그리고 burn_asset의 burn_aRAND와 토큰이 프로그램의 공개 볼트(vault)에 예치되거나 프로그램 자체의 토큰이 파기됨. 볼트는 체인이 계산한 노트로만 다시 지급함(Programs)

(register_aggregator의 번들도 burn_r을 통해 제네시스 본드를 소각합니다. 체인 20에서는 집계가 꺼져 있습니다.)

소각은 수수료가 아닙니다. 본드의 소각은 RAND가 풀에서 레지스터로 이동하는 것이며, 공급량 감사의 burned에 계산되고 register_total에 다시 나타납니다. 브리지 소각은 체인 14부터 하나의 번들입니다(이전에는 둘이었습니다). 슬롯 0–1은 브리지된 자산을 소각하고 슬롯 2–3은 수수료를 지불하므로, RAND 공급량에는 그 수수료인 BRIDGE_BURN_FEE, 0.01 RAND를 통해서만 영향을 줍니다. 소각은 해당 자산을 뒷받침하는 코인을 지정해야 하고, 그 코인의 정수 단위만큼 해제해야 하며, 그 담보가 잠근 양 안에 들어와야 합니다(Bridge). 체인 20에서는 제네시스의 bridge.fees가 브리지된 모든 민트와 소각에서 zUSD로 10 bps도 받습니다. 입금은 총액에서 수수료를 뺀 만큼을 기록하고 소각은 amount − fee를 해제하며, 각 수수료는 재무부 앞으로의 차폐된 zUSD 노트입니다. 수수료 노트는 발행되어 담보된 상태로 남으므로 zUSD의 total_supply == Σ locked는 그대로 유지됩니다. 이는 RAND의 이동이 아니며 RAND 공급량 감사에 들어가지 않습니다. TokenBurn은 0.001 RAND의 번들 기본료를 지불하며, 브리지된 토큰은 거기서 거부되고 bridge-burn을 통해 나갑니다.

체인 20에서는 수수료 하나도 소각입니다(체인 15 이후 모든 체인이 그렇습니다). 제네시스가 tokens.burn_registration_fee를 설정하므로 RegisterToken 또는 RegisterBridgedToken의 1 RAND registration_fee는 제안자에게 지급되지 않고 파기되며, 제안자는 번들 기본료만 받습니다. 이는 burned에 계산되고 별도로 registration_fees_burned에도 계산됩니다(RPL tokens).

rand bond <validator> 1000 [--registration <hex>]     # burns 1000 RAND out of this wallet's notes
rand bridge-burn <ASSET> <AMOUNT> <TO_CHAIN> <TOKEN> <TO>   # burns AMOUNT of a bridged asset, released as TOKEN on TO_CHAIN
rand token burn <ASSET> <AMOUNT>                      # destroys AMOUNT of an RPL token this wallet holds

수수료는 또 다른 인출입니다

모든 번들의 fee는 풀에서 블록 제안자의 rewards(공개 레지스터 필드)로 나가며, 검증인이 이를 노트로 인출할 때에만 풀로 돌아옵니다(Staking). Withdraw는 인출액에서 0.001 RAND 기본료를 이를 적용한 블록의 제안자에게 지급하며, 그 기본료는 레지스터를 떠나지 않으므로 경계를 넘는 이동이 아닙니다.

공급량이 움직이는 방식

in:   genesis_deposited, faucet_minted, withdraw_deposited, program_rand_out
out:  fees_paid, burned
pool_value     = in − out
total_supply   = pool_value + Σ register (stake + pending + rewards) + program_rand_held
               ==  genesis_deposited + genesis_staked + faucet_minted − slashed − registration_fees_burned

program_rand_held와 program_rand_out은 체인 20(RPL-2)에서 새로 추가되었습니다. Invoke가 burn_r을 통해 프로그램 볼트로 소각하는 RAND는 풀 쪽에서는 burned에 계산되고 볼트에 보유되며, 볼트가 노트로 지급하는 양은 풀로 돌아옵니다. rand_getSupply는 둘 다 invariant_holds와 함께 제공합니다.

faucet mint만이 체인이 발행한 총량을 늘리며, chain 20에서는 소각된 등록 수수료만이 그 총량을 줄입니다. slashed는 슬래시된 aggregator 본드를 집계하거나, 제네시스 staking.slashing 섹션이 있는 경우에는 슬래시된 validator 스테이크를 집계하는데, chain 20에는 둘 다 없습니다(aggregation은 꺼져 있고 slashing은 null입니다). 본드, 수수료, withdraw, vault 예치는 풀, 레지스터, vault 사이에서 가치를 이동시킬 뿐 새로 만들어 내지 않습니다. Supply에 카운터와 계산 예시가 있습니다. 블록 aggregation 보조금, 즉 halving 일정에 따라 봉인된 블록마다 새로 발행되어 deposit note 형태로 aggregator에게 지급되는 RAND는 최초의 예정된 발행이 되겠지만, chain 20에서는 활성화되어 있지 않습니다.

fullnode 커밋 c0878c3f(chain 21) 기준으로 2026-10-12에 마지막으로 검증되었습니다. 코드와 이 페이지의 내용이 다를 경우 코드가 옳습니다. 알려 주시기 바랍니다.