区块链入门的几个基本问题

Posted 北极象

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区块链入门的几个基本问题相关的知识,希望对你有一定的参考价值。

目录

前言

当我们在提到区块链的时候,很多人都知道这是个跟金融,就是跟money有关的东西,与其说区块链,我们常用的词应该是区块链技术,这种说法其实就揭露了其本质——技术。那与区块链相关联的另一个名词又是什么呢?那当然就是大名鼎鼎的比特币(BitCoin)。

比特币

比特币,你可以把它当作是一种电子货币,它的出现绝对不是偶然,然是历史发展的必然。在中本聪的论文(见附件)中对比特币出现的前因后果大致是这么描述的(翻译可能有误)

在物理世界中,货币是由各国的央行发行,这是一个中心化的发行机制,说白了,就是容易受到某个中心化机构的控制
货币的流转
电子货币:可信的第三方(银行、支付宝等)承担着货币的流转
物理货币:人直接把cash交给另一个人
当然,人与人直接交易,流转货币,这种方式方式当然是安全的(除非遇到假钞,这里不讨论这种情况哈)
那么,可信的第三方作为货币流转的中介,这种方式有什么问题吗?我看平时支付宝用的好好的啊。中本聪的论文里是这么讲的:

中心化的第三方,没法完全保证可信
中心化的第三方,所有的交易,用户的余额都存在一个中心化的数据库中,不能完全保证交易的不可更改(因为只有一个人知道,你改了,我找谁说去?)
在人与人交易的过程中,第三方作为中间人,也是需要承担风险的,万一两个交易的人扯皮子,你说我作为担保人是不是得吃闷亏,这样就无形中增加了这种交易的成本,甚至有可能让很多人放弃这种方式的交易
中心化的第三方不是福利机构啊,人家凭什么要给你管账本,要陪你扯皮子呢?还不是由服务费吗?
那么,中本聪就设想,在电子交易的过程中,能不能通过某种方式,把这个第三方给去了,像物理世界中的先进交易那样,用户A直接就把货币打到用户B的钱包里?

于是乎,比特币就这么登上历史的舞台。。。

区块链

看完上面,相信你们对比特币是干嘛用的已经有了一个大致的了解了,中本聪的论文里称比特币是一种点对点的电子现金系统,那么作为与物理世界里的钞票对应的电子现金,需要解决什么问题呢?

货币的发行,首先得像央行发行软妹币一样,有一定的机制去保障这些个货币能被正常的发行出来啊。但是,又不能像央行发行软妹币那样一家说了算,我想发多少就发多少,这样迟早完蛋啊,很多血淋淋的例子我就不多列举了
货币的转移,比特币这种电子现金系统肯定也要有一种机制去保证货币能在用户之间流转吧,并且这种流转也不能再有第三方介入了啊
交易、余额等,我得有一套机制去存人与人之间的产生的交易信息吧,我还要去记录一个人还剩多少钱吧,并且,这个过程也不能让某一个中心化的机构来做
上面说到的这样,可以看成是实现比特币这套电子现金系统中,必须解决的关键性问题,那么怎么解决这些个问题呢?那就是今天的主角——区块链技术发挥作用的地方了。大概的意思就是:区块链是什么比特币这种电子货币,保障比特币发挥作用的底层技术!

区块链大揭秘

抛砖引玉

下面,我们来说一个故事,借此来引出区块链技术的关键问题。

故事一

那是一个晴空万里的早上,始金向往常一样高高兴兴的上班去了,一到公司,成晓就告诉他,老板觉得你很不错,刚刚说要给你升职加薪,始金一听,心想肯定骗我的,就没当回事,不料,过一会盛哥又来了,说了跟成晓一样的话,始金心里开始打鼓了,难道这是真的?没过一会,黎晨也对他说了同样的话,子墨,罕喻也是,这下不得了了,始金开始信了,这不得不信啊,毕竟这么多人都说了,那肯定就是真的啊!

故事二

