常见的数字货币基本模型
代表数字货币的不同架构和交易验证方式。
Account Based
基于账户的数字货币模型。
主要特点
- 账户地址:每个用户都有一个唯一的账户地址,类似于银行账户号码。这个地址用来标识用户的身份,并用于接收、存储和发送数字货币。
- 中央账本:所有账户的余额和状态信息都存储在中央账本中,所有交易都需要在中央账本上进行记录和验证。可扩展性,性能和隐私性不高。
- 交易处理:通常是通过修改账户余额来实现的。当一个用户向另一个用户发送数字货币时,相应的账户余额会相应地减少和增加。
UTXO Based
Unspent Transaction Output,基于未花费的交易输出模型,比特币就是采用的这种模型。
主要关注的是资金的来源和去向,每笔交易都有若干交易输入(也就是资金来源),同时也都有若干笔交易输出(也就是资金去向)。一般来说,每一笔交易都要花费(spend)一笔输入,产生一笔输出,而其所产生的还没有被下一笔交易花费的 Output ,就是“未花费过的交易输出”,也就是 UTXO。
主要特点
- 账户地址:UTXO 模型没有账户这个概念,每个用户管理的是一组私钥,对应一组公钥和地址。
- 交易细节:
- 每个UTXO都是一笔交易的输出,它包括一个特定的货币数量和一个公钥脚本,代表一定数量的数字货币。
- 当用户想要发起新交易时,他们需要选择足够的UTXO作为输入,然后将它们合并成新的UTXO来支付接收方。也就是所有的资金来源都必须要来自前面的某一个或者几个交易的UTXO( Coinbase 矿工奖励交易除外,没有输入只有输出)。且任何一笔交易的交易输入总量必须要等于交易输出总量。
- 任何交易都能够从输入溯源到 Coinbase 交易。
- 余额:用户的余额是钱包地址关联的所有的 UTXO 金额的和,也就是动态的,需要从创世区块开始扫描每一笔交易,如果遇到某笔交易的某个Output是钱包管理的地址之一,则钱包余额增加,反之遇到某笔交易的某个Input是钱包管理的地址之一,则钱包余额减少。
以比特币的为例,如图
比特币的隐私保护问题
比特币作为第一个电子现金系统,其使用的最核心的隐私保护措施就是交易假名和地址不可关联,但这是存在一些问题的。
公开账本信息泄露
我们知道,比特币使用的是UTXO,用户的钱包会管理很多地址,这些地址与用户本身没有任何关联,故能实现隐私。但是,由于比特币网络上的账本是公开可查询的,导致交易金额以及交易的历史是可查的。而交易的地址和金额都是明文的,如果不做一些安全措施的话,是可以通过对交易之间的关系以及交易时间的进行分析,是有可能分析出哪些地址是属于哪个用户的。比如,一笔交易中多个输入来自不同的地址但在统一交易中被用于创建输出,那么显然这多个地址就会属于某个单一用户。另外一些交易也会泄露额外的信息,比如交易留言,金额等等。
当然,最核心的问题是,比特币做不到深层次的隐私,由于现在很多时候都涉及到了实名制的问题,一旦某个地址与用户身份进行了绑定,那么等于隐私被暴露了,想再次进行隐私是很困难的,一旦最初的这个地址暴露以后,即使我们更换一个新的地址,把暴露地址中的币转入新地址,新地址和老地址之间关联性就非常明显。即便是自己做的防护措施挺好,但一旦与自己交易的那个地址暴露了,那么就可以从那个地址的持有者里拿到自己的信息。
通讯协议未加密
比特币的通讯协议是没有加密的,因此节点在进行消息传播的时候,是有概率泄露源IP和地址的对应关系的,同样也可以在网络中部署节点监听进行信息收集。
轻量级节点信息泄露
因为不是所有节点都有能力存储完整的账本,还有很多设备客户端是受限制的,比如手机,平板等等,上面使用的是轻量级密码算法和协议,在支付的时候是采用了简化的支付验证(SPV),这种方式不存储完整的区块链,也不验证系统种的所有交易,也可以让支付完成。它只默认连接随机的几个节点,而且只请求给定高度的区块,或者相关交易的过滤区块。这就产生了隐私问题,因为只读取特定交易区块而选择性的进行交易验证。
一些常用的隐私保护措施
两种隐私的理解方式
- Pseudonymous
**假名机制,**比特币这种机制是伪匿名的,叫做假名机制,即用户可以独立生成任意数量的地址,无需注册或者认证,同一用户之间的地址是无相关联的,那么仅仅凭借地址是没法找到用户的。但是就像前面提到的,可以通过对交易历史的分析是可以有很大概率找到联系的。就像网名和实名之间的联系。
这种链条状的交易历史可查会导致如果其中一个节点的信息暴露出来,那么整条交易链上的信息就会暴露出来。
- Anonymous
匿名机制,也就是用户什么相关信息都不透露,类似学校表白墙上发了信息,但是要求墙墙“狠狠的🐎”,它发了信息,但是你不知道任何有关它的信息。
CoinJoin
之前的交易中,由于交易是可见的,也是交易双方一一对应的,同一区块会存放多个交易,那么可以通过把输入和输出的地址进行打乱混淆,切断交易双方的联系,让别人无法分辨谁和谁是对应的交易双方,从而提升隐私性。
这就是混币,也就是地址混淆。这是不需要修改协议就能一定程度上提高匿名性的有效手段,有效抵抗交易图分析攻击。
但是这也不是完美的,因为如果要混合交易,那么双方的交易量必须得相似,不然还是很容易能找出联系。
中心化混币
也就是找一个可信机构来进行混淆,需要保证该机构不保存任何账本记录,也不认证用户的信息,这样数据外泄的时候就不会减少用户信息泄露。
但是也同样存在一定问题,如,
- 提供服务的机构会存在一定特征行为,比如混币交易的时间存在一些规律,会抽取一定手续费,存在一些常用的地址池等等,这会给攻击者提供一定分析材料,所以需要保证这种外部的隐私性。
- 机构知道了输入地址和输出地址,那它是有可能知道它们对应关系的,也有可能从中盗取货币资金,所以需要保证这种内部的不可链接关系。
一些解决方案
- 随机化
解决外部隐私问题,最容易想到的就是随机化,将一些固定的东西进行随机化,如,一定范围内的随机化交易时间,随机化交易手续费,在多个混币机构之间多混几次。这能起到一定程度的保护作用。
- 承诺+电子签名
这是用来解决机构和用户之间的信任问题,防止资金盗取的。也就是服务机构用自己的电子签名去做承诺,即约定好输入输出地址、混淆资产金额、约定时间等信息,并用混币服务商的长期公钥 对应私钥进行签名。出现问题时,用户就可以打开承诺向其他用户说明情况,进行证明。
- 盲签名
接下来是内部地址的不可链接性问题,需要服务提供商在不知道用户输入输出地址对应关系的情况下进行输入和输出阶段。这就用到了盲签名,它可以同时隐藏消息内容和签名请求者的隐私,满足
- 被签名消息对签名者是不可见的,即签名者不知道他所签署消息的具体内容。
- 签名消息不可追踪,即当签名消息被去盲化公布后,签名者无法将去盲化签名与盲化签名对应上。
盲签名的一般做法是,用户随机选择一个随机因子,然后与待签名的消息进行计算,让其与原消息没有关联,从而达到盲化。然后签名者对盲化的消息进行签名,从而不知道签名消息的内容。后续就是解盲签名和公布去盲化签名以及原始消息进行验证了。
去中心化
也就是无需第三方混币服务商。
用户在网络中找到其他需要混币的用户,通过多方参与者运行协议的方式构造一致的混币交易,确认后进行签名使得交易生效即可。
一般方式
分为协商、混淆、确认、结束四个阶段
- 协商阶段:用户寻找参与混币的其他同伴,协商去中心化混币协议需要的参数,例如各用户混币输入输
出地址、混币金额等参数。 - 混淆阶段:参与混币的用户根据协议对所有输出地址进行混淆,隐藏用户输入、输出地址之间的关联
关系。 - 确认阶段:混币用户根据混淆阶段得到混淆后的交易输出构造混币交易,确定无误后进行广播,将混币
资产发送到各用户指定的输出地址。 - 结束阶段:若混币协议正常结束,则参与混币的各用户销毁此次混币过程相关记录;若过程出现错误中
止,则参与混币的用户找出并且排除造成错误的用户。
同样去中心化混币也存在着一些不足,如寻找其他混币用户困难、容易让外部攻击者混入监听、DOS攻击、女巫攻击等等。
一些去中心化的方案
Confidential Transaction(CT)
混淆地址很麻烦,那么如果不隐藏地址而是把金额隐藏了呢?这就是私密交易CT,是站在密码学角度的。在CT中,每笔交易的金额会被加密成一个隐藏的数学证明,该证明可以保证交易的输入等于输出,以保持账户平衡,但不揭示金额。
隐藏可以通过加密来实现,但是又要满足可以进行一定的计算,那么自然而然能够想到 HE ,也就是同态加密。另外还需要注意到两个问题,
- 合理金额问题:当然为了使得交易金额在一个合理的区间,需要使用 Range Proof 来保证。以免出现金额为负数之类的问题。
- 所有权问题:也就是钱是不是属于自己的,或者说交易的人是否真的有那么一笔钱,解决方案有
- 通过特殊的交易,把普通的币转换为私密输出,然后就可以得到最早的第一笔CT,接着按照比特币的 UTXO 机制继续即可。
- 除了承诺和范围证明外,再加一份证明,证明交易的金额和整体账本上的金额符合的。
密码学方法除了可以隐藏金额以外,还可以隐藏交易双方的地址。
隐藏地址:主要思想是,每次发送者要发起一笔交易时,先利用接收者的公钥信息计算出一次性临时中间地址,然后将币发送到这个中间地址,,接收方再利用自己的公私钥信息找到那笔交易,从而进行花费,主要基于 DH 密钥交换。
**密码累加器:**这个是用来判定一个数据是否在某一集合的。主要概念是,将整个集合组合到一个较小的累加器数据中,达到以固定大小的证据证明某元素在累加器中的效果。
Zerocoin
也就是零币。
该方案,把比特币换成一个 Zerocoin 币,使用承诺隐藏交易细节,再从另一个比特币地址中换回 Zerocoin 币,割裂输入地址和输出地址的关系。Zerocoin 通过创建两种新的交易类型来扩展比特币:铸币交易 (mint) 和花费交易 (spend)。
主要思想:
用户可以独自进行混币操作,通过铸币交易将资产加入密码累加器,生成私密资产,达到和所有使用 ZeroCoin 的用户共同混币的效果。当用户需要使用之前加入累加器的资产时,根据参数生成凭证,证明自己拥有累加器资产集合中的某一未曾花费过的资产,花费该资产生成等额比特币 。
基本流程如下
- 铸币:
允许用户交换一定数量的比特币以制造新的 Zerocoin 币。每个 Zerocoin 币是使用随机数
r
r
r对序列号
s
n
sn
sn 的币承诺
c
m
cm
cm。即
c
m
=
C
O
M
M
r
(
s
n
)
=
g
s
n
h
r
cm = COMM_r(sn) = g^{sn}h^r
cm=COMMr(sn)=gsnhr
具体流程大致是
- 用户选择要铸造的金额。
- 用户创建一个随机的加密序列号,用于标识零币,同时保持零币的匿名性。
- 用户将所选金额的数字货币发送到一个特殊的零币铸造地址,并提供加密序列号作为证明。
- 一个零币铸造协议会检查交易的有效性,然后将等额的零币创建并发送给用户。
- 交易:
用户可以发出包括接收地址、序列号、和 spend 交易的 proof(证明自己知道秘密承诺
c
m
cm
cm和随机数
r
r
r),其中
c
m
cm
cm是过去经过铸币的,也就是存在于区块链上,可以通过承诺随机数
r
r
r打开
c
m
cm
cm以得到币的序列号
s
n
sn
sn。
具体流程大致为
- 用户选择要发送的零币金额,并提供接收方的零币地址。
- 用户提供以前铸造的零币的加密序列号作为证明,以表明他们拥有这些零币,并且可以合法地使用它们。
- 交易被广播到网络中,然后由矿工验证和包含在区块链中
Zerocoin 会构建相应的零知识证明,通过密码累加器累积所有的铸币承诺集合,然后证明该集合中相应的承诺随机数和集合中元素。 但在 Zerocoin 中, 计算累加器的见证 (witness) 需要访问目前为止的所有承诺。
零知识证明并不将花费交易与任何特定的铸币交易 (迄今为止所有铸币交易之间) 相联系。如果验证正确, 并且序列号以前没有被花费, 则将相应量的比特币发送到目的地址
同时缺陷也很多,如无法拆分金额,无法隐藏交易金额和接收方的地址,零知识证明的开销,验证时间大,然后每个节点需要存储的容量也大。
Zerocash
和 Zerocoin 同源的,是针对其缺陷的改进方案。主要使用了zk-SNARKs协议来保证交易之间的不可链接性,同时也对交易金额和输入地址保密。
主要思想:
Zcash是在比特币上增加一套匿名支付机制(DAP, Decentralized Anonymous Payment)得到的货币协议。
DAP 也可以搭建在其他底层货币上,是相互独立的,底层的货币称为 basecoin, 在其之上也增加了 shielded coin 和 transparent coin (unspent basecoin)的概念。相比于 basecoin(BC),shielded coin(SC)的所有权和金额都是隐藏的,暴露在外面的只有一个陷门承诺,其中包含了面值
v
v
v和暗地址
a
p
k
a_{pk}
apk。
同样zcash 也提供了两种交易铸币(Mint)和花费(Pour),铸币负责把BC 转换为 SC,花费则是负责 SC 的支付,同时它可以实现两种货币的转换。
部分细节如下
- **铸币(mint):**输入BC,输出等额的 SC 。
zcash地址对
(
a
p
k
,
a
s
k
)
(a_{pk},a_{sk})
(apk,ask),其中
a
p
k
a_{pk}
apk就是所谓的暗地址,假设要铸币值为
v
v
v的,用户首先随机选取
ρ
\rho
ρ,设置币的序列号
s
n
=
P
R
F
(
a
s
k
s
n
(
ρ
)
)
sn = PRF(^{sn}_{a_{sk}}(\rho))
sn=PRF(asksn(ρ))(显然序列号不能除拥有者之外的人知道,所以生成的时候是需要用到拥有者的私钥的)。
为了让验证者验证 SC 面值的正确性,需要对此做两次承诺。
- 第一次是对除了 v v v以外的所有数据进行承诺,放在一个陷门为 r r r的承诺 k = C O M M r ( a p k ∣ ∣ ρ ) k = COMM_r(a_{pk} || \rho) k=COMMr(apk∣∣ρ)中
- 第二次则是将 k k k和 v v v一起放在陷门为 s s s的承诺 c m = C O M M s ( v ∣ ∣ k ) cm=COMM_s(v||k) cm=COMMs(v∣∣k)中。
铸币的结果则是铸币承诺
c
=
(
a
p
k
,
v
,
ρ
,
r
,
s
,
c
m
)
c=(a_{pk},v,\rho,r,s,cm)
c=(apk,v,ρ,r,s,cm)和铸币交易
t
x
m
i
n
t
=
(
v
,
k
,
s
,
c
m
)
tx_{mint}=(v,k,s,cm)
txmint=(v,k,s,cm)
两步承诺的目的主要是验证 SC 的合法性的时候只需要公开
k
,
s
,
v
k,s,v
k,s,v,即铸币交易,任何人都可以验证,无需展示地址、序列号等信息,达到隐藏的效果。
- 交易(pour):
花费交易
t
x
p
o
u
r
=
(
s
n
1
o
l
d
,
s
n
2
o
l
d
,
c
m
1
n
e
w
,
c
m
2
n
e
w
,
v
p
u
b
,
π
P
O
U
R
,
∗
)
tx_{pour} = (sn_1^{old},sn_2^{old},cm_1^{new},cm_2^{new},v_{pub},\pi_{POUR},*)
txpour=(sn1old,sn2old,cm1new,cm2new,vpub,πPOUR,∗)
∗
*
∗中包含了新旧SC,输入两个旧的 SC(
c
1
o
l
d
,
c
2
o
l
d
c_1^{old},c_2^{old}
c1old,c2old) ,输出两个新的 SC(
c
1
n
e
w
,
c
2
n
e
w
c_1^{new},c_2^{new}
c1new,c2new),以及一个面值为
v
p
u
b
v_{pub}
vpub的 BC(大小可能为0)。
可以看到交易中还提供了旧 SC 的序列号,用于防止重复花费,当SC被花掉的时候必须要公布出来。
π P O U R \pi_{POUR} πPOURproof 能证明, s n 1 o l d , s n 2 o l d sn_1^{old},sn_2^{old} sn1old,sn2old是两个合法的序列号,也就是它们对应的承诺 c m 1 o l d , c m 2 o l d cm_1^{old},cm_2^{old} cm1old,cm2old存在于账本上,且可以打开;新的承诺 c m 1 n e w , c m 2 n e w cm_1^{new},cm_2^{new} cm1new,cm2new也是可以打开的;输入和输出是平衡的,即 v 1 o l d + v 2 o l d = v 1 n e w + v 2 n e w + v p u b v_1^{old}+v_2^{old} = v_1^{new}+v_2^{new}+v_{pub} v1old+v2old=v1new+v2new+vpub;对于旧SC c i o l d c_i^{old} ciold中承诺的 a p k i o l d a^{old}_{pk_i} apkiold,存在对应的 a s k i o l d a^{old}_{sk_i} askiold。
参考
UTXO模型
浅谈零知识证明:背景与起源
[1]李旭东,牛玉坤,魏凌波等.比特币隐私保护综述[J].密码学报,2019,6(02):133-149.DOI:10.13868/j.cnki.jcr.000290.
[1]张云聪. 高效可扩展的区块链隐私保护技术研究[D].上海交通大学,2019.DOI:10.27307/d.cnki.gsjtu.2019.003618.
[1]张奥,白晓颖.区块链隐私保护研究与实践综述[J].软件学报,2020,31(05):1406-1434.DOI:10.13328/j.cnki.jos.005967.