了解比特币白皮书

写在开头

因为菜鸟一只,之前只是懂点hyperledger fabric,所以对于中本聪白皮书了解的不多,也是花了时间看了一下,下面全是一些学习记录,不正之处还望指出来。

bitcoin白皮书英文

bitcoin白皮书中文

 

摘要

比特币是一种不需要第三方支持的点对点电子现金支付系统

主要问题

去中心化的p2p系统
解决支付双花的问题

为什么区块链称为链?

 比特币引入了基于时间戳的随机散列,并且让其形成前后文相关的序列。

账本不可更改 

除非重新完成全部的工作量证明,形成的交易记录将不可更改。

 

简介

缺陷

比特币缺乏不可逆缺陷。这里面需要注意的是比特币系统代替的是中心化中介的信用,并不能保证交易双方的信用,相反一旦交易的某一方出现信用问题这笔交易是无法撤销的,对于初次接触比特币的人一定要尤为注意,也就是说和传统银行交易不同,一旦你确定支付,哪怕对方是骗了你,你的交易损失是无法追回的。
比特币解释

一种电子支付系统,它基于密码学原理而不基于信用,使得任何达成一致的双方,能够直接进行支付,从而不需要第三方中介的参与。杜绝回滚(reverse)支付交易的可能,这就可以保护特定的卖家免于欺诈;而对于想要保护买家的人来说,在此环境下设立通常的第三方担保机制也可谓轻松加愉快。

 

交易

定义

 一枚电子货币(an electronic coin)是这样的一串数字签名:每一位所有者通过对前一次交易和下一位拥有者的公钥(Public key) 签署一个随机散列的数字签名,并将这个签名附加在这枚电子货币的末尾,电子货币就发送给了下一位所有者。而收款人通过对签名进行检验,就能够验证该链条的所有者。

结构

比特币的交易需要引入reference之前的交易用于证明有足够的输入比特币用于支出,比特币的交易记录方式是一个基于时间序列的链式结构。判断是否有足够的输入用于支付则需要矿工来判断。

  • 私钥:自己知道,用来签名。私钥本质上是随机数。
  • 公钥:所有人都可以知道,用来验证签名。公钥是由私钥生成的,通过椭圆曲线(ECPoint)生成,一个私钥经过椭圆曲线变换之后能够得到公钥。
  • 地址:比特币钱包地址。公钥太长了,所以就有更短一些的地址的概念,另一方面没有发送过交易的地址,并不想暴露自己的公钥,而地址是通过摘要算法生成的,不会暴露公钥的真实内容。

公钥私钥和地址的关系

    https://blog.csdn.net/jerry81333/article/details/56824166

 

货币支付过程

假设:每个人的地址为公钥。小兰付给小明2个比特币。

Step1: 首先查看当前图中的交易内容:交易内容,前一条交易的地址,小明公钥,使用小兰私钥加密(交易内容,前 一条交易的地址,小明公钥)之后的数字签名,以及小兰的公钥。
Step2: 小兰通过P2P技术将当前交易发送给小明。
Step3:
 a) 小明首先使用小兰公钥将小兰签名进行解密得到hash值。
 b) 小明加密交易内容,前一条交易的地址和小明自己的公钥得到hash值。
 c)对比两个hash值,判断是否来自小兰。

交易双方加密解密过程

交易记录中包含前一条交易的地址,用于reference以前的记录。

双重支付的问题

  • 一是所有的交易全网都是公开的,所有人都可以追溯交易的来龙去脉。
  • 二是每笔交易都有时间戳,具有先后顺序,形成时间序列交易链。证明前一条有效即可,则后面的无效。
  • 三是,假如有人说那我通过特有的方式创造了相同时间戳的双重支付记录。那么就会产生分叉,分叉的最终结果还是取最长的链,只会有一条记录记录在区块链上。

如何判断用户当前有足够的比特币用于支付

矿工工作:确认时首先要确认之前reference的这笔交易是否存在,同时还要检查在这之前有没有将比特币支付过了。这一切确认后,这笔交易有效性就被确认了。

 

时间戳

时间戳的意义

时间戳的意义在于避免双重支付问题,时间戳的单位是块。块的生成需要矿工的工作,后面再看。这里直接先说时间戳。
A timestamp server works by taking a hash of a block of items to be timestamped and widely publishing the hash, such as in a newspaper or Usenet post [2-5].

