区块链是“价值互联网”的基础协议。HTTP协议是“信息互联网”的基础协议。两者都是建立在TCP/IP协议之上的应用层协议,同是互联网的两大基础协议
一.比特币
2009年1月3日出现Bitcoin
矿工通过创造一个新区块得到的比特币数量大约每四年(或准确说是每210,000个块)减少一半.2140年之后,不会再有新的比特币产生。
一个比特币可以拆分到小数点后8位
UTXO:Unspent Transaction Outputs 未花费交易输出,它是比特币交易过程中的基本单位。避免双花。transaction-based Ledger。隐私保护性好,需要显式说明币的来源
以太坊是account-based Ledger
Merkle树:数据结构。 计算机领域,多用来进行完整性验证处理
加密算法:ECC(椭圆曲线算法)
准匿名(pseudoanonymous)交易机制
二.EVM
EVM是基于栈的虚拟机
以太坊的PoW算法叫Ethash算法
密码学Hash算法
性质
- 抗碰撞性(计算上成立,数学上不成立)
- 原像不可逆
- 谜题友好
密码学
非对称加密,常用RSA, ECC(椭圆曲线算法).应用
:数字证书(CA认证),比特币地址
- 公钥:加密. 私钥:签名
编码
相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I"(大写i),和字母小写"l"(小写L),以及"+"和"/"符号
区块链特点
- 去中心化
- 不可篡改
- 匿名性
- 可溯源
区块链发展
应用
- V1.0 数字货币(可编程货币)
基于栈编程,图灵不完备(无循环语句,不能实现复杂编程) - V2.0 智能合同(可编程金融)
图灵完备(可以用代码实现各种复杂逻辑) - V3.0 高级智能合同(可编程社会)
智能合约(smart contract)
分布式账本技术(Distributed Ledger Technology,简称DLT)
在DLT中,实施者对它的实现方式有更大的控制权.
区块链:技术和结构分散化,组织和发展也是分散化的。在DLT中,技术是分散的,但它的公司组织可能不是。
节点
轻节点SPV(Simplifed payment verification)
手机端钱包,只同步所有的区块头信息以及和自己相关的交易数据.认证
Token
以太坊代币eth,燃料为gas,最小单位wei,1ether=10^18 wei
hash算法:一段原文产生摘要算法,相同的原文产生同样的摘要
白皮书:业务 . 黄皮书:技术
空块攻击:只出块,不打包交易!或者频繁大量只有1笔新币交易,而没有其它交易的块,其实空块并非绝对空,还是有一笔的。只是说没有打包其它交易。
另外个别情况下偶尔一次,也没有问题,但短期内频繁空块就是攻击了,其效果是使交易内存池变大,交易平均确认时间变长。其实已经有很多矿池消灭了空块的,技术上没有难度的。打包空块并不会比打包满块有优势。但是有ASICBoost专利就不同了,空块有利于ASICBoost专利的实施
粉尘攻击:大量低额,低手续费的垃圾交易,让网络拥堵!
女巫(sybil)攻击:在 P2P 网络中,节点是可以随时加入和退出的。为了维持网络稳定,同一份数据通常需要备份到多个分布式节点上,这就是数据冗余机制。单个恶意节点伪装多重身份,把原来要备份到多个节点上的数据欺骗到了同一个恶意节点,这种攻击数据冗余机制的手段,就叫做女巫攻击。地址占投票多数
SPV原理
UTXO的定义
区块链进阶:——简单支付验证(SPV)
简单支付验证(Simplified Payment Verification,简称SPV)是一种无须维护完整的区块链信息,只需要保存所有的区块头部信息即可进行支付验证的技术。该技术可以大大节省区块链支付验证用户的存储空间,减轻用户存储负担,降低区块链未来交易量剧增而给用户带来的压力。以比特币系统为例,节点只需保存所有区块头信息,即可进行交易支付验证。节点虽然不能独立验证交易,但能够从区块链其他节点获取交易验证的必要信息,从而完成交易支付验证,同时还可以得到整个区块链网络对交易的确认数。
要理解SPV的概念,首先需要理解如下两类概念的区别。
一是SPV与轻钱包(或瘦客户端)的区别。轻钱包指的是节点本地只保存与其自身相关的交易数据(尤其是可支配交易数据),但并不保存完整区块链信息的技术。SPV的目标是验证某个支付是否真实存在,并得到了多少个确认。比如爱丽丝(Alice)收到来自鲍伯(Bob)的一个通知,鲍伯声称已经从其账户中汇款一定数额的钱给了爱丽丝。如何快速验证该支付的真实性,是SPV的工作目标。轻钱包或瘦客户端的目标不仅是支付验证,而且是用于管理节点自身的资产收入、支付等信息。比如爱丽丝使用轻钱包或瘦客户端管理自身在区块链的收入信息、支出信息,在本地只保存与爱丽丝自身相关的交易数据,尤其是可支配交易数据。轻钱包与SPV的最大区别是,轻钱包节点仍需下载每个新区块的全部数据并进行解析,获取并本地存储与自身相关的交易数据,只是无须在本地保存全部数据而已。而SPV节点不需要下载新区块的全部数据,只需要保存区块头部信息即可。虽然轻钱包或瘦客户端中部分借鉴了SPV的理念,但和SPV是完全不同的。
二是区块链支付验证与区块链交易验证的区别。SPV指的是区块链支付验证,而不是区块链交易验证。这两种验证方式存在很大的区别。区块链交易验证的过程比较复杂,包括账户余额验证、双重支付判断等,通常由保存区块链完整信息的区块链验证节点来完成。而支付验证的过程比较简单,只是判断该笔支付交易是否已经得到了区块链节点共识验证,并得到了多少的确认数即可。还是以比特币系统为例,用户爱丽丝收到来自鲍伯的通知,鲍伯声称已经从其账户中汇款一定数额的钱给爱丽丝。爱丽丝进行交易验证的过程如下:首先,爱丽丝遍历完整的区块链账本,在区块链账本的交易中保存了鲍伯的历史交易信息(包括鲍伯的汇款账户、鲍伯的签名、历史收款人的地址以及汇款金额信息等),查询鲍伯的账户,就可以判断鲍伯提供的账户是否有足够的余额,如果余额不足则交易验证失败;其次,爱丽丝要根据区块链账本判断鲍伯是否已经支出了这个账户上的钱给别人,即是否存在双重支付问题,如果存在则交易验证失败;最后,判断鲍伯是否拥有其提供账户的支配权,如果判断失败则交易验证失败。而如果爱丽丝只是进行支付验证,则过程简单得多:通过SPV,爱丽丝可以进行支付快速验证,即检查此项支付交易是否已经被收录存储于区块链中,并得到了多少个确认数,就可以判断支付验证的合法性。详细的技术原理如下。
(一)SPV的技术原理
在区块链中,区块信息主要包括区块大小、区块头、交易数量和交易信息四部分内容。其中,区块头大小为固定字节,比如比特币中区块头的大小始终为80字节。区块头中一般包括如下信息:前一区块(也称父区块)的哈希值、区块中交易默克尔树的根哈希值、时间戳等。以比特币为例,其区块头的数据结构如表3-1所示。
表**3-1 **区块头的数据结构
通过区块的哈希值,可以识别出区块链中的对应区块。区块前后有序链接,每一个区块都可以通过其区块头的“前一区块的哈希值”字段引用前一区块。这样把每个区块均链接到各自前一区块的哈希值序列就创建了一条一直可以追溯到第一个区块(创世区块)的链条。前一区块的哈希值,可以确保区块链所记录的交易次序。默克尔树的根哈希值则可以确保收录到区块中的所有交易的真实性。
区块链节点利用SPV对支付进行验证的工作原理如下:
①计算待验证支付的交易哈希值;
②节点从区块链网络上获取并存储最长链的所有区块头至本地;
③节点从区块链获取待验证支付对应的默克尔树哈希认证路径;
④根据哈希认证路径,计算默克尔树的根哈希值,将计算结果与本地区块头中的默克尔树的根哈希值进行比较,定位到包含待验证支付的区块;
⑤验证该区块的区块头是否已经包含在已知最长链中,如果包含则证明支付真实有效;
⑥根据该区块头所处的位置,确定该支付已经得到的确认数量。
上述方法可以减轻用户的负担。以比特币为例,无论未来的交易量多大,区块头的大小始终只有80字节,按照每小时6个的区块生成速度,每年产出52560个区块。当只保存区块头时,每年新增存储需求约为4兆字节,100年后累计的存储需求仅为400兆字节,即使用户使用的是最低端的设备,正常情况下也完全能够负载。
SPV的工作原理中,最为关键和复杂的是步骤③,节点从区块链获取待验证支付对应的默克尔树哈希认证路径的过程。例如,一个区块链节点想要知道其钱包中某个比特币地址即将到达的某笔支付,该节点会在节点间的通信链接上建立起布鲁姆过滤器,限制只接受含有目标比特币地址的交易。当节点探测到某交易符合布鲁姆过滤器的要求时,将以默克尔区块消息的形式发送该区块。默克尔区块消息包含区块头和一条连接目标交易与默克尔树根的默克尔哈希认证路径。默克尔树哈希认证路径是验证待验证支付是否存在于默克尔树的关键条件,该认证路径由默克尔树所有路径中节点的哈希值共同构成,自下而上进行哈希计算。节点能够使用该路径找到与该交易相关的区块,进而验证对应区块中该交易的有无。如图3-1所示为根据交易A、B、C、D、E、F、G、H生成的默克尔树。这是一棵自下而上通过哈希运算生成的二叉树。叶子节点为交易信息的哈希值,叶子节点两两进行哈希运算得到其父节点,继续此过程,直至生成默克尔树根节点。需要注意的是,如果存在单个叶子节点无法匹配成对,则用复制的方法构成完整的二叉树,比如图3-2中交易H不存在,则可以将交易G的哈希值M(G)复制一份替代M(H),从而完成二叉树的生成过程。
图**3-1 **交易默克尔树结构示意图
图**3-2 **默克尔树哈希认证路径示意图
假设待验证交易为E,则交易E的默克尔树哈希认证路径为图3-2虚线框所示的M(F)、M(GH)和M(ABCD)。通过该哈希认证路径,即可以通过哈希计算找到一条链接交易E与默克尔树根的完整路径。
(二)SPV的功能扩展
虽然SPV可以高效地进行支付验证,但对于节点当前状态(账户余额、账户信息甚至合约状态等)均无法给出证明。SPV能否扩展并更进一步呢?以太坊对SPV的功能进行了扩展:每一个区块头,并非只包含一棵默克尔树,而是包含了三棵默克尔树,分别对应了三种对象——默克尔交易树、默克尔收据树和默克尔状态树。其中默克尔收据树和默克尔状态树是比特币等现有区块链系统没有的。默克尔收据树是由展示每一笔交易影响的数据条构成的默克尔树。而在默克尔状态树中,则保存账户信息、账户余额等信息。三棵默克尔树的功能分工如下。
①默克尔交易树:保存交易信息,用于验证交易是否真实包含于区块链中。
②默克尔收据树:保存某个地址的历史事件实例,比如一个交易是否成功执行、一个众筹合约是否完成了目标等。
③默克尔状态树:保存了账户名称、账户余额等信息。
基于上述三棵树,以太坊不仅可以实现SPV的支付验证,而且可以快速验证账户是否存在、了解账户余额甚至快速判断交易是否执行成功等信息,实现了良好的SPV扩展。
(三)SPV面临的问题
SPV面临的第一个是问题是SPV节点与区块链系统去中心化程度似乎存在一定的矛盾。随着SPV节点数量的增多,那么区块链参与完整验证的节点数量就会减少。然而,SPV却不能完全独立构成区块链。由于SPV节点没有存储完整的区块链信息,SPV的实现离不开存储区块链完整信息的节点或系统的辅助。
SPV面临的第二个问题是交易可锻性攻击 [19] 。由于SPV实现中一个关键步骤是根据支付哈希值定位其在区块中的位置,而该过程可能遭遇交易可锻性攻击。比如比特币系统中,交易可锻性攻击体现在交易ID(账号)可被伪造,而交易ID可被伪造的原因是比特币签名算法不够完善。以比特币为例,交易可锻性攻击的过程如下:在比特币的交易中,第三方交易系统会将交易发送方、接受方、交易金额等数据作为一个交易发送到比特币网络中,发送之前会对这条交易信息进行加密和签名,接着根据生成的签名最终获得一个哈希值,这个哈希值作为交易ID返回给提现的用户。一次交易请求过后,用户接收到的仅有一个交易ID,根据这个交易ID可以查看交易是否成功。当交易发送到比特币网络中后,网络中的各个节点会根据之前生成的签名来验证交易的真实性。问题就出在签名算法上:椭圆曲线数字签名ECDSA这个算法的一个问题是,修改签名的某个字节能够使签名依然校验成功,这样伪造签名之后交易依然能够成功进行。由于交易ID是根据签名生成的,而伪造之后的签名会生成一个完全不同的交易ID,第三方判断到两个ID不同便会确定当前交易失败,而事实上交易已经成功了。这时如果用户发现交易提示失败,可以再次发起交易,第三方交易系统一看之前交易确实失败了,那就会再进行一次交易。这时用户的比特币钱包里就会多收到一份比特币,也就造成了第三方交易平台资金损失。交易的可锻性体现在虽然交易签名被“锻造过”(即修改伪造过),但最终的交易依然有效。上述攻击对于SPV是有效的,因为在交易可锻性攻击场景中,伪造的交易和正常的交易都在区块链网络中,如果伪造的交易先被处理,那么攻击就成功。从而,SPV支付在区块链中的位置定位过程可能无法完成或出现错误,最终影响支付验证的进程和准确性。
有人提出可以通过改进SPV的工作流程来提升攻击防范的有效性,比如不再仅根据哈希值来判断支付的状态,而是使用双因素或者多因素验证,包括账户余额、支付信息追踪等来综合判断支付是否真正成功,但这会增加SPV的复杂度。如何更加有效地解决SPV面临的问题还值得进一步研究