区块链金融:技术变革重塑金融未来
上QQ阅读APP看书,第一时间看更新

第2节
代码创富的技术逻辑与技术框架:比特币运行机制解析

一、比特币交易

比特币交易分为三部分:元数据、一系列输入和一系列输出。元数据存放内部处理信息,包含这笔交易的规模、输入数量、输出数量和哈希值,也是这个交易独一无二的ID,并有时间戳证明;所有输入排成一个序列,每个输入格式一样,包括之前那笔交易的哈希值、之前交易的输出索引(从0开始)、数字签名;所有输出排成一个序列,要和特定公钥(地址)对应,所有输出的金额之和必须小于或等于输入金额之和,二者差额部分作为交易费(激励)支付给为这笔交易记账的矿工。

举例说明,图2-8所示为与比特币类似基于交易的账本。

图2-8 与比特币类似基于交易的账本

其一,地址转换。由某个交易输出的比特币,要么在另一个交易被完全消费掉,要么一个都不被消费,不存在只消费部分的情况。交易1中爱丽丝获得了25个比特币,交易2中她必须把这25个比特币全部消费掉,所以她把17个比特币转给鲍勃,剩下8个币转给自己,而这8个币可以转到另外一个爱丽丝所有的地址(不同于交易1中获得25个币的地址)。

其二,有效验证。当新交易被加入总账本,比特币网络要验证这25个比特币之前有没有被花费掉,只需要从爱丽丝所引用的交易开始,一直核查到账本上最新记录的交易为止,而不需要从账本建立之初的交易开始核查,这样可以大大提高效率。

其三,资金合并。只需要发起一个交易,交易里有两个输入和一个输出,输出地址就是所得比特币(收益)。

我们列出一个真实的比特币交易程序段来阐释比特币交易三个部分。

二、比特币脚本

大部分比特币脚本都非常基础,每个交易输出不仅要确定一个公钥,同时还要指定一个脚本(输入脚本和输出脚本)。为了确认一笔交易正确获取了上一笔交易所输出资金(比特币),网络必须把交易输入脚本和上一笔交易输出脚本串联起来,只有在当前交易这个串联脚本被成功执行后才可获取资金(比特币)。输出脚本指定一个公钥(或是公钥哈希值地址),输入脚本也会指定一个对应公钥的签名。

常见比特币脚本如下。

OP_DUP
OP_HASH160
69e02e18……
OP_EQUALVERIFY
OP_CHECKSIG

比特币脚本语言是堆栈式、线性、无法循环执行和非图灵完备[1]的,只有256个指令。每个指令只有1个字节,只能被执行一次。因此,指令数目的执行时间和内存使用上限被硬性规定下来。矿工执行网络任一交易者递交的脚本,但设计者并不希望他们提交可能无限循环的脚本。

输入脚本和输出脚本举例如下,虚线下方是上一笔交易的输出脚本,虚线上方是当前交易的输入脚本,二者链接起来就成为一个新脚本。

<sig>
<pubKey>
————————————————————
OP_DUP
OP_HASH160
<pubKeyHash>
OP_Equalverify
OP_CHECKSIG

一些比特币脚本工作语言中的指令及其功能见表2-4。

表2-4 一些比特币脚本工作语言中的指令及其功能

在堆栈中执行一个脚本,只需要一个堆栈来累积数据,不需要分配内存和变量,因而堆栈语言只有两类指令(数据指令、工作指令)计算相对较为容易。数据指令用于把数据推到堆栈顶部。工作指令用于将堆栈顶部数据作为输入值,用来计算某个函数。

执行脚本过程如下:前两条指令是数据指令,分别是输入脚本签名和用来验证签名的公钥,直接把它们堆到堆栈最上面。接着执行复制指令OP_DUP,将堆栈最上层的公钥复制,并置于堆栈最上层。下一个指令是OP_HASH160,该指令取得最上层数据,并计算其哈希值,然后将结果再堆到堆栈最上层。接下来,执行pubkeyHash指令,将发送者指定的公钥哈希值堆到堆栈最上面。这时候,执行OP_EQUALVERIFY指令,检查堆栈顶部的两个数值是否相等,假设相等,也就代表接受者使用的是正确公钥,这条指令会移除堆栈顶部的两条数据。同时使用OP_CHECKSIG来检查签名,假如没有碰到任何差错,这个脚本输出的就是TRUE。脚本执行堆栈状态如图2-9所示。

图2-9 比特币脚本的执行堆栈状态图

