您的位置:首页 > 其它

干货|比特币如何产生与交易

2018-03-25 23:41 344 查看


最近研究区块链,从区块链起源比特币入手,有些许收获,整理成文分享给大家。文章着重讲解比特币交易系统,适合对比特币系统或区块链技术有一定了解的人群阅读。通过此文可了解比特币底层技术区块链的运作原理。因为大多数文章要么泛泛而谈区块链能去中心化、能防篡改、能追溯,可以改变行业改变世界,而不加以解释如何实现,要么只针对某一环节进行深度解析,缺乏整体的串联介绍,所以本文尝试进行有一定深度的整体介绍,希望能帮助大家理解比特币系统的实现。

中本聪在比特币白皮书中介绍说,比特币交易系统是一种完全通过点对点技术实现的电子现金系统,它使得在线支付能够直接由一方发起并支付给另一方,中间不需要通过任何的金融机构(基于密码学原理而不基于信用)也能防止双重支付问题(double-spending)(去中心化)。该网络通过随机散列(hashing)对全部交易加上时间戳(timestamps),将他们合并入一个不断延伸的基于随机散列的工作量证明(proof-of-work)的链条作为交易记录,除非重新完成全部的工作量证明,形成的交易记录将不可更改(防篡改、可追溯)。其实就是一串使用密码学方法相关联产生的数据块,每一个数据块中包含比特币交易信息,用于验证其信息的有效性和生成下一个区块。这个系统核心流程是比特币的产生与交易。

接下来将会对如何产生比特币,比特币如何交易,去中心化系统如何解决共识问题,数据为何不可篡改,如何追溯进行讲解(这些问题的答案在文中都会用下划线标出便于大家定位)。

文章主要分为三大块:一是比特币的产生;二是比特币的交易;三是附录,包含常见问题和涉及技术介绍,帮助大家理解文章。

1

比特币的诞生-挖矿

整个挖矿流程如下:

检索待确认交易内存池,选择包含进区块的交易。中本聪创造的创世区块并无交易打包,所以挖的是空块。因为每一个区块都有容量限制,后人挖矿一般会根据手续费对待确认交易集进行排序,由高到低进行打包,尽可能使得每次挖矿的收益最大;(挖矿除了比特币奖励外还有交易确认记录的手续费)

构造Coinbase,确定打包交易集,统计手续费等信息;

构造HashMerkleRoot,对所有交易构造Merkle数;

填充其他字段,获得完整区块头;(步骤234如果不懂没关系,看完全文再回头看就好理解了)

对区块头进行SHA256D运算(两次SHA256计算)(详见下文,建议先看看附录一的哈希运算,有助于理解);

验证结果,如果符合难度,则广播全网,全网验证通过则所有节点一起记录,不符合改变参数继续计算并验证;(共识机制其实就是此算法及其验证过程,无中心却人人认可;比特币产自哪个节点完全看算力看运气;每个节点都拥有所有交易记录信息)

上述过程最重要的就是哈希计算,过程如下:

通过Sha256D(version+hashPrevBlock+hashMerkleRoot+nTime+nBits+nonce)(这几个字段见表2区块头结构)得到64位的十六进制或者256位的二进制哈希值;



表1:区块结构(区块头信息见表2和交易详情结构见表3表4)



表2:区块头结构

将结果哈希值与目标哈希值进行比较,如果当前nonce值计算的哈希值小,那么挖矿成功,否则,挖矿失败,旷工需要更改nonce值(通常加1)再试,直到成功(暴力搜索);–以上其实就是工作量证明机制(Proof-of-Work),解决了共识问题。

其中,

目标哈希值target=2*(256-difficulty)

difficulty值由节点自动调整,规则为New difficulty=OldDifficulty*(Actual time of last 2016 Blocks/20160minutes)即:最新2016个区块花费时长与20160分钟比较所得,其中20160分钟是这些区块以10分钟一个的速率所花费的时长。

