第一章 介绍
比特币组成(四个关键的创新点):
- 一个去中心化的点对点网络(比特币协议)
- 一个公共的交易账簿(区块链)
- 一个去中心化的数学的和确定性的货币发行(分布式挖矿)
- 一个去中心化的交易验证系统(交易脚本)
一个分布式计算问题的解决方案
中本聪的此项发明,对“拜占庭将军”问题也是一个可行的解决方案,这是一个在分布式计算中未曾解决的问题。这个问题包括了试图通过在一个不可靠的、具有潜在威胁的网络中,通过信息交流来达成一个行动协议共识。中本聪的解决方案是使用工作量证明的概念在没有中央信任即构下达成共识,这代表了分布式计算的科学突破,并已经超越了货币广泛的适用性。它可以用来达成去中心化的网络共识来公正选举、彩票、资产登记,以及数字化公证等等。
钱包和地址的关系:钱包是多个地址和解锁资金密钥的简单集合,每笔交易可以使用不同的地址,有利于提高隐私的安全性。用户可以创建地址的数量几乎不受限制。
第二章 比特币的原理
大多数钱包应用维护着一个含有用钱包自己密钥锁定的“未消费交易输出”小型数据库。完整客户端含有整个区块链中所有交易的所有未消费输出副本。
交易被包在一起放进区块中时需要极大的计算量来证明,但只需少量计算就能验证它们已经被证明。
任何比特币网络节点(其它客户端)收到一个之前没见过的有效交易时会立刻将它转发给连接到自身的其它节点。
新交易不断地从用户钱包和应用流入比特币网络,当比特币网络上的节点看到这些交易时,会先将他们放到各自节点维护的一个临时的未经验证的交易池中。
交易被加进新区块时,以交易费用高的优先以及其它一些规则进行排序。
矿工开始构建一个新区块时会包含一个特殊交易,将新生成的比特币(当前每区块为25比特币)作为报酬支付到矿工自己的比特币地址。
轻量级客户端通过确认一个交易在区块链中且在它后面有几个新区块来确认一个支付的合法性,这种方式叫做简易支付验证(SPV)
大多数情况下,比特币客户端会将多个小额支付聚合成一个大的支付,也许会将一整天的比特币收入聚合成一个交易。
第三章 比特币客户端
比特币核心(即比特币标准客户端)拥有交易账簿(区块链)的一份完整拷贝,里面记录了自2009年比特币网络被发明以来发生在比特币网络上的每一笔交易。2013年底大约是16GB。
bitcoind:命令行的比特币客户端
交易ID在交易确认之前并不权威。区块链中找不到交易哈希值并不意味着此笔交易没有进行,因为交易哈希值在区块确认之前时可以更改后。在确认之后txid时不变且权威的。
比特币核心默认建立包含仅与用户钱包相关交易的数据库。可以在bitcoin.conf配置文件中将txindex赋值为1来建立完整的交易索引。
bitcoin-cli getinfo 获得比特币核心客户端的状态信息
bitcoin-cli encryptwallet/walletpassphrase 加密钱包/解锁钱包
bitcoin-cli backupwallet/importwallet/dumpwallet 备份钱包/加载钱包/转储钱包
bitcoin-cli getnewaddress/getreceivedbyaddress/listtransactions/getaddressesbyaccount/getbalance
bitcoin-cli gettransaction/getrawtransaction/decoderrawtransaction
bitcoin-cli getblock/getblockhash
bitcoin-cli listunspent/gettxout/createrawtransaction/decoderrawtransaction/signrawtransaction/sendrawtransaction
第四章、第五章 密钥、地址、钱包
比特币的所有权时通过数字密钥、比特币地址和数字签名来确立的。
数字密钥实际上并不是存储在网络中,而是由用户生成并存储在一个文件或简单的数据库中,称为钱包。存储在用户钱包中的数字密钥完全独立于比特币协议,可由用户的钱包软件生成并管理,而无需区块链或网络连接。
公钥用于接收比特币,私钥用于比特币支付时的交易签名。
支付比特币时,比特币的所有者需要在交易中提交公钥和签名(每次交易的签名不同,但都是从同一个私钥生成)。比特币网络中的所有人都可以通过交易中的公钥和签名验证该交易是否有效,即确认支付者在该时刻对这笔比特币的拥有权。
大多数比特币钱包工具为了方便会将公钥和私钥以密钥对的形式存储在一起,然后,公钥可以由私钥计算得到,所以只存储私钥也是可以的。
以公钥K为输入,计算其SHA256哈希值,并以此结果计算RIPEMD160哈希值,得到一个长度为160位(20字节)的数字。
通常见到的比特币地址是经过“Base59Check”编码的,这种编码使用了58个字符和校验码,提高了可读性、避免歧义并有效防止了在地址转录和输入中产生的错误。
Base64使用了26个小写字母、26个大写字母、10个数字以及两个符号,用于在电子邮件这样的基于文本的媒介中传输二进制数据。
Base58是Base64编码格式的子集。
WIF:Wallet Import Format
压缩格式公钥:一个公钥是一个椭圆曲线上的点(x,y),而椭圆曲线实际是一个数学方程,如果我们知道了公钥的x坐标,通过解方程能得到y的坐标。另一方面,y的解是来自于一个平方根,在素数p阶有限域上使用二进制算术计算的时候,y可能是偶数或者技术,所以需要一个前缀来表示y的符号。前缀02表示y是偶数,前缀03表示y是奇数。
压缩格式私钥相比非压缩格式私钥多出一个字节,即后缀01,表明该私钥只能被用来生成压缩的公钥。
当从一个实现了压缩格式公钥的新的比特币钱包导出私钥时,钱包导入格式(WIF)将会被修改为WIF压缩格式,该格式会在私钥后面附加一个字节大小的后缀01。最终的Base58Check编码格式的私钥被称为WIF(压缩)私钥,以字母K或L开头。以5开头的时从较老的钱包中以WIF(非压缩)格式导出的私钥。
BIP0038加密方案需要一个长密码作为口令,通常由多个单词或一段复杂的数字字母字符串组成。加密结果是由一个base58check编码过的私钥,前缀为6P。
以数字3开头的比特币地址是P2SH(pay to script hash)地址,指定交易中受益人为哈希脚本,而不是公钥的所有者。
比特币钱包只含有密钥,而不是钱币。每个用户有一个包含多个密钥的钱包,钱包只包含私钥/公钥对的密钥链。用户用密钥签名交易,从而证明他们拥有交易输出。
非确定性钱包,每个密钥都是从随机数独立生成的,密钥彼此无关,just a bunch of keys,JBOK
确定性钱包,所有的密钥都是从一个主密钥派生出来,这个主密钥即为种子。
HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥。
密钥延申函数,使用2048次哈希是一种非常有效的保护,可以防止对助记词或密码短语的暴力攻击。(需要尝试超过几千个密码和助记符组合,而这样产生的种子数量是巨大的2^512)
链码用来引入确定性随机数据,使得索引不能充分衍生其它的子密钥。因此,有了子密钥并不能让它发现子集的姊妹密钥,除非有了链码。
子密钥不能从非确定性(随机)密钥中被区分出来,因为衍生函数是单向的,所以子密钥不能用来发现他们的母密钥。子密钥也不能用来发现他们的相同层级的姊妹密钥。只有母密钥和链码才能得到所有的子密钥。需要同时有子密钥以及对应的链码才能创建一个新的分支来衍生出孙密钥。
HD钱包使用一种叫做硬化衍生(hardened derivation)的替代衍生函数,打破了母公钥和子链码之间的关系。这个硬化衍生函数使用了母私钥而不是母公钥去推到子链码,这就在母/子顺序中创造了一道防火墙。
当强化私钥衍生函数被使用时,得到的子私钥以及链码与使用一般衍生函数得到的结果完全不同。得到的密钥分支可以用来生产不易被攻击的扩展公钥,因为它所含的链码不能被用来获得任何私钥。
第六章 交易
UTXO的面值为“聪”的离散(不连续)且不可分割的价值单元,一个UTXO只能在一次交易中作为一个整体被消耗。
交易输出包含两部分:
一定量的比特币,面值为聪(satoshis),是最小的比特币单位
确定花费输出所需条件的加密难题(称为锁定脚本,见证脚本,脚本公钥)
交易费是基于交易的千字节规模来计算的,而不是比特币交易的价值。
比特币交易验证并不基于静态模式,而是通过脚本语言的执行来实现的。这种语言允许表达几乎无限的各种条件,这也是比特币作为一种“可编程的货币”所拥有的力量。
锁定脚本是一个放置在输出上面的花费条件:它制定了今后花费这笔输出必须要满足的条件。在大多数比特币应用程序中,锁定脚本将以scriptPubKey的形式出现在源码中。
解锁脚本是一个解决或满足被锁定脚本在一个输出上设定的花费条件的脚本,它将允许输出被消费。解锁脚本是每一笔比特币交易输入的一部分,而且往往含有一个由用户的比特币钱包(通过用户的私钥)生成的数字签名。由于解锁脚本常常包含一个数字签名,因此被称为scriptSig。
ECDSA,椭圆曲线数字签名算法,Elliptic Curve Digital Signature Algorithm。
数字签名在比特币中有三种用途,第一,签名证明私钥的所有权,即资金的所有者。第二,授权证明是不可否认的。第三,签名证明交易在签字之后没有也不能被任何人修改。
每个输入可能在其解锁脚本中包含一个签名,因此,包含多个输入的交易可以有个有具有不同SIGNASH标志的签名,这些标志在每个输入中承诺交易的不同部分。
SIGHASH类型没看太明白。
第七章 高级交易和脚本
P2SH地址是基于Base58编码的一个含有20个字节哈希的脚本,就像比特币地址是基于Base58编码的一个含有20个字节的公钥。由于P2SH地址采用5作为前缀,这导致基于Base59编码的地址以3开头,这给客户一种特殊类型地址的暗示。
P2SH锁定脚本包含一个赎回脚本哈希,该脚本对于赎回脚本本身未提供任何描述。P2SH交易即便在赎回脚本无效的情况下也会被认为有效。如果处理不当,比特币可能会被锁死在这个P2SH交易中。
Return操作符允许开发者在交易输出上增加80字节的非交易数据。与伪交易型的UTXO不同,Return创造了一种明确的可复查的非交易型输出,此类数据无需存储于UTXO集。Return输出被记录在区块链上,它们会消耗磁盘空间,也会导致区块链规模的增加,但它们不存储在UTXO集中,因此不会使得UTXO内存膨胀,不会使全节点的内存不堪重负。
Return不涉及可用于支付的解锁脚本的特点,实际是没有成本的。
CLTV(Check Lock Time Verify,检查锁定时间验证)不会取代nLocktime,而是限定特定的UTXO,并通过将nLocktime设置为更大或相等的值,从而达到在未来才能花费这笔钱的目的。
通过将nLocktime与CLTV结合使用,交易锁定时间限制中描述的情况也发生变化。因为Alice锁定了UTXO本身,所以Bob或Alice在3个月的锁定时间到期之前不可能花费它。
一笔输入交易,当输入脚本中的nSequence值小于2^31时,就是相对时间锁定的输入交易。这种交易只有到了相对锁定时间后才生效。
第八章 比特币网络
第九章 区块链
完整的区块链节点是通过检查整个链中在它之下的数千个区块来保证这个UTXO没有被支付,从而验证交易。而SPV节点是通过检查在其上面的区块将它压在下面的深度来验证交易。
比特币核心客户端使用Google的LevelDB数据库存储区块链元数据。
当N个元素经过加密插入Merkle树时,至多计算2*log^2(N)次就能检查出任意元素是否在该树种。
Merkle树需要偶数个叶子节点,如果仅有奇数个交易需要归纳,则最后的交易会被复制一份。
有了Merkle树,一个节点能够仅下载区块头,然后通过从一个满节点回溯一条小的Merkle路径就能认证一笔交易的存在。
SPV节点不保存所有交易也不会下载整个区块,仅仅保存区块头,使用认证路径(Merkle路径)来验证交易存在于区块中。
Regtest允许创建本地区块链以进行测试,在本地作为一个封闭系统运行。
第十章 挖矿和共识
矿工通过创造一个新区块得到的比特币数量大约每四年(更准确的说是每210,000个块)减少一半。开始时间为2009年1月每个区块奖励50个比特币。2012年11月减半为每个区块奖励25个比特币。2016年7月减为每个新区块奖励12.5个比特币。知道2040年所有的比特币(20,999,999,980)全部发行完毕,不再有新的比特币产生。
通货紧缩是一种由于货币的供应和需求不匹配导致的比特币增值现象,与通货膨胀相反,价格通缩意味着货币随着时间有越来越强的购买力。
通货膨胀导致货币缓慢但不可避免的贬值,这是一种隐性税收的形式,惩罚在银行存钱的人从而实现解救债务人。
在Coinbase交易中,“交易哈希”字段32个字节全部填充0,“交易输出索引”字段全部填充0xFF(十进制的255),这两个字段的值表示不引用UTXO。“解锁脚本”由coinbase数据代替,数据可以由矿工自定义。
在一个完全去中心化的网络中,难度的调整的调整是在每个完整节点中独立自动发生的。每2016个区块中的所有节点都会调整难度。难度的调整公式是由最新2016个区块的花费时长与20160分钟比较得出的。
为了防止难度变化过快,每个周期的调整幅度必须小于一个因子(值为4),如果要调整的幅度值大于4倍,则按4倍调整。
比特币将区块间隔设计为10分钟,是在更快速的交易确认和更低的分叉概率间做出的妥协。更短的区块产生间隔会让交易清算更快的完成,也会导致更加频繁的区块链分叉。与之相对的,更长的间隔会减少分叉数量,却会导致更长的清算时间。
双重支付可以有两种方式:要么是在交易被确认前,要么攻击者通过区块链分叉来完成。进行51% 攻击的人,可以取消在旧分叉上的交易记录,然后在新分叉上重新生成一个同样金额的交易,从而实现双重支付。
共识攻击除了“双重支付”攻击,还有一种攻击场景就是拒绝对某个特定的比特币的地址提供服务。
硬分叉的四个阶段:软分叉,网络分叉,挖矿分叉,区块链分叉。
基于旧的共识规则的节点将拒绝根据新规则创建的任何交易和块。
在BIP-34之前,Coinbase可以让矿工选择包含的任意数据。在BIP-34激活之后,有效块必须在Coinbase的开始处包含特定的块高度,并且使用大于或等于“2”的版本号进行标识。
一旦交易被记录在区块中,并且随后的区块中添加了足够的工作,交易数据就变得不可篡改。 不可改变性是由能源进行承保的,因为重写区块链需要消耗能源才能产生工作证明。
共识规则拒绝任何时间戳距离现在太远(过去和将来)的块。
第十一章 比特币安全
第十二章 比特币应用
染色币用于跟踪第三方持有的数字资产和实物资产,并通过染色币所有权证书来进行交易。
状态通道是区块链外,由双方之间的交换状态代表的虚拟结构。使用这个术语表示链外双方之间的关系和共享状态。
支付通道值状态通道的引申概念之一,代表了链外状态的变化通过区块链上的最终结算得到保障。
支付通道是一种状态通道,其中被改变的状态是虚拟货币余额。
在通道的整个生命周期中,只有两个交易需要提交给链上进行挖矿:资金交易和结算交易。在这两个状态之间,双方可以交换任何数量的承诺交易,其他人不会看到,也不会提交到链上。
状态通道使用时间锁来在时间维度中执行智能合约。
撤销先前承诺交易的这种机制首先被作为闪电网络的一部分提出。
在签署新的承诺交易之前,他们必须首先交换撤销密钥以使先前的承诺无效。
带有相对时间锁(CSV)的不对称可撤销承诺是实现支付通道的更好方法,也是区块链技术非常重要的创新。通过这种结构,通道可以无限期地保持开放,并且可以拥有数十亿的中间承诺交易。
闪电网络是一种端到端连接的双向支付通道的可路由网络。这样的网络可以允许任何参与者穿过一个通道路由到另一个通道进行支付,而不需要信任任何中间人。
闪电网络实现了一种基于成为Sphinx方案的洋葱路由协议,该路由协议确保支付发送者可以通过闪电网络构建和通信路径,使得
1、中间节点可以验证和解密其部分路由信息,并找到下一跳。
2、除了上一跳和下一跳,不能了解作为路径一部分的任何其它节点。
3、无法识别支付的路径长度,或者自己在路径中的位置。
4、路径的每个部分被加密,网络级攻击者不能将路径不同部分的数据包彼此关联。
5、不同于Tor(互联网上的洋葱路由匿名协议),没有可以被监视的“推出节点”。付款不需要传输到比特币区块链,节点只是更新通道余额。
在通道生命中双方交换的每一项承诺交易都会被时间锁锁进未来时间点。但是,对于每个承诺,延迟时间会稍短一点,所以最新的承诺可以在被它废止的前一承诺之前被赎回
网友评论