比特币“销毁证明脚本”(proof of burn)也应给予关注,如果交易代码运行结果是将比特币转到“销毁证明脚本”,那么这笔比特币将被销毁,在实际应用中它主要被用来引导用户使用其他加密数字货币系统。

三、比特币脚本的应用

比特币有较完善的技术手段(脚本、矿工、交易验证等)保证强制执行全网共识的智能合约,而非通过法律、仲裁等中心化权威机构。

1.第三方支付交易(escrow transaction)

比特币第三方支付交易可以用“多重签名”(MULTISIG)实现。只要网络2/3用户签名,比特币即可完成点对点支付,并纳入全网监管。如果支付过程中出现争议,同样是2/3用户签名支持的那一方得到权益保障。

2.绿色地址(green addresses)

如果小王要将某笔比特币转账给小李,但是小李没有在线或者当时没有时间处理,无法通过查看比特币网络更新来确认小王转账是否完成。一般情况下,小王可以等待小李和网络确认,但是如果小王转账的目的是购买商品等用途,可能就无法等那么长时间。

为了解决这个时延问题,比特币采取了第三方交易所等金融媒介方式,交易方式从点对点改为了第三方参与。小王通知交易所需要转账给小李,如果小李在交易所也有账户,那么交易所从小王账户扣取费用,从交易所绿色地址转账给小李,而小李不需要实时查看交易所账户和比特币网络来确认交易。当然,小王和小李要信任交易所签名的交易,交易所也要保证不会进行双重支付等造假行为。另外,如果收款人小李信任交易所,他就无须信任转账人小王,这就实现了双方的无须信任交易。

Base58是比特币的一种特殊编码方式,主要用于产生比特币钱包地址。相比Base64等其他编码方式,Base58不使用数字“0”、字母大写“O”、字母大写“I”、字母小写“i”“+”和“/”符号,采用数学经常使用的进制转换方法——辗转相除法。

Base58设计的主要目的如下。

①避免混淆,在某些字体下,数字0和字母大写O,以及字母大写I和字母小写i会非常相似。

②Base64编码中包含“+”和“/”,非字母或数字的字符串作为账号较难被接受。

③在邮件系统中,使用字符和数字的组合不容易换行。

④大部分软件支持双击选中整个字符串。

比特币使用Base58算法对公钥Hash160及私钥编码,从而生成以1或者3开头的比特币地址,以及WIF(Wallet Import Format)格式的私钥。

3.高效小额支付(efficient micro-payments)

如果小王是小李的客户,需要持续向小李支付小额费用(比特币),但多次小额支付会产生较大网络流量费和交易手续费,解决方案是将多次小额费用累积起来,最后一次性支付。

小王先发起一个MULTISIG交易,把可能花费的最大金额先转到MULTISIG地址,这个交易需要小王和小李两个人签名才有效。小王在每次转账时签名一次,直到所有转账完成,这些转账交易只有小王签名,小李没有签名,因而没有放到比特币网络记账。小李在小王最后一笔转账里签名,并把小王所有转账信息记账到比特币网络。

4.退款锁定时间

如果小王所有转账完成后,小李没有在最后一笔转账里签名,那么小王转给小李的比特币可能会存放入第三方交易所,损失掉他转到MULTISIG地址的所有比特币。为了解决这个问题,小王和小李需要预先约定退款锁定时间。比特币元数据有一个参数“lock_time”,在此参数上可以填写具体时间值t。这个值告诉矿工在记账时,需要经过确定的t时间才能记账到比特币网络,这笔挖矿方能生效,这个技术就解决了退款的锁定时间问题。

小王发起MULTISIG交易,陆续把比特币转入第三方交易所托管,如果过了退款锁定时间,小李还没有在最后一个转账交易里签字,小王则可以通过这个退款交易指令收回已转账的所有比特币。

四、比特币网络

比特币网络底层是一个运行在TCP网络上的点对点网络,有一个随机拓扑结构,在规则和技术上实现了所有节点平等,没有权限更高的主节点(超级节点),每个节点和其他随机节点相连,节点之间不需要信任,但可在比特币网络完成可信交易。每个节点既是服务者(如矿工),也是消费者。新节点随时可以加入,旧节点随时可以离开,因此比特币网络一直处于动态变化。比特币网络底层结构示意图如图2-10所示。

图2-10 比特币网络底层结构示意图