那么计算得到的64位的十六进制或者256位的二进制哈希值如何与目标哈希值进行比较呢?如果是二进制直接看结果哈希值的前N个比特位是否全部为0(如下图),是的话挖矿成功。(0越多值越小;值越小,N越大,难度越大)可以类比抛硬币,按顺序抛256个硬币,编号为1至256,每进行一次Hash运算,就像抛一次硬币,256个硬币抛出的结果若前N个硬币全部正面向上则获取记账权,挖矿成功。如果是十六进制,直接比较就行。(二进制也可直接比较)



图1:挖矿原理图

所以,挖矿流程就是节点构造区块,初始化区块头各字段,计算hash值并验证区块的过程。不合格则nonce自增,再计算并验证,如此往复。每次大约需10分钟产生一个区块(全网),最初每个区块产生50个比特币,每个比特币为1亿聪,之后大约每4年(21万个区块)减半(比特币的产生)。总量大约2100万,到2140年才挖完,而到2045年就挖掉99.9%了。下图是比特币产生年份表



图2:比特币产生年份表

看上表可以发现第一个区块是在2009年产生的,具体时间是格林威治时间2009年1月3日18:15:05,由中本聪创造。有趣的是,中本聪在创世区块上留下了泰晤士当天的头版文章标题“The Times 03/Jan/2009 Chancellor on brink of second bailout forBanks”,讽刺了中心化金融体系并巧妙地证明此区块的生成时间是在09年1月3号之个报纸标题出现之后。下图是创世区块的信息截图,做个了解,记录了区块高度、哈希值、前一区块哈希值、时间难度等交易信息,根据前一区块hash、下一区块哈希可以追溯前一个区块、后一个区块。



图3:创世区块信息

2

比特币的交易

交易得先从公钥、私钥、地址讲起,构造流程如下:

使用随机数发生器生成一个256位的私钥;

私钥经过SECP256K1椭圆曲线算法处理,生成公钥,无法反向推出私钥;

将公钥通过SHA256哈希计算得出32字节哈希值(下方有流程图,可参照着理解),再用哈希值进行RIPEMD-160计算得到20字节的哈希值,把版本号—20字节的哈希值组成的21字节数组进行SHA256D运算,取得到的哈希值的头4个字节作为校验和,放在21字节组的尾部,对组成的25位数组进行Base58编码,得到地址。



图4:地址产生算法

通过上述流程得到公私钥地址就可以交易了,在交易过程需要通过私钥对交易进行签名,签完名后发起交易,交易会到待确认池子里面,等待节点来打包确认放进区块,也就是上文的挖矿过程。签名通过算法Sig=FuncSig(FuncHash(m),dA)=(R,S)进行,其中dA是签名私钥、m是交易信息、FuncHash是哈希函数、FuncSig是签名算法、Sig是签名结果。验证过程则是通过一系列函数算法进行验证,略复杂感兴趣可自行了解。数据签名算法的核心在于证明数据的发送方是签名者发出的,防抵赖。签名的这些数据存放在解锁脚本里,如表4交易结构2。比特币系统里的交易分为两种,一种是挖矿所得,即一个区块的第一笔交易,称为coinbase交易;第二种是普通交易,也就是非挖矿交易。



表3:Coinbase交易结构



表4:普通交易结构

交易结构构造完毕后即可发起交易,交易信息会到待确认交易池中等待打包确认。在比特币的交易信息里,有两个很关键的字段:输入/输出,输入并非明确某人有多少数量的比特币,而是指向比特币来源,即前一个已确认的交易中的UTXO(可追溯);输出定义某人有多少比特币,并且输出要全部输出(最多只有两个),分为两部分,一部分给外人,一部分给自己,其实就是找零机制。正是这种设计建立起分布式账簿,所有区块和交易形成互相连接的链条。找零机制有个好处就是保护隐私。因为每一笔比特币交易都可在全球性的公共总账上看到,如果某个比特币地址偶然被知道其使用者,那么将不利于使用者的隐私保护。而有了找零机制,地址A发起付款给地址B,找零地址不设置为A,而是改为C(自己的另一个账户)。那么地址B和C是不是A?都有可能,这样整个交易的真相将变得难以推测。



