malefo`s blog 别想那么多,去做就对了

区块链学习笔记

2020-03-04
malefo

Go

* content {:toc} ## *前言* 我是从2017年开始知道了区块链,然后开始入迷,我就是想方设法的去找各种资料和教程来看,也参加了一个宣讲会。 然后由区块链知道了go语言,开始学习go语言,但是本人的自律能力实在是差,老是坚持不下来。 来到新公司后,机缘巧合新公司有一位同事是go语言的开发者,而他也正好离职,然后他手上的项目就落到了我这个学了几天的人手上。 然后经过几个月的项目历练,对go已经比较熟悉,这时候我就继续了我喜爱的区块链学习。。。 ## *结构* * [1 区块-block](#1-区块) * [2 工作量证明-proof of work](#2-工作量证明) * [3 区块链-block chain](#3-区块链) * [4 交易-transaction](#4-交易) * [4 持久化-persistence ](#5-持久化) #### 正文 ##### 1 区块 区块是构成区块链的单位,每一个区块包含的参数如下 ``` type Block struct { // 日期 Timestamp int64 // 交易 transactions []*Transaction // nonce Nonce int64 //hash Hash []byte //区块高度 Height int64 //上一个区块的hash PrevBlockHash []byte } ``` 可见一个区块中是包含了多比交易 区块分为两种,创世区块和普通区块,至于里边的区别就是交易的内容有些不同,这点到交易的时候再细说。 在区块的参数中,我们主要说一下hash和nonce,这两个参数的产生需要借组工作量证明来生成,何为工作量证明, 即证明你为生成这个块做过工作,有消耗,消耗什么?电能。 nonce:即为计算出比指定难度小的hash所计算的次数和 hash:区块的hash值 看一段代码 ``` func (pow *ProofOfWork)run()(nonce int64, hash []byte){ nonce = 0 var hashInt big.Int var tempHash [32]byte for { dataBytes := pow.prepareData(nonce) tempHash = sha256.Sum256(dataBytes) nonce++ hashInt.SetBytes(tempHash[:]) if hashInt.Cmp(pow.target) < -1 { break } } hash = tempHash[:] return } ``` 这是计算nonce和hash的方法,可以看出在这里有个无限for循环,只有当计算出来的hash小于给定的target,这个区块才能成立, nonce和hash才能确认 ##### 2 工作量证明 为什么需要工作量证明,这里引用一篇博客的话 >>http://www.bugclosed.com/post/25 >在分布式网络中各个孤立的节点要有一种机制对某件事情达成共识,而工作量证明(Proof of Work)就是一种应用在区块链中的共识机制,另一种著名的公式机制是权益证明(Proof of Stake)。 >比特币网络采用了工作量证明的机制,可以简单理解为在做一件事情之前需要提供自己完成了一定的前置工作的证明,而其他节点可以很容易的验证这个证明的真伪。类似现实生活中的学历证书,驾驶证等等,获得需要经过大量努力,验证真伪相对容易。 >比特币的工作量证明是通过让挖坑节点计算新区块数据+nonce的hash值,不断变化nonce值使得产生的hash结果的前N位刚好是0从而达到目标。而这个计算过程没有捷径可走,只能不断反复计算,消耗算力。为了提高自己的计算速度,更快得到结果,从而得到挖矿奖励,需要采用更高性能的计算设备。但当性能提高后计算结果比比特币预制的10分钟更端后,比特币网络会动态增加难度,让计算时间重新归回10分钟。 >遍布世界各地的分布式网络中,就是一个赤裸裸的逐利场,你不能指望每个节点都诚实可靠不作恶,只能假定各个节点都可能作恶,通过一种机制来保证他们不作恶。为了奖励旷工计算和保存账本数据,通过挖矿奖励来驱动他们。而为了让他们不作恶,是需要让他们”付出代价“才行,工作量证明就是付出算力的代价,权益证明就是付出权益,表面自己愿意投入其中。工作量证明机制并不新鲜,比特币中的hashcash在很早之前就应用在了垃圾邮件过滤的场景中。 概括就是,你在做这件事之前,需要考个证。 因此我们在生成区块的时候都要去靠这个证,这个证就是proofOfWork,来看看他的结构 ``` type ProofOfWork struct { block *Block target *big.Int } ``` 里边的参数有两个,一个是你需要证明的区块,另一个就是目标值,这个目标值在新建pow的时候给上 ``` const targetBit = 20 func NewProofOfWork(block *Block) *ProofOfWork{ target := big.NewInt(1) //左移 236,20个0换成16进制就是4个位置 target = target.Lsh(target, 256 - targetBit) return &ProofOfWork{ block: block, target: target, } } ``` 看到这里,target我直接写死了,没有像比特币一样会进行一个浮动,前期好出,后期难出。 关于难度值,我推荐一篇博客 >> https://cloud.tencent.com/developer/news/245238 这里target换成16进制就是16个数,1在第21位,前20个0换成16进制就是4位,因此难度值为H0000 1000 0000 0000, 要计算比这个小那就是从H0000 0FFF FFFF FFFF开始。 怎么证明呢,那就是不停的进行计算。不停的大量计算是很耗费能源的 >摩根士坦利发布的一项报告预测曾显示,2018年,比特币的电力需求预计将增长三倍,一年的用电量相当于阿根廷全国一年的电力需求 这样的消耗是非常恐怖的,但是没办法,就好比,人要开车就必须要考驾照,尽管他在练习的时候会撞好几次车,付好几次维修费, 但总比天天在国道在高速上撞车好吧。 技术是没问题的,只是我们需要把它合理的使用和合理的规划,找到适用的场景,才能避免浪费。 ##### 3 区块链 所谓区块链呢,就是把一个个区块连城一个链,就好比一个ArrayList,有序的自动扩充数组。 有一个更好的比喻,就好比微信多人聊天,每一个人发的消息就是一个区块,只不过这个区块里边的数据只有一条, 久而久之,这个聊天群里就有了很长很长的历史消息记录,就算其中一个人删了某一条,大家还是看得到,整个历史记录不会发生变化。 来看看区块链的数据结构吧 ``` type BlockChain struct { Tip []byte DB *bolt.DB //数据裤 } ``` tip是最新区块的区块hash,DB是数据裤,用来存储区块数据的。 ##### 3 交易 我认为交易是区块链的核心,我来阐述一下。 在中心化的交易中,每个用户单独维护自己的钱包,钱包记载了你的可用资金,每个账户的交易记录都是各自可看而对于全网是不可看的。 由中心化,中央服务器来维护这些交易款项。 在区块链之中,没有了中心化,每笔交易都记录在一条链之中。每次的交易就是在链中寻找这个账户的可用交易项。在区块链之中, 每一笔交易都分为输入和输出,而输入是由上一笔交易的输出而来,环环相扣。 ``` ```

Similar Posts