随着比特币网络发展,各地又出现了公共节点。2018年3月,公共节点达到历史峰值的11083个。排名前十名地区共有公共节点7792个,占总公共节点总数的79.3%,美国、德国,法国位列前三。比特币网络公共节点主要分布见图2-11。

图2-11 比特币网络公共节点主要分布

用户发起一个交易,需要通过洪泛算法[2](flooding algorithm)让整个比特币网络都知道。小王要转账比特币给小李,小王在客户端发起一个交易,把这个交易告诉与小王(节点)相连接的其他节点,这些节点核验后,决定是否转播这笔交易。如果核验通过,这些与小王相连接的节点会将交易转播给与其连接的节点。以此类推,直到小李接收这笔转账并在区块和网络记账。需要注意的是,在小李还没有确认前,每个节点会有一个交易池将接收的转播交易信息储存,但不会记账到比特币网络,只是用于避免这个交易在网络不停转播带来的效率降低和数据冗余。

每个节点收到一笔新交易信息时,会有四个环节核验:一是交易验证,针对每个前序交易输出,运行核验脚本;二是检查是否有双重支付;三是检查该交易信息在之前是否被接收过,默认保留最早接收的交易信息。用户也可以自行操作保留和转播收到的历次交易信息,如2013年以来有矿工为了获得更高收益,遇到交易冲突时,将手续费高的交易放入自己的交易池,将手续费低的交易替换出去;四是只接收和传播白名单标准脚本。

区块传播与交易传播类似。矿工挖到比特币,打包一个区块,将区块加入比特币网络,传播给该矿工相连接节点,以此类推转播出去。如果某个区块同时被多名矿工挖到,只有其中一个区块可以加入比特币网络,其他区块则被丢弃。哪个区块被确认取决于其他节点的共识和转播。

完全有效节点必须长期在线,才能接收比特币网络所有交易数据。一个节点离线时间越长,其保存的交易数据就越不完整。由于离线期间无法执行交易,只有重新上线后,把缺省交易数据重新下载更新,才能确保在比特币网络的所有权益(如交易、转播交易信息等),同时也会消耗较长时间。比特币网络完整交易数据(区块链)的存储空间在2016年年初已经超过50G,到今天已是庞大的数据量。

由于完全有效节点存储空间过大,用户难以实现快速查看、运行、核验脚本,也就出现了轻量节点(Lightweight Nodes),也称简单转账验证(Simple Payment Verification,简称SPV节点)。SPV节点通过某个比特币钱包软件实现,不会存储比特币网络所有交易数据,而是只下载和存储与用户有关的、用户关心的、需要核验的部分交易数据。

SPV节点的优势在于节省了大量存储空间,只需要几十MB存储空间即可,一部智能手机下载比特币钱包软件就能操作,但是SPV节点的安全性不如完全节点,不能核验某个区块所有交易的历史记录,因而只能依赖完全节点去核验没有存储的其他交易。

比特币网络是一个开源协议网络,由使用C++、Go等不同语言编写的不同软件系统无缝交互,兼容性强,即使部分软件出现问题,也不至于影响整个网络。为了确保交易及时有效,大部分节点会调用比特币早期核心代码开发者用C++语言编写的资源数据库(Bitcoind Library)。

由于比特币投资人、矿工、用户投入很大,规则改变的负面影响也会很大,那么比特币总数量和挖矿记账奖励也可能长期不变,但是比特币交易处理能力和效率急需提升。按照中本聪的白皮书,比特币区块大小限定在1MB,每个交易占用空间大致为250字节,每个区块最多容纳4000个交易。平均每隔10分钟有一个矿工获得记账权利,所以每秒只能处理7个交易,效率远低于以太坊等其他加密数字货币和银行等传统金融机构的记账能力。

如果要引入一些新特性来改善效率,则需要修改比特币规则协议,在操作上会非常复杂,很难判断所有节点都会达成共识并更新版本。修订协议分为硬分叉、软分叉两种类型。

硬分叉指通过修改协议引入新特性,可能使之前协议失效,造成运行新协议的节点认定有效的区块会被运行旧协议的节点认为无效,就会使比特币网络产生分裂,所有节点根据运行协议版本的不同扩展为两条不同的区块链(两个网络)。比特币现金就是硬分叉的典型案例。比特币硬分叉示意图如图2-12所示。

图2-12 比特币硬分叉示意图

如果比特币网络共识规则改变后,这种改变是向前兼容的,旧节点可以兼容新节点产生区块,则不会扩展为两条不同的区块链,即为软分叉。新规则下产生的区块会被旧节点接受,旧节点只是无法识别新规则的真实意义,新旧节点仍然处于同一条区块链,对整个系统的影响相对较小。

