BTC 区块链原理
Posted LeoHsiao1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BTC 区块链原理相关的知识,希望对你有一定的参考价值。
区块链(block chain):一种分布式数据库技术。以区块为单位存储数据,区块们以哈希链的形式串联,因此防伪。
- 区块链起源于比特币(BTC),用于记录交易信息,每笔交易相当于 SQL 数据库的一个事务。
- 本文主要分析比特币协议中的区块链原理(协议更新之后,一些细节可能变化)。
- 参考资料:
区块结构
-
如下图,一条区块链由多个区块串联组成,后一个区块会记录前一个区块的哈希值,构成哈希链。
- 哈希运算时采用 SHA256 算法。
- 存储字节流时采用小端序。
- 每个区块采用递增的序号作为标识符,又称为区块高度(Height)。
- 每个区块最多允许包含 1MB 的数据,超过则视作无效区块。
-
一个区块在结构上分为两部分:
- header :用于存储该区块的元数据。
- body :用于存储交易信息。
-
区块 header 的长度固定为 80 bytes ,按顺序记录以下信息:
- nVersion
- :区块链协议的版本。
- 4 bytes ,int32_t 。
- previous block header hash
- :上一个区块的 header 的哈希值。用于确保它们不会被篡改。
- 32 bytes ,char[32] 。
- merkle root hash
- :当前区块 body 中所有交易信息的 Merkle Tree 的根哈希。用于确保它们不会被篡改。
- 32 bytes ,char[32] 。
- timestamp
- :矿工打包当前区块时的 Unix time 时间戳。必须大于前 11 个区块的平均时间戳、不大于当前实际时间 +2 小时。
- 4 bytes ,uint32_t 。
- nBits(target threshold)
- :nonce 的目标阈值。
- 4 bytes ,uint32_t 。
- nonce
- :一个随机数。
- 4 bytes ,uint32_t 。
- nVersion
挖矿难度
- 矿工打包新区块时,需要尝试指定 nonce 值,比如穷举。如果使得当前 header 的哈希值小于等于 target threshold ,则有权打包该区块,被其他矿工承认。
- SHA256 哈希值的长度为 32 bytes ,而 target threshold 以有损压缩形式存储为 nBits ,长度为 4 bytes 。
- 例:根据 nBits 计算出 target threshold
>>> nBits = int('0x170cfecf', 16) # 假设 nBits 的取值 >>> target = 256**(int('0x17', 16) - 3) * int('0x0cfecf', 16) # 将第一个字节作为 256 的幂,再乘以后三个字节 >>> '0x' + ":064x".format(target) '0x0000000000000000000cfecf0000000000000000000000000000000000000000'
- 可见 nBits 第一个字节的值越大,会使 taget 越大,开头连续的 0 越少,因此挖矿难度越小。
- difficulty 表示挖矿难度。
- 计算公式如下:
diffculty = difficulty_1_target / target
- 可见 difficulty 与 target 成反比,取值越小则挖矿难度越小,最小为 1 。
- difficulty_1_target 表示区块链的初始难度,是一个常数:
>>> difficulty_1_target = 2**(256-32)-1 >>> '0x' + ":064x".format(difficulty_1_target) '0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff' >>> difficulty_1_target / target 21659675333681.926
- 当 difficulty 为 1 时,target 达到允许的最大值 ‘0x1d00FFFF’ 。因为有损压缩丢失了右侧的所有 ‘0xF’ ,所以有的程序会将 difficulty_1_target 计算成偏小的值:
>>> _target = 256**(int('0x1d', 16) - 3) * int('0x00FFFF', 16) >>> '0x' + ":064x".format(_target) '0x00000000ffff0000000000000000000000000000000000000000000000000000' >>> _target / target 21659344833264.848
- 丢失右侧 ‘0xF’ 的 difficulty_1_target 常用于快速估算难度,称为 bdiff(Bitcoin difficulty)。
- 标准的 difficulty_1_target 常用于正式挖矿,称为 pdiff(Pool difficulty)。
- 例:根据 nBits 估算出 difficulty
>>> nBits = int('0x170cfecf', 16) >>> difficulty = 256**(29 - (nBits >> 24))*(65535.0 / ((float)(nBits & 0xFFFFFF))) >>> difficulty 21659344833264.848
- BTC 预计每隔 10 分钟生成一个新区块。为了维持这一速率,会每隔 2016 个区块调整一次挖矿难度,重新计算 nBits :
expected_time = 2016*10 # 理论上最近 2016 个区块应该消耗 2016*10 分钟即 2 周 actual_time = ... # 实际上最近 2016 个区块消耗的时长 new_difficulty = old_difficulty * ( actual_time / expected_time ) new_nBits = ... # 根据 new_difficulty 算出 new_nBits
- 计算公式如下:
- 理论上,SHA256 哈希值有 2^256 种可能性,而 nonce 只有 2^32 种可能性,因此可能穷举 nonce 的所有值之后依然不满足 target threshold 。
- 例如 2020 年发布的蚂蚁矿机 S19 ,额定算力为 95 THash/s ,遍历 nonce 所有值的耗时不超过 1 秒:
>>> (2**32) / (95*10**9) 0.045
- 当 nonce 被穷举完时,矿工通常会在 coinbase 交易中使用一个 4 bytes 的随机数,称为 extraNonce ,从而增加到 2^64 种可能性。
- 例如 2020 年的比特币全网算力达到了 150 EHash/s = 150 * 10^3 PHash/s = 150 * 10^6 THash/s ,遍历 nonce + extraNonce 消耗的秒数为:
因此挖矿难度自动上调得很大,从而限制产生新区块的耗时依然为 10 分钟。矿工还需要用其它变量来增加可能性。>>> round((2**64) / (150*10**15)) 123
- 例如 2020 年发布的蚂蚁矿机 S19 ,额定算力为 95 THash/s ,遍历 nonce 所有值的耗时不超过 1 秒:
账户
-
BTC 协议中,用户可以根据 ECDSA 算法随机生成一对私钥、公钥,代表一个 BTC 账户,相当于一个银行账户的密码、账户名。
- 示例:
0xL3HpQs5M7tZLN1m6zmJ9YSPuFzA4gJDJy8Ru2hd5nAwcZC4tPm1T # 私钥 0x1N8nCD314Z87BgYsK1y3vwRpAk8S1qbRcg # 公钥
- 前缀 0x 表示十六进制。
- 私钥需要保密,而公钥公开给其他人。
- BTC 采用椭圆曲线数字签名算法(ECDSA)对交易数据进行数字签名,其中采用的椭圆曲线为 secp256k1 。
- 用户可以编写一个消息,将消息的哈希值用私钥加密之后公布,称为数字签名。其他人可使用对应的公钥解读数字签名,从而验证该消息的内容没有被篡改,并且是由该公钥对应的私钥签署的。
- 虚荣地址(Vanity Addresses):虽然 BTC 私钥、公钥是随机的,但用户可以尝试生成大量私钥、公钥,直到公钥中包含有意义的单词,比如 ILoveU 。
- bitaddress :一个网站,用于随机生成 BTC 账户,支持离线使用。
- 示例:
-
生成一对私钥、公钥的步骤:
-
用户生成一个很大的随机整数,作为私钥(private key)。
- 私钥的长度为 256 bits = 32 bytes 。通常经过 Base58Check 编码,表示成 52 位长度的十六进制数。
- 用户选择私钥时应该尽量随机,避免与其他人相同。
-
根据 ECDSA 算法,计算出私钥在椭圆曲线上对应的一个点,其坐标 x、y 作为公钥。
- 通过私钥可以计算出对应的公钥,但不能通过公钥反推出私钥。而且值域庞大,使得穷举几乎不可能。
- 未压缩公钥(uncompressed):拼接坐标 x、y 的值,并加上前缀 0x04 用于区分,总长度为 1+32+32 = 65 bytes 。
- 压缩公钥(compressed):只采用坐标 x 的值,并加上前缀 0x02 或 0x03 表示坐标 y 为偶数或奇数,总长度为 33 bytes 。
- 椭圆曲线关于 x 轴对称,一个坐标 x 对应两个 y 点。且在 secp256k1 曲线中,这两个 y 点分别为偶数、奇数,因此需要通过前缀区分。
- 使用压缩公钥时,需要给私钥加上后缀 0x01 用于区分,其长度增加 1 字节。
- 压缩格式的公钥、私钥更方便记录,是用户通常看到的格式,也是一般钱包采用的导入格式(Wallet Import Format,WIF)。
- 钱包软件在实际使用公钥时,会从压缩格式转换成非压缩格式。
-
计算压缩公钥的 SHA256 哈希值,再计算其结果的 RIPEMD-160 哈希值。
-
将公钥哈希值(public key hash)经过 Base58Check 编码,表示成 34 位长度的十六进制数,称为账户地址(address)。
-
-
Base58Check 编码是为了将数据表示成更短的值,并加上校验码,并不会加密原数据。过程如下:
- 输入原数据 payload 。
- 在 payload 之前加上 1 字节的地址版本号 version 。
- P2PKH 地址的 version 为 0x00 ,因此 base58 编码之后,开头为 1 。
- P2SH 地址的 version 为 0x05 ,因此编码之后,开头为 3 。
- BTC 私钥的 version 为 0x80 ,因此编码之后,未压缩格式的开头为 5 ,压缩格式的开头为 K 或 L 。
- 对 version-payload 计算两次哈希值,取开头的 4 字节作为校验码 checksum 。
- 如果网络传输之后,再次计算两次哈希值,发现开头与校验码不一致,则说明编码值出错。
- 在 payload 末尾加上校验码 checksum ,将 version-payload-checksum 进行 base58 编码。
- 与 base64 相比,base58 的特点:
- 移除了
+/
两个特殊字符,只允许使用大小写字母、数字。 - 移除了
0OIi
四个容易混淆的字母。
- 移除了
- 与 base64 相比,base58 的特点:
交易
-
block body 中可以包含 n≥1 笔交易(transaction),最大数量取决于区块的容量限制。
- 包含的第一笔交易必须是 coinbase 交易。
- coinbase 交易不存在输入,凭空产生一定量可以输出的 BTC ,作为打包该区块的矿工的奖励。
- 其后可以包含 m≥0 笔普通交易。
- 当交易被保存到区块中之后,其内容就不能被改变。
- 通常采用交易的哈希值作为其标识符,称为 txid 。
- BTC 交易时,最小的单位为聪(satoshis)。1 BTC = 10^8 聪。
- 包含的第一笔交易必须是 coinbase 交易。
-
一个交易主要包含以下内容:
- version :交易格式的版本号,占 4 bytes 。
- in-counter :表示输入项的数量。
- inputs :包含 n≥1 个输入项。
- 每个输入项的主要内容:
- index :输入项在 inputs 中的序号,从 0 开始递增。
- previous txid :指向输入的 BTC 来自的之前交易。这会将该交易的 UTXO 全部输入当前交易。
- sigScript
- 每个输入项的主要内容:
- out-counter :表示输出项的数量。
- outputs :包含 n≥1 个输出项。
- 每个输出项的主要内容:
- index
- value :输出的 BTC 数量。
- pkScript
- 一个交易的总输入减去总输出的差值,会被矿工作为手续费,即
fee = sum(inputs) – sum(outputs)
。
- 每个输出项的主要内容:
- locktime :表示允许将该交易打包到区块中的最早时间,占 4 bytes 。
- 如果取值小于 5 亿,则视作区块高度。
- 如果取值大于 5 亿,则视作 Unix 时间戳。
- 交易通常将 locktime 设置为 0x00000000 ,表示不限制。
-
如果一个账户收到了一些 BTC ,则可以发起一笔交易,输入一些 BTC ,然后输出给其它账户。
- 所有账户收到的 BTC ,都来自历史交易的输出,且源头都是 coinbase 交易。
- 如果一个交易输出的 BTC ,尚未被目标账户花费,则称为未花费交易输出(Unspent TX Output,UTXO)。
- 一个账户拥有的所有 UTXO ,称为该账户的余额。
- 一个交易的 UTXO 必须被一次性全部花费。例如 UTXO 为 5 BTC 时,用户可以新建一个交易,转账 1 BTC 给别人,然后将剩下的 BTC 转账给自己。
- 统计 BTC 区块链上发生的所有交易的输入、输出,就可以知道所有账户的余额。
- BTC 并没有提供直接查询账户余额的数据库,但一些区块链浏览器提供了这种查询功能。
-
发起一个交易的过程如下:
- 用户编写一个交易。
- 用户生成交易的 sigScript ,存放在交易的 inputs 中。
- 用户将交易广播到 BTC 网络上,等待矿工将它打包入新区块。
sigScript
:签名脚本(Signature Script,sigScript)。
- sigScript 包含以下内容:
- pubKey :账户公钥
- sig :使用账户私钥,生成交易数据的数字签名。
- 交易延展性(Transaction Malleability)攻击
- :一种攻击方式,指改变未打包交易中的签名,使得交易的哈希值改变,导致引用该交易 txid 的其它交易失效。
- 由于椭圆曲线的对称性,可以计算出两个有效的签名,还可以根据任意一个签名推算出另一个签名。
- 常见的解决办法:
- 等待一个交易被打包,再引用它的 txid 。但这就不能实现闪电交易。
- 规定只采用取值较小的那个签名。
- 使用 SegWit 。
- :一种攻击方式,指改变未打包交易中的签名,使得交易的哈希值改变,导致引用该交易 txid 的其它交易失效。
pkScript
:公钥脚本(Pubkey Script,pkScript),采用一种基于堆栈的脚本语言,包含一些指令。
-
pkScript 可以声明一些条件,当 sigScript 满足条件时才能花费 UTXO 。
- 比如 P2PKH 通常的条件是:输出 n 个 BTC ,并指定一个公钥。只有拥有该公钥对应私钥的人,才有权花费该 UTXO 。
-
pkScript 又称为锁定脚本(locking script),因为它输出的 BTC 一直不可用,直到有人提供满足条件的 sigScript 。
-
pkScript 的几种类型:
- Pay To Pubkey(P2PK)
- :将 BTC 转账给公钥。
- Pay To Public Key Hash(P2PKH)
- :将 BTC 转账给公钥哈希。
- P2PK 常用于 BTC 早期的交易,后来被 P2PKH 取代。主要原因:
- P2PKH 使用公钥哈希,更短。
- P2PKH 使用公钥哈希,隐藏了公钥,提供了额外的安全性。直到用户花费该账户时,才会提供公钥。
- Pay To Script Hash(P2SH)
- :将 BTC 转账给脚本哈希。
- 如果其他人提供的 sigScript 中,包含与 P2SH 哈希一致的脚本,称为赎回脚本(redeem script),则有权花费该 UTXO 。
- 通过赎回脚本可实现复杂的功能,例如多重签名、SegWit 兼容地址。
- :将 BTC 转账给脚本哈希。
- Pay to Witness Pubkey Hash(P2WPKH)
- :与 P2PKH 类似,但启用了 SegWit 。
- Pay to Witness Script Hash(P2WSH)
- Null Data(空数据)
- :用于在 pkScript 中添加任意字节的空数据。
- Pay To Pubkey(P2PK)
隔离见证
:隔离见证,一种 BTC 的扩容方案,属于软分叉升级。
-
原理:给区块附加一个称为 witness 的结构,将交易中的见证数据(主要包含 sigScript )移出,存放在 witness 区域。
- 这会减小交易的一大半体积,可以在区块中打包更多交易。
- witness 区域的 tree 哈希记录在 coinbase 交易中,从而嵌入 Merkle Tree 。
- 此时的区块称为 SegWit 格式。基础容量(称为 size )依然限制为 1MB ,附加 witness 数据时的总体积(称为 weight )限制为 4MB 。
- 此时交易的哈希值称为 wtxid 。改变 sigScript 时,不会影响 wtxid ,避免了 Transaction Malleability 攻击。
-
使用 SegWit 时,账户地址有两种格式:
- 原生地址(Native):采用 Bech32 编码格式,只允许使用小写字母、数字,长度为 42 位,开头为 bc1 。
- 兼容地址(Nested):采用 P2SH 地址,开头为 3 。
- 原生地址地址的效率比兼容地址更高。
- 传统地址(Legacy)不支持与 SegWit 原生地址转账。
- SegWit 兼容地址支持与传统地址、SegWit 原生地址转账。
-
SegWit 软分叉还涉及到 BTC 社区的治理问题,相关历史:
- 2015 年,Bitcoin Core 开发人员提出了 BIP141 ,提议 SegWit ,是此时 BTC 变动最大的一次软分叉升级。
- 2016 年,Bitcoin Core 按 BIP9 方式开始 SegWit 软分叉,但支持 SegWit 的矿工远未达到 95% 的激活阈值,主要原因:
- SegWit 尚未推广,早期升级的收益较小。
- 旧区块可通过 AsicBoost 算法提高挖矿的哈希算力。
- SegWit 增加了区块的复杂性,需要修改很多客户端代码,不如硬分叉简单。
- 2017 年 2 月,社区的开发人员提出了 BIP148 ,提议用户激活软分叉(User Activated Soft Fork,UASF),逼迫矿工激活 SegWit 。
- BIP148 大意为:从 8 月开始,采用 BIP148 的节点会拒绝不支持 SegWit 的新区块,导致发生硬分叉。
- BIP9 让矿工投票决定软分叉升级,而 UASF 使得用户也拥有了控制权。但这更像一个抗议行动,不支持的矿工只是少了打包这部分用户交易的手续费收益。
- 2017 年 4 月,Charlie Lee 与矿工协商之后,成功在 LTC 上激活 SegWit 。
- 2017 年 5 月,一些公司和矿池签署了纽约共识(New York Agreement,NYA),表示作为激活 SegWit 的交换,要求也激活 SegWit2x 。
- 原理:与 SegWit 不同,直接将区块的基础容量限制从 1MB 增加到 2MB ,属于硬分叉升级
- SegWit2x 与 BCH 的区块扩容类似,受到 Bitcoin Core 开发人员的反对,最终在 11 月放弃了该提议。
- 2017 年 5 月,一个开发人员提出了 BIP91 ,使得 BIP148 与 SegWit2x 两派可以兼容,避免发生硬分叉。
- BIP91 的内容与 BIP148 相似,但没有限制时间。
- BIP91 部署之后,激活它的阈值为 80% 。当 BIP141 被激活或失败时,BIP91 就会停止。
- 2017 年 7 月,市场担心 BIP148 硬分叉的风险,BTC 价格从 $2700 跌到 $2000 ,促使矿工们支持 BIP91 并激活它。
- 2017 年 8 月,SegWit2x 终于激活。
- 此时,大部分矿工、钱包软件依然没有升级 SegWit 。但是采用 SegWit 原生地址的用户越来越多,为了服务这部分用户,矿工、钱包软件也会逐渐升级 SegWit 。
合约交易
多重签名
:多重签名(multi-signature,multisig),一种基于 P2SH 的交易方式。
- 原理:将 BTC 转账到一个 P2SH 地址,通过 pkScript 指定 n 个公钥,要求 sigscript 至少用 m 个对应的私钥签名才有效。
- 其中 1≤m≤n≤15 ,又称为 m-of-n 交易。
- 1of2 是允许两个账户中的任意一个都有权花费 UTXO 。
- 2of3 适合三方交易。例如 A 想花费 BTC 从 B 处购买商品,先将 BTC 转账到 2of3 多签地址。
- 如果仲裁方判断交易成功,则与 B 一起签名,将 BTC 转账给 B 。
- 如果仲裁方判断交易失败,则与 A 一起签名,将 BTC 转账给 A 。
- 没有 A 或 B 的同意,仲裁方不能私自转走 BTC 。
闪电交易
:闪电交易(Lightning Network,LN),一种 layer2 技术,基于链下交易(Off-Chain)。
-
原理:在区块链下进行任意数量的交易,然后将这些交易的结果保存到区块链。主要步骤如下:
- 开启通道:两个账号将一笔 BTC 转账到一个多签地址,暂时锁定,称为开启一个闪电交易通道(channel)。
- 使用通道:双方建立对等连接(Peer connection),私下进行一些交易。
- 关闭通道:双方根据交易结果,将多签地址的 BTC 分配给双方。
-
在通道中,双方私下进行的交易只需要互相知道,不必公布到区块链上,称为承诺交易(commitment transaction)。
- 每个承诺交易,表示此时的通道状态,即双方应该分别拥有通道的多少 UTXO 。
- 每创建一个新的承诺交易,就撤销旧的承诺交易。
- 为此双方要交换一个承诺撤销密钥,证明它已撤销。
- 如果一方将已撤销的承诺交易广播到链上,企图双花攻击。则另一方可以根据撤销密钥,广播一个更新的惩罚交易(Penalty transaction),将通道的全部资产转给自己。
- 每个承诺交易设置了 locktime ,如果某方离线,则另一方等待 locktime 时间之后就可以将承诺交易公布到链上,从而关闭通道。
- 每个承诺交易的 locktime 依次递减,因此越新的承诺交易能越早公布到链上。
- 准备关闭通道时,双方签署最后一笔承诺交易,立即公布到链上。
-
闪电交易通道只能连通两个账户,但大量相互开启通道的账户可以组成闪电交易网络。
- 假设 A 与 B 之间存在通道,B 与 C 之间存在通道,则 A 可以通过 B 间接转账给 C 。此时 B 称为路由节点,像计算机网络的路由转发。
- 哈希时间锁定合约(Hash Time Locked Contracts,HTLC):一种智能合约,用于保证路由节点的可信任。工作流程如下:
- A 创建一个密钥 secret ,私下发送给 C 。
- A 在 A、B 之间的通道,使用 secret 的哈希值签署一个 HTLC 合约,将 BTC 转入合约。合约大意为:如果 B 能在 locktime 时间内发现 secret ,则有权获得合约的 UTXO ,否则资金将返回给 A 。
- B 在 B、C 之间的通道,也创建一个使用同样 secret 哈希值的 HTLC 合约,请求 C 提供 secret 。但是合约锁定的 UTXO 微少一点,因为 B 收取了手续费。locktime 也更短一点。
- C 提供 secret ,完成 B 的 HTLC 合约,得到 UTXO 。然后 B 再提供 secret ,完成 A 的 HTLC 合约。
- 即使 B 下线,C 依然可以完成 B 的 HTLC 合约,只有 B 会受到损失。
- 一些大型的路由节点可连接大量用户,像中心化网络。
- 一些路由节点会担任瞭望塔(watchtower),监控网络,广播惩罚交易。
-
优点:
- TPS 很高
- 手续费很低:支付给路由节点的费用很低,适合以 satoshis 为单位的小额交易。
- 耗时短:每个交易不超过一分钟,不需要等待区块链打包、确认。
- 隐私:只有开启通道、关闭通道的两次交易需要公布到链上,期间的交易不会上链,路由节点也不会知道整个交易的源头、终点。
- 耗费区块空间小:通道中的交易不必保存到区块链。
-
相关历史:
- 2017 年 5 月,LTC 区块链进行了第一次闪电交易。
- 2019 年 1 月,twitter 用户发起了一场称为闪电火炬(Lightning Torch)的行动,用于推广闪电交易。
- 规则:通过闪电交易发送一笔小额 BTC ,收到转账的账户添加 10w satoshis 之后再发送给下一个账户,以此类推。
- 这笔 BTC 传递了将近 300 次,最终被捐赠。
CoinJoin
:一种混币方案。
-
原理:n 个账户共同发起一笔 BTC 交易,分别输入 C 数量的 BTC ,然后分别输出 C 数量到 n 个账户。
- 如果输出账户与输入账户都不同,则难以确定它们之间的对应关系,任一输出账户受某个输入账户所有人控制的概率是 1/n 。因此即使输入账户暴露了现实身份,输出账户也重新得到了匿名性。
- n 的数量越大,混淆度越高。
-
BTC 账户具有匿名性,但账户的交易过程、余额都是公开的,难以保护隐私。
- 例如用户 A 使用一个 BTC 账户在网上购物,转账记录都是公开的,其他人可以知道他购买的所有商品,推测他的消费习惯、个人喜好。
- 如果购物时的 IP 地址、物流信息被泄露,账户就失去了匿名性。即使 A 将 BTC 转入其它账户,其他人也知道新账户的地址,推测新账户很可能属于他。
- 例如用户 A 使用一个 BTC 账户在网上购物,转账记录都是公开的,其他人可以知道他购买的所有商品,推测他的消费习惯、个人喜好。
-
混币(Coin Mixing)
- :指混淆多个账户的交易过程,使得难以确定每个账户的收入来自哪个账户、支出去向哪个账户,只能知道每个账户收入、支出的数量以及余额。
- 常见的混币方案:
- 通过第三方平台转账:比如将币转入中心化交易所,再由从交易所转出到其它账户地址。但这样需要担心交易所的提现风险,而且交易所也能查出交易过程、记录 KYC 信息。
- CoinJoin
- 闪电交易也加强了隐私,但并不属于混币,而是避免交易过程上链。
以上是关于BTC 区块链原理的主要内容,如果未能解决你的问题,请参考以下文章
待更新北京大学肖臻老师《区块链技术与应用》公开课笔记 02-BTC-密码学原理