感觉网上中文翻译怪怪的: 时间戳服务器通过对以区块(block)形式存在的一组数据实施随机散列而加上时间戳。
我看了这个就纠结于随即散列是个啥意思?应该是表示hash值的。
a hash of a block of items:多条交易构成块的hash值。
to be timestamped:具有时间戳含义。

我的理解是:时间戳通过多条交易构成块的hash具有时间戳含义并且将当前hash广播出去,当前hash代表当前区块。时间戳的运行机制就是两个区块产生间隔中所有交易进行Hash运算,加盖时间戳,我们就得到了一个按时间序列产生的交易记录了,这就是区块链。

当前hash值具有时间戳含义通过区块hash的计算就可以知道了:前面文章也有介绍,区块的hash计算如下。

func calculateHash(block Block) string {
        data := string(block.Index) + string(block.TimeStamp) + block.PrevBlockHash + block.Data
        blockInBytes := sha256.Sum256([]byte(data))
        return hex.EncodeToString(blockInBytes[:])
    }   

如何避免双重支付

前面内容了解到区块的hash具有时间戳。现在假设两条交易在同一区块,则验证第一条有效之后,第二条则无效。如果在不同区块,则区块具有时间戳,前面区块的交易有效之后,第二条记录则无效。如果碰到区块分叉,则最终只会有一个区块会成功上链,也不会出现双重支付。

时间戳的计算

因为区块的产生是不同矿工工作出来的,那么时间戳以谁为准呢?“多数人的正义”,时间来自于连接的其他节点(node)时间的中位数(mean,是个数学概念,比平均值更不受极端数字影响),要求连接的节点(node)数量至少为5,中位数和本地系统时间差别不超过70分钟,否则会提醒你更新本机的时间。同时,在接收到新的block时会拒绝时间与自己差距+2小时和-(前11个block时间中位数)的block

中位数

中位数,又称中点数,中值。中数是按顺序排列的一组数据中居于中间位置的数,即在这组数据中,有一半的数据比他大,有一半的数据比他小,这里用来表示中位数。(注意:中位数和众数不同,众数指最多的数,众数有时不止一个,而中位数只能有一个。)

偶数:23、29、20、32、23、21、33、25

首先将该组数据进行排列(这里按从小到大的顺序),得到:20、21、23、23、25、29、32、33 因为该组数据一共由8个数据组成,即n为偶数,故按中位数的计算方法,得到中位数为四个数和第五个数的平均数。(23+25)/2 = 24 

奇数:10、20、 20、 20、 30

首先将该组数据进行排列(这里按从小到大的顺序),得到:10、 20、 20、 20、 30 因为该组数据一共由5个数据组成,即n为奇数,故按中位数的计算方法,得到中位数为20,即第3个数。

 

工作量证明

本质

工作量证明机制本质就是提升了作恶的成本,让作恶的投入产出比低于做诚实节点的投入产出比,这就是中本聪运用博弈论的点睛之笔。但生成hash前需要工作量证明。比方说SHA-256下,随机散列值以一个或多个0开始。那么随着0的数目的上升,找到这个解所需要的工作量将呈指数增长,但是检验结果仅需要一次随机散列运算。我们在区块中补增一个随机数(Nonce),这个
 随机数要使得该给定区块的随机散列值出现了所需的那么多个0。

恶意攻击

恶意修改区块链内容?存在有些人恶意修改区块链内容。如果修改了区块链内容,则需要重新计算当前hash值和之后所有区块链的hash值,因为hash值的计算受区块链内容的影响。

Merkle Tree

                                     

每个块都会有一个 Merkle 树,它从叶子节点(树的底部)开始,一个叶子节点就是一个交易哈希(比特币使用双SHA256哈希)。叶子节点的数量必须是双数,但是并非每个块都包含了双数的交易。因为,如果一个块里面的交易数为单数,那么就将最后一个叶子节点(也就是 Merkle 树的最后一个交易,不是区块的最后一笔交易)复制一份凑成双数。从下往上,两两成对,连接两个节点哈希,将组合哈希作为新的哈希。新的哈希就成为新的树节点。重复该过程,直到仅有一个节点,也就是树根。根哈希然后就会当做是整个块交易的唯一标示,将它保存到区块头,然后用于工作量证明。

区块