图5:交易例图

交易信息在进入待确认交易池后,每一个节点都将收到的交易信息纳入区块中,当一个节点找到一个足够难度的工作量证明后会向全网进行广播,其他节点会验证该节点区块中所有的交易都是有效且之前未存在过才会认可该区块的有效性(通过默克尔树进行比对校验—防篡改,默克尔树可查看附录二),验证通过则全网的节点都会跟随在该区块的末尾制造新区块以延长该链条,被接受的区块的随机散列哈希值视为先于新区块的随机散列哈希值。如果有两个节点同时找到答案,其他节点会在自己率先收到的区块基础上进行工作,直到下一个区块产生,其中一条链条被证实为是较长的一条,那么较短分支链条上的节点将转换阵营,开始在较长链条上工作。

在这个共识机制中,新的交易不需要抵达全部节点,只要交易信息能抵达足够多的节点(超过一半),那么这些交易将被整合进一个区块中,其他没有接收到的节点后续会发现自己缺失了某个区块,重新下载更新即可,此为拜占庭容错。–拜占庭问题可见上一篇文章。最终整个交易信息会被打包在不同的区块之中,区块与区块直接通过哈希算法、时间戳关联起来,实现可追溯。



图6:区块链接图

总结一下:比特币电子现金系统通过对每一笔交易进行哈希处理进行关联、通过默克尔树将交易与区块进行关联,通过区块头哈希与下一区块进行关联,实现了整个交易-交易、交易-区块、区块-区块之间的关联,实现过程可追溯;通过哈希处理的默克尔树进行信息比对校验、工作量证明机制(POW)、时间戳服务器,实现了防篡改、防双重支付;通过工作量证明机制下的共识算法以及激励,实现了系统去中心化;当然其中还涉及到各种密码学原理,比如非对称性加密技术保证的数据传输安全、Merkle tree保证的数据真实并优化存储等。所以,其实其底层技术区块链优势无非就两点,一是共识机制打造的去中心化系统,相比较传统技术可以更好解决某些问题;二是密码学技术打造的防篡改可追溯,可以很好解决各行业领域存在的信任问题;至于具体有什么场景可以应用,如何解决这些场景的痛点,我们下次再聊!

3

附 录

附录一:哈希算法

哈希算法也称为散列函数算法,在区块链中应用广泛。看一个转换例子比较直观,一个字符串xingfushifendouchulaide的hash运算结果(64位十六进制)。

**Text:**xingfushifendouchulaide

**算法:**sha256

结果:

b717189a738923eca3789287390b9b9c8a7839bca783928000cbdabed892bc43

如果用MD5加密,运算结果是32位十六进制,用Sha512加密,结果是128位十六进制。哈希算法其实就是一个映射的关系组,可以实现快速将明文转换为hash值,而极难在短时间内反推出明文。另外,当明文稍作修改,hash值会有很大出入,不同的明文,难以出现相同hash值。万一(概率极低)真的出现明文x不等于y,而f(x)=f(y)的情况,那么即产生了冲突,一般会通过链接法、开放定址法、桶定址法(可自行了解)来解决。

哈希函数一般有以下几种:

直接取余法:取余

乘法取整法:取整

平方取中法:平方后取中间

加法hash:把输入元素加起来得到结果

乘法hash:乘以某个固定或不断变化的数

位运算hash:利用各种位运算来混合输入元素

混合hash:通过各种hash混合构造

区块链中哈希运算简言之就是通过某种映射(函数关系)将一段字符串转换为哈希值并与目标对象进行比较,在签名验证、默克尔树比对中需要相等,在挖矿竞争中需要小于目标哈希值。

