技术 › 网络
交易结构
门罗币交易的字节里有什么:前缀、RingCT 签名与可修剪部分
简而言之
一笔交易 = 前缀(版本、输入、输出、extra)+ RingCT 基础部分(类型、手续费、加密金额、输出承诺)+ 可修剪部分(Bulletproofs+、CLSAG、伪输出)。交易哈希由这三部分的哈希构成,因此旧节点可以丢弃可修剪部分(修剪,pruning),而交易依然可以验证。
前缀
version = 2
unlock_time = 0 // 遗留字段,现在始终为 0
vin[]: // 输入
txin_to_key:
amount = 0 // 金额隐藏在 RingCT 中
key_offsets = [g₀, Δ₁, …, Δ₁₅] // 16 个全局索引,以相对偏移存储
k_image = I // key image,32 字节
vout[]: // 输出
amount = 0
target: txout_to_tagged_key
key = P // 一次性公钥,32 字节
view_tag = 1 byte
extra = [0x01 ‖ R, …] // 交易公钥及其他内容
key_offsets 以差值形式存储:第一个是该输出的绝对索引,其余是与前一个的距离。数字越小,用 varint 编码时占用的字节越少。
RingCT 基础部分
type = 6 // RCTTypeBulletproofPlus
txnFee = fee in atomic units (varint)
ecdhInfo[] = encrypted amount, 8 bytes per output
outPk[] = commitment C, 32 bytes per output
可修剪部分
bulletproofs_plus[] = one aggregated proof
CLSAGs[] = { s[16], c1, D } per input
pseudoOuts[] = C̃, 32 bytes per input
交易哈希
txid = Keccak( H(prefix) ‖ H(RingCT base) ‖ H(prunable) )
这种“三个哈希组成的树”让修剪节点可以丢弃旧交易中体积庞大的证明(只保留哈希),同时仍能计算出 txid。
手续费
手续费取决于交易的权重(≈ 字节大小,并针对 Bulletproofs+ 做了调整,使多输出交易不会便宜得不成比例)以及优先级。每字节的基础费率会根据区块大小中位数自动调整——参见动态区块大小。
FCMP++ 带来的变化
- 取代
key_offsets的是对某个区块的引用,证明基于该区块时的树状态构建。 - 取代 CLSAG 的是成员证明和 SA+L;key image 保留。
- 输出格式改为 Carrot(3 字节 view tag、Janus 锚点)。