比特币的区块由区块头及该区块所包含的交易列表组成。区块头的大小为80字节,由4字节的版本号、32字节的上一个区块的散列值、32字节的Merkle Root Hash、4字节的时间缀(当前时间)、4字节的当前难度值、4字节的随机数组成。区块包含的交易列表则附加在区块头后面,其中的第一笔交易是coinbase交易,这是一笔为了让矿工获得奖励及手续费的特殊交易。

区块结构如图:来源

工作量输入如图

工作量证明过程

计算sha256(block_header)的值并且判断当前hash值以足够的0开头。通过反复尝试得到满足条件的随机数。

问题:在网上看到一篇文章通过计算目标值来计算nonce的,有步骤不理解,先记录在这里,后面再继续看。

http://www.infoq.com/cn/articles/bitcoin-and-block-chain-part02

对于为什么不使用基于IP地址的投票权问题(IP地址共识机制)

因为IP地址分配是一个中心化问题(IP地址的分配受ICP控制,政府组织可以很轻易回收和控制这些ip地址资源)

工作量证明方式与摩尔定律抵消

随着硬件的快速发展,计算所需的时间会越来越少。中本聪自己定义困难度的增加。难度的调整是在每个完整节点中独立自动发生的。每2016个区块,所有节点都会按统一的公式自动调整难度,这个公式是由最新2016个区块的花费时长与期望时长(期望时长为20160分钟即两周,是按每10分钟一个区块的产生速率计算出的总时长)比较得出的,根据实际时长与期望时长的比值,进行相应调整(或变难或变易)。也就是说,如果区块产生的速率比10分钟快则增加难度,比10分钟慢则降低难度。

 新难度值 = 旧难度值 * ( 过去2016个区块花费时长 / 20160 分钟 )

 可以查看困难度调整https://bitcoinwisdom.com/bitcoin/difficulty 
   

网络

  • 新的交易向全网节点广播  
  • 每个节点将接受的新交易组成一个区块  
  • 每个节点为自己的区块寻找有难度的工作量证明  
  • 当其中一个节点找到了区块的工作量证明,该节点向全网广播该区块  
  • 只有当区块内的所有的交易都是有效的并且没有已经被花费过的,网络中的节点才会接受该区块  
  • 结点接受新区块的方式就是通过将接受的区块加载到该节点的区块链上,然后以接受区块的hash作为前一个区块hash在区块链上继续创建新的区块  

 结点总是认为最长的链是正确的,并且在这条链上工作

如果两个节点先后向全网广播了两个不同的区块,则其他的节点接受到这两个区块,会首先工作在第一个接受到的区块上,然后也会将第二个区块添加到区块链上。因为当前不知道这两个区块谁会成为最长的区块。接下来就分别以两个区块继续添加新的区块到链上。一般认为一个区块后面再链了6个区块后,就不肯能被“颠覆”了,故称为“六次确认”。


激励

  • 1) 每个新区块的第一笔交易特殊处理作为奖励给创建当前区块的节点。  
  • 2)如果交易的输入大于输出,则差额作为交易费,该交易将被增加到包含该交易的区块中,最终还是会流向创建该区块的节点中去。  
  • 3)创建区块的奖励使用cpu的时间和电力的消耗装换的。  
  • 4)激励系统在于提倡节点的诚实,因为节点的不诚实行为没有诚实行为带来的奖励大。 

 

回收硬盘空间

如果一个货币的最新一条交易已经被足够多的区块埋藏,则可以删除最新一条交易之前的交易以节省磁盘空间。

删除方式

之前谈到区块的结构,只保存区块头,删除交易内容

中本聪对于空间的考虑

区块的最大高度为1M, 一年产生区块为 1*6*24*365 = 52560MB。当然这是最大值。这也是中本聪考虑回收空间的意义。区块头的高度是80byte, 一年产生区块为:80*6*24*365=4.2MB。按照摩尔定律预测,每年增长1.2GB的速度,所有的区块头部放到内存中都不是问题。  

目前比特币似乎没有在这个方面有相关开发说明。好像并没有使用这个方案。在网上看到有强制删除的,删除的
区块的所有内容。但是当需要trsanction history的时候还需要下载以前的记录。http://8btc.com/thread-91737-1-1.html  

 

组合和分割价值

交易被允许多输入多输出。  
交易输出最多有两个:  

  • 一个用于支付  
  • 一个用于找零  