应用举例:比如数据完整性校验,最简单的方法是对整个数据做Hash运算得到固定长度的Hash值,然后把得到的Hash值公布,用户下载数据后对数据再次进行Hash运算,比较运算结果和公布的Hash值,如果两个Hash值相等,说明数据没有损坏。可以这样做是因为输入数据的稍微改变会引起Hash运算结果的面目全非,而且根据Hash值反推原始输入数据的特征是困难的。–防篡改

附录二:默克尔树(Merkletree)

Merkle tree的叶子节点的value是区块数据Hash,非叶子节点的value是根据它下面所有的叶子节点值hash串联后计算得到的哈希值,如果是单身哈希,就直接对它自己进行哈希运算,得到另一个哈希值,层层往上推,会形成一颗倒三角数,到最顶部就只剩下一个根哈希,叫做Merkle Root。



附图1:默克尔树结构



附图2:默克尔树在区块中的位置

比对验证从根哈希值比对起,如果一样,那么整个区块的信息都没问题,因为只要有任一环节出现不一样,根哈希都会不一样。如果根哈希不一样,就可以往下层层追溯,找到不一样的环节。如下图:

附录三:常见问题

什么是区块链?

通俗来讲那就是去中心化的分布式账本。在区块链系统中,只要有能力部署自己的服务器都能加入区块链网络,成为网络节点,所有节点拥有完全一样的权利与义务,可进行读写操作,只要满足机制,其他所有节点会依次同步,实现整个网络中所有节点的数据完全一致。

晦涩一点讲就是利用块链式数据结构来验证与存储数据,利用分布式节点共识算法来生成和更新数据、利用密码学的方式来保证数据传输和访问安全、利用由自动化脚本代码组成的智能合约来编程和操作数据的一种全新的分布式基础架构与计算范式。

如何防止双重支付?(工作量证明/共识机制)

为了达到目的,我们只需要关注交易之前发生的交易,而不需要关注交易之后是否会有双重支付,因为比特币系统交易是公开存储于所有节点并且有一系列的交易时间顺序。只要保证交易之前没有其他交易,那么此笔交易就是安全的,除非发生51%攻击。51%攻击是指攻击者在一笔交易被确认后在同一区块发起另一笔交易B,而后联合全网51%的算力进行挖矿(略大于二分之一的概率挖到),打包交易B确认交易记录,继续挖矿,构造一条比之前区块链更长的链条,再公布全网,全网会认可最长链条的记录,因为最长链包含了最大工作量。所以,只要不发生51%攻击,通过工作量机制证明机制、哈希算法构造的唯一公认的历史交易序列可以避免双重支付问题产生。

对称性加密算法和非对称性加密算法的区别?

对称性加密算法只有一把密钥保证加密数据的安全,加解密都用这把密钥。如何保存和传递密钥是一件比较头疼的事情,一旦传递过程中泄露密钥数据则毫无安全。而非对称性加密算法可以实现不直接传递密钥,也能完成解密。加密和解密使用不同的规则,两种规则存在某种对应关系即可。如下,非对称性加密算法使用私钥进行加密,对方使用公钥即可解密。

交易中的锁定脚本解锁脚本的重要性?

在中心化方式下,如果某种协议一旦确定,想要变更是非常困难的,需要经过广泛讨论并取得共识。而如果是脚本系统,那么完全可以通过升级或者推出补丁,甚至发行一个新版本来解决。

为何区块的产生时间是10分钟?

总要有一个值,为何不是更短,比如1分钟。时间过短会导致孤块增多,因为出块时间短也就代表着难度低,举个例子,假如1秒扔10个硬币全正面视为出块,若降为1秒扔2个硬币全正面视为出块,那么同一时间出块的节点将大量增加,却只有一个能被共同认可加入链条,也即无用孤块过多。那为何不是1小时呢?效率问题。

内容来源:SteveMark

作者:李魔王

以下是我们的社区介绍,欢迎各种合作、交流、学习:)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  技术 阅读