那是一个晴空万里的早上,始金向往常一样高高兴兴的上班去了,一到公司,马老师就对始金说,公司决定要给你升职加薪,始金立马就信了。

通过上面的两个故事,大家可以看到,要让用户相信一件事,其实可以通过两种方式,一种是故事一中的很多人说这是真的,另一种就是有一个权威的第三方来说这是真的。而区块链技术正式借助故事一的思想来实现对交易的有效性的保障。

总结

这就是区块链技术的最重要的思想——去中心化

当然,这个去中心化,包括两层意思,第一层是货币的发行去中心化;另一层是货币的转移(流转)去中心化。意思就是货币的发行不再由像央行这样的中心化的机构来控制,而是由整个系统来决定,至于决定货币发行的因素,我们后面再谈;与此同时,货币在用户之间的流转也要去中心化,用户直接将货币转给另一个用户,而不需要第三方来记账担保,而是所有参与的用户都来共同担保,大家一起来见证这笔交易,保证交易的有效性。

引人入胜

下面我们就以比特币的在用户之间的转移(交易)为例,来引出区块链的各种神奇的机制。

广播交易信息

吃瓜群众在收到交易信息后,拿出自己的小本本记下A和B的交易,一旦记录成功,就不可撤销,不可更改

划重点!!!

吃瓜群众为什么要替别人记账本?由此引出矿工挖矿,这也是比特币的发行机制。也就是说记账的用户,系统会给予它相应的奖励。
这么多吃瓜群众,每个人都拿着小本本来记账,那么到底最后的账本应该采取谁的呢?因此,必须要有一种机制让所有人都能认同最终都记账结果的有效性,这就是比特币采取的共识机制——基于工作量证明的共识机制
各位看官,你们的小本本记好了吗?

继续,在共识机制的保障下,获得最终记账权的群众会向全网广播本次交易的交易信息,其他群众会核对确认这本交易,交易达到6个确认以上就会被记录在案。(什么?为什么是6个?)

吃瓜群众在记录交易信息的时候,会盖上时间戳(Hash值),形成完整的时间链,这个时间戳其实是一种存在证明,表明这笔交易确实真实的发生过
每次经过确认的交易记录都会形成一个区块(Block)
区块与区块之间会通过某个神奇的算法链接起来

侃侃而谈

好了,通过上面一番操作之后,相信各位看官对比特币啊,区块链啊这些基本的概念,还有一般的流程什么的都有了一个感性上的认识(嗯。我好像知道区块链是什么了!)下面我们来深入的总结一下区块链的关键思想和技术吧!

去中心化

比特币的网络中,没有一个中心化的服务器,整个网络由各种节点组成,共同组成了一个去中心化的网络
货币发行的去中心化,在比特币网络中,货币发行是由"矿工挖矿"这种机制来保障的,而这种机制是一个完全的去中心化的机制
货币的交易流转去中心化,比特币的每一笔交易都是由网络中的所有节点来共同保证其有效性和不可篡改的

开放性

所有比特币用户的交易信息都被记录在一个分布式账本中,这个账本信息对所有用户公开,任何人都可以下载这个账本信息
比特币网络是开放的,任何服务器都可以接入到网络中,也可以下载到全量的账本信息

不可篡改性

每一笔交易信息都被存放在区块之中,每一个新产生的区块都是按照时间(Hash 值)的顺序链接在一起的,时间的不可逆导致任何试图修改区块信息的操作都是可以被追溯的
每一个新产生的区块都应用量哈希算法来进行加密,参与哈希的因子不仅包括本次交易的信息,而且还包括上一个区块的哈希值,这种方式下,如果对某一区块的信息进行修改,需要更改所有区块的信息,造假几乎是不可能的

相关技术

下图是一个真正区块的展示,区块中本次我们重点介绍的几个字段有:

Bits
Nonce
Hash
Previous Block
Merkle Root

共识机制

http://c.biancheng.net/view/1897.html