每次交易都会花完,如果输入大于输出,差值会成为交易费,奖励给区块。  

原文提到不理解

当一笔交易依赖于多笔交易时,这些交易又各自依赖于更多交易,在这里这个不是问题,不需要展开交易历史的完整独立副本。

结点在确认交易的时候是需要验证输入值的,不知道这里说不展开交易历史的完整副本指的是依靠节省回收磁盘空间只依靠merkle tree的root hash来判断。

交易结构 来源

每个交易都有四字节交易版本号作为前缀,它告诉Bitcoin节点和矿工使用哪些规则进行验证它。


标准Pay-To-Public-Key-Hash(P2PKH)交易类型

案例:小兰向小明支付1个比特币   

1. 小明/小兰拥有自己的私有/公开的密钥对。
2. 小明向小兰提供自己的公钥哈希值,由于公钥哈希值经常被用来编码为BitCoin地址。它们是包含地址版本 
   号,哈希值,来捕获打字错误的checksum错误检测校验base58编码字符串。
3. 小兰得到小明地址然后解码得到小明公钥。创建交易:
   一个包含指令的标准的P2PKH交易输出,这个指令允许任何人花费这个输出,若他们能证明他们控制着
   相应于小明哈希过的公钥的私钥。这些指令称为pubkey脚本或scriptPubKey。

   **这里的交易输出就是上面output结构中的“Txout-script / scriptPubKey”**
   **交易过程中,发送方使用锁定脚本进行锁定,锁定在接收方的地址上,只有证明自己是接收方,才能使用比 
   特币。**

4. 小兰广播该交易,节点将其添加到区块链。
5. 一段时间,小兰进行比特币交易,创建交易必须由输入。小明接受交易内容,需要创建一个签名脚本 - 
   满足小兰在之前输出pubkey脚本里列出的条件的一组数据参数。签名脚本也称为scriptSigs**也就是上面    
   input结构中的“Txin-script / scriptSig”**。  

如何验证签名的就不深入了解了,详情:https://blog.csdn.net/jerry81333/article/details/56824166

P2PKH

Pubkey script: OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG  
Signature script: <sig> <pubkey>


节点认可交易

▷交易的语法和数据结构必须正确。  
▷输入与输出列表都不能为空。  
▷交易的字节大小是小于MAX_BLOCK_SIZE的。  
▷每一个输出值,以及总量,必须在规定值的范围内 (小于2,100万个币,大于0)。  
▷没有哈希等于0,N等于-1的输入(coinbase交易不应当被中继)。  
▷nLockTime是小于或等于INT_MAX的。  
▷交易的字节大小是大于或等于100的。  
▷交易中的签名数量应小于签名操作数量上限。  
▷解锁脚本(scriptSig)只能够将数字压入栈中,并且锁定脚本(scriptPubkey)必须要符合isStandard的格式 (该格式将会拒绝非标准交易)。  
▷池中或位于主分支区块中的一个匹配交易必须是存在的。  
▷对于每一个输入,如果引用的输出存在于池中任何的交易,该交易将被拒绝。  
▷对于每一个输入,在主分支和交易池中寻找引用的输出交易。如果输出交易缺少任何一个输入,该交易将成为一个孤立的交易。如果与其匹配的交易还没有出现在池中,那么将被加入到孤立交易池中。  
▷对于每一个输入,如果引用的输出交易是一个coinbase输出,该输入必须至少获得COINBASE_MATURITY (100)个确认。  
▷对于每一个输入,引用的输出是必须存在的,并且没有被花费。  
▷使用引用的输出交易获得输入值,并检查每一个输入值和总值是否在规定值的范围内 (小于2100万个币,大于0)。  
▷如果输入值的总和小于输出值的总和,交易将被中止。  
▷如果交易费用太低以至于无法进入一个空的区块,交易将被拒绝。  
▷每一个输入的解锁脚本必须依据相应输出的锁定脚本来验证。  

block rule 查看文章 

钱包

Wallet: A Bitcoin wallet is a collection of private keys but may also refer to client software used to manage those keys and to make transactions on the Bitcoin network.

比特币钱包是私钥的集合,比特币客户端与之关联用来在区块链网络中生成交易。存在客户端就必定存在地址。不然没法交易。具体的钱包基于比特币网络的客户端开发就不看了。
 

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页