五、比特币的存储和使用

1.用户自己存储和管理比特币

用户把比特币存放在个人电脑、手机等联网智能终端,这是热存储方式,方便但不安全。将比特币存储在离线智能终端,这是冷存储方式,相对更加安全,但使用起来不方便。用户要有效区分和管理热存储、冷存储,需使用不同的私钥和地址。由于冷存储不在线,热存储必须通过相应技术手段找到冷存储地址,两者才能进行转账。

目前用得较多的解决方法是使用分层确定性地址机制的电子钱包(分层确定性钱包,Hierarchical Deterministic Wallet),它通过椭圆曲线密码学机制,在确保没有私钥参与的情况下,将公钥直接分散成子公钥,并且分散子公钥可以由分散子私钥认证,也就是冷存储端制造多个地址,并且热存储端能够知晓其制造的所有地址。

2.用户通过第三方机构提供服务来存储和管理比特币

一些专业公司为用户提供“在线钱包”服务。用户将密钥、交易等比特币的存储、管理等信息上传到云端服务器,通过网页或者APP客户端操作。由于在线钱包第三方运营公司存储了用户的比特币密钥,用户使用在线钱包登录密码保护密钥,所以用户需要信任第三方公司,并与之约定责权利。在线钱包的优势是方便,风险在于第三方公司及其技术人员掌握密钥,可能存在安全隐患。

一些比特币交易所也提供比特币存储服务,类似于银行存款业务,用户将比特币存储到交易所,以便在将来某个时间需要时提取比特币,或者兑换成法币。用户在交易所完成上述操作时,比特币网络并不会记录任何交易,交易所不需要在网络将比特币从一个地址转移到另一个地址,交易所和用户只需要签署和修改智能合约。交易所提供比特币存储服务的风险在于挤兑、黑客入侵、借新还旧等。

部分交易所会公开用户比特币存储信息,如公布用户姓名、比特币数量、市值等,用户据此可以计算交易所的存储规模(也可以理解为交易所需要兑付的负债规模),不过这种模式也存在用户隐私信息泄露、交易所瞒报假报信息等问题,因而一些交易所采取梅克尔树来描述用户比特币存储规模(也称为负债证明,Proof of Liabilities)。

技术原理如下:交易所构建一个梅克尔二叉树,每个叶节点为一个用户(储户),每个叶节点添加一个存储金额字段。每个叶节点存储金额字段保存用户比特币存储数量。每个节点存储金额字段等于最相邻两个子节点存款金额之和,根节点存储金额字段代表比特币存储总数量。用户可以要求交易所证明自己在梅克尔树上,以此判断自己的比特币是否安全。负债证明如图2-13所示。

图2-13 交易所梅克尔二叉树负债证明

交易所构建完梅克尔树负债证明后,把根节点(用户)哈希指针和存储金额字段进行加密签名,然后在比特币网络广播,并且声明交易所的所有用户都可以对应到叶节点,所有存储数据都是准确的,那么根节点存储金额字段就是用户在交易所的比特币存储规模和交易所负债证明。

3.交易费用

交易费用是用于补偿交易所、支付商、矿工处理某笔交易所付出的代价,具体金额可以由发起交易方自行设定,也可以采取链上用户提供的参考标准。用户支付交易费越高,其交易数据就会被更快、更安全地转播和记账。2015年以前,交易费在矿工收入中占比不到1%,因而大部分用户并不在意交易费收入和支出,但随着挖矿难度加大、挖矿奖励降低,交易费占比不断上升。目前,很多比特币钱包、交易所等第三方服务商都会收取标准化交易费用,用户的每笔交易都要缴纳一定比例的交易费。收取交易费成为第三方服务商的主要营收。

[1] 图灵完备:如果一门编程语言、一个指令集可实现图灵机模型里面的全部功能,或者说能够满足任意数据按照一定顺序计算出结果,就可称其具有图灵完备性。

[2] 洪泛算法:不要求维护网络拓扑结构和相关路由计算,仅要求接收到信息的节点以广播方式转发数据包。例如,源节点希望发送一段数据给目标节点,源节点首先通过网络将数据副本传送给它的每个邻居节点,每个邻居节点再将数据传送给各自除发送数据来的节点之外的其他邻居节点。如此继续下去,直到数据传送至目标节点或者数据设定的生存期限到0为止。