区块链技术解决了在一个去中心化网络中进行价值表示和价值传输的问题,而这种分布式的去中心化网络中如何对数据达成一致是一个非常关键的问题。在我们的日常生活中,几乎所有的事情都是达成共识的过程。而这也恰恰是比特币最核心的突破之一,即:如何在去中心化的情况下,对某个交易事件达成一致。

共识机制的两大核心

经济激励:通过每个区块产生一定数量的新的比特币来奖励参与者
引入外部资源确保安全:即通过大量的外部计算来确保共识的安全性,也就是工作量证明(Proof of Work)

达成共识的主要过程(产生新区块的过程)

监听:节点监听全网的交易信息,通过验证的交易会进入节点的内存池
构建:构建一个空的区块,称为候选区块
交易:从内存池中打包交易至候选区块
造头:构造区块头,填写区块头的下述字段
版本号version字段:表示本区块遵守的验证规则
父区块哈希值Previous Block
用merkle树汇总全部的交易,将merkle root的哈希值填写至merkle root字段
时间戳timestamp字段
填写目标值Bits字段
运算:不断调整随机数Nonce,进行Hash计算,使得计算出的Hash值满足一定的要求,即:小于目标Hash。(OR:计算出来的Hash值的二进制表示具有一定数量的前导0)
因为比较二进制数,其实比较的就是前面的0,谁的0多,谁就越小呗
打包:打包区块信息,并对外广播(gossip协议)新区块
验证:其他节点验证通过后,将其链接(Previous Block)至主链(难道还有侧链?嗯。。。)
等待:等待主链后再链接5个新区块(也就是5+1个区块)后,那么区块正式生效,不可篡改。
这种达成共识的过程,我们叫做基于工作量证明的共识机制。这里有几点可以解释一下:

工作量如何理解?

不断调整随机数进行SHA-256运算比拼的是计算机算力,这种依托算力进行的计算是一种工作量
计算Hash值小于目标Hash为什么就可以体现出工作量?
掷骰子掷出的点数<=6,平均需要掷一次,工作量可以量化为1;那么要求掷出的点数<=3呢?平均需要掷2次,工作量翻倍。当目标值很小的时候,想要让计算出的Hash值小于目标值,难道非常大
随着计算机算力的提升,如何控制计算的难度?
256位二进制数构成的目标Hash值,任意改变一个bit,难道难度就翻倍,因此,可以通过调整目标Hash值来调整难度

Hash计算

一般采用的是一次SHA-256运算,计算输出的Hash值是一个256位的二进制数构成,为了表示方便,采用16进制表示,那么就是256/4=64位16进制数
输入的一点点改变,都会引起输出的巨大变化,毫无规律可言

Bits和目标Hash值

Bits与难度是相对应的,它是用一个32位的整数来压缩存储当前256位的目标Hash值。

目标Hash值:0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Bits:0x1D00FFFF
怎么压缩的呢?规则为:

目标Hash值的有效位数 = (64-8)+ 2 = 58 (也就是29个字节),那么Bits字段的最高字节 = 29,16进制表示就是 0x1D
+2是因为目标Hash值的最高位0xFF(1111 1111)> 0x80(1000 0000)
Bits剩下的3个字节,取Hash值的最高3个字节来存储

Merkle Root

在比特币中使用梅克尔树,是为了将交易信息存储在每个区块中。

用Merkle树来汇总所有的交易信息,并且将汇总得到的Merkle Root放在区块头,这样做的好处是显然的:

所有的交易参与Hash计算,直至汇总到Merkle Root。如果有人篡改了梅克尔树底部的一些数据区块,会导致上一层的哈希指针不匹配,那么他不得不一直篡改上一层的哈希指针,直到数的顶端,而此刻,篡改即将终止,因为我们存储了树根节点的哈希指针,这样就可以防止交易信息被篡改
简化支付验证:将Merkle Root保存在区块头,而不是所有的完整的交易信息,可以实现一个light client,用户只需下载非常小的区块头数据就可以验证一笔交易的真实性
按最长链原则,拉取所有的区块头到本地
计算待验证交易的tx_hash值
找到存有tx_hash的区块头
找到这个区块中的Merkle Tree的一些关键节点,并按构造规则构建一颗Merkle-Tree-Copy
比较Merkle-Tree-Copy的Root和区块中的Root是不是一样
只要我们记住最前面的树根节点的哈希指针,我们就可以根据哈希指针回溯到表中的任意位置
3.1.6 为什么通过验证后还需要等待6个区块
交易被打包进入区块,并且通过验证之后,需要再等待6个区块才会正式生效,主要是为了解决"双花"问题。那么什么是"双花"问题呢?这里,我们整理一下与此相关的几个概念:

51%算力攻击
双花问题
3.1.6.1 51%算力攻击
在基于工作量证明的共识机制当中,网络中的节点比拼计算机算力进行复杂的Hash运算,最先算出结果的那个节点所生成的区块将被全网接受,链接到区块链上,称为新的区块。那么,当某个人或组织掌握了全网51%的算力时,就可以按"随心所欲"的伪造交易。

双花问题

假设小黑有666BTC,他把这些币支付的大白同时,也把这些币发到自己的另一钱包地址上。

最终,发给大白那笔交易先被得到了确认,并打包在区块高度为N的区块内。

这时,控制了超过50%算力的小黑,发起51%算力攻击,他通过重新组装第N个区块,将发给自己那笔交易打包进区块里,并持续在这条链上延展区块,由于算力的优势,这条量将称为合法的最长链。(用户只承认他看到的最长链——最长链原则)

这时,转账给大白的那边交易就被篡改。

如何避免

为了避免双花造成的损失,一般认为,等 6 个区块确认后的比特币交易基本上就不可篡改了。

一般来说,确认的区块数越多,越安全,交易被篡改的可能性就越低。

想要实现双花,其实就是恶意节点和安全节点相互比拼算力挖矿的过程,当恶意节点形成的恶意链比安全节点形成的可信链长的时候,恶意节点就可以实现双花。这里,做了一个假设,即:假设恶意节点占全网的算力为p,那么安全节点就为q=1-p,在经过第n个区块后,恶意链追上可信链的概率为:

(pq)n ( p q ) n
那么,当可信节点产生了n个区块后,恶意节点产生了多少个区块呢?

在这里,中本聪假设恶意节点产生的区块的个数服从一个泊松分布:

P(X=k)=(λkk!)e−λ P ( X = k ) = ( λ k k ! ) e − λ
这个公式表示:恶意节点产生k个区块的概率为:P(X=k)

因此,我们可以求出,在可信节点产生n个区块后,恶意节点产生区块的期望值。

∑∞k=0(λkk!)e−λ(pq)n−k ∑ k = 0 ∞ ( λ k k ! ) e − λ ( p q ) n − k
对这个数列求和,当N=6,p=10%时sum=0.0002。

表示:当可信节点产生6个区块后,恶意节点产生区块个数的期望值为0.0002

也就是说,在上述假设的条件下,经过6个区块的确认后,恶意节点造假的可能性几乎为0。

区块链入门教程eth的账户和基本单位

我们在命令行输入 eth.accounts 可以看到当前该区块链中共有几个账号,以及每个账号的公钥地址。
在eth系统中,状态是由被称为“账户”(每个账户由一个20字节的地址)的对象和在两个账户之间转移价值和信息的状态转换构成的。
eth的账户包含四个部分:
随机数,用于确定每笔交易只能被处理一次的计数器
账户目前的以太币余额
账户的合约代码,如果有的话
账户的存储(默认为空)
简单地说,每一个eth账户都有一对公钥和私钥组成。
公钥我们可以理解为就是账户地址,任何其他账户都可以访问该地址
私钥可以理解为一段加密过的密码,这一对公钥和私钥共同组成一个唯一标示的eth账户。
例如在上节我们建立的第一个eth账户 eth.accounts[0] 中,地址 0xbcf5b841303bc08026ce2d3b8f83498ffe42c12f 就是公钥,而对密码加密而成的,就是私钥。
增加账户
我们可以输入命令 personal.newAccount(“123”) 来新建一个账户,(注意123可以修改为任何别的密码)
当eth的私链在挖矿时候,所挖到的以太币都会存入第一个eth账户中,即eth.accounts[0] 中,而eth.accounts[1]默认是不会有以太币的。这个时候我们可以用下面的命令来查看eth.accounts[0] 中的以太币余额。
eth.getBalance(“0xbcf5b841303bc08026ce2d3b8f83498ffe42c12f”)
如何在两个账户之间进行以太币转换
前面说过每个账户的公钥(地址)是一切eth账户操作的核心,但地址字符串太长,我们用acc0/acc1 分别代表accounts[0]和[1],另外设置要转移0.01个以太币
1.> acc0 = eth.accounts[0]
2."0xbcf5b841303bc08026ce2d3b8f83498ffe42c12f"
3.> acc1 = eth.accounts[1]
4."0xb8b12a801b610176935a15321f77b48dd5c0c448"
5.> amount = web3.toWei(0.01)
6."10000000000000000"

这个时候我们可以使用eth.sendTransaction来将0.01个以太币从acc0转移到acc1中。

1.> eth.sendTransaction({from: acc0, to: acc1, value: amount})

eth的一个保护机制,每隔一段时间账户就会自动锁定,这个时候任何以太币在账户之间的转换都会被拒绝,除非把该账户解锁.
这个时候我们就需要执行 personal.unlockAccount(acc0) 并输入密码来解锁acc0才可。

1.> personal.unlockAccount(acc0)
2.Unlock account 0xbcf5b841303bc08026ce2d3b8f83498ffe42c12f
3.Passphrase: 
4.true
5.>

这个时候我们重新执行命令eth.sendTransaction({from: acc0, to: acc1, value: amount}), 结果如下:

1.> eth.sendTransaction({from: acc0, to: acc1, value: amount})
2."0xeea74dd5ff3f1287614d52ebb674edb93e8c5e51e4296835044d3d858d3d9f10"
3.> eth.getBalance(acc1)
4.10000000000000000
5.>

我们可以看到这个时候acc1有了数值10000000000000000, 而不再是之前的0了。但我们明明要给0.01ether币的,为何数值会如此大呢? 其实是对的,我们只要输入命令web3.fromWei(10000000000000000,”ether”) 就可以知道了。

1.> web3.fromWei(10000000000000000,"ether")
2."0.01"

Ether币的基本单位
Ether币最小的单位是Wei,也是命令行默认的单位, 然后每1000个进一个单位,依次是

1.kwei (1000 Wei)
2.mwei (1000 KWei)
3.gwei (1000 mwei)
4.szabo (1000 gwei)
5.finney (1000 szabo)
6.ether (1000 finney)

简单地说就是就是1 以太币 = 1000000000000000000 Wei (这就是上一站章中为何我们转移0.01个以太币,结果却显示很长的原因)
如何进行ether 和 Wei之间的转换

1.Ether–> Wei:web3.toWei
2.> web3.toWei(1)
3."1000000000000000000"
4.> web3.toWei(1.3423423)
5."1342342300000000000"
6.> web3.toWei(0.00034)
7."340000000000000"

1.>
2.Wei –> Ether: web3.fromWei
3.> web3.fromWei(10000000000000000)
4."0.01"
5.> web3.fromWei(1000000000000000000)
6."1"
7.>

以上是关于区块链入门的几个基本问题的主要内容,如果未能解决你的问题,请参考以下文章

区块链入门教程eth的账户和基本单位

区块链快速入门--原来这就是区块链

区块链快速入门--原来这就是区块链

区块链快速入门--原来这就是区块链

区块链快速入门--原来这就是区块链

区块链快速入门——区块链简介