现在的位置: 首页 > 数据库 > 正文

区块链初体验

2020年02月12日 数据库 ⁄ 共 4918字 ⁄ 字号 评论关闭

目录

1 区块链是啥

2 区块链的最大特点

3 区块链链式结构

3.1 区块

3.2 链式结构

4 Hash哈希(散列)

5 Hash 的不可修改性

6 验证账本

7 区块链应用场景

8 实践(基于GO语言)

7.1 创建Block

7.2 创建Blockchain

7.3 创建Http Server


1 区块链是啥

一种特殊的分布式数据库

因为比特币系统里的数据是用一个个区块存储的,然后通过hash的方式将一个一个区块连接,形成一个区块的链条,所以叫做区块链。

区块链的主要作用是储存信息。任何需要保存的信息,都可以写入区块链,也可以从里面读取,所以它是数据库

任何人都可以架设服务器,加入区块链网络,成为一个节点。区块链的世界里面,没有中心节点,每个节点都是平等的,都保存着整个数据库。你可以向任何一个节点,写入/读取数据,因为所有节点最后都会同步,保证区块链一致。

2 区块链的最大特点

分布式数据库并非新发明,市场上早有此类产品。但是,区块链有一个革命性特点。

区块链没有管理员,它是彻底无中心的。其他的数据库都有管理员,但是区块链没有。如果有人想对区块链添加审核,也实现不了,因为它的设计目标就是防止出现居于中心地位的管理当局。

正是因为无法管理,区块链才能做到无法被控制。否则一旦大公司大集团控制了管理权,他们就会控制整个平台,其他使用者就都必须听命于他们了。

但是,没有了管理员,人人都可以往里面写入数据,怎么才能保证数据是可信的呢?被坏人改了怎么办?请接着往下读,这就是区块链奇妙的地方。

3 区块链链式结构

3.1 区块

区块链由一个个区块(block)组成。区块很像数据库的记录,每次写入数据,就是创建一个区块。

区块头(Head):记录当前区块的头信息。

包含上一个区块的哈希值(PreHash),本区块体的哈希值(Hash),以及时间戳(TimeStamp)等等。

区块体(Body):实际数据

3.2 链式结构

区块链里的第一个区块由中本聪创建于2009年,被称为创世区块。它是区块链里面所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。

每一个节点都“知道”创世区块的哈希值、结构、被创建的时间和里面的一个交易。因此,每个节点都把该区块作为区块链的首区块,从而构建了一个安全的、可信的区块链的根。

创世区块的哈希值

000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

4 Hash哈希(散列)

数据结构检索(查找)之入土攻略(二)

把任意长度的输入key作为自变量,通过hash函数(),变换成固定长度的输出,该输出就是哈希值。

哈希值 = hash(key)

区块链的哈希长度是256位,这就是说,不管原始内容是什么,最后都会计算出一个256位的二进制数字。而且可以保证,只要原始内容不同,对应的哈希一定是不同的。

5 Hash 的不可修改性

区块与哈希是一一对应的,每个区块的哈希都是针对"区块头"(Head)计算的。也就是说,把区块头的各项特征值,按照顺序连接在一起,组成一个很长的字符串,再对这个字符串计算哈希。

Hash = SHA256( 区块头 )

上面就是区块哈希的计算公式,SHA256是区块链的哈希算法

举例说明:Hash(张三借给李四100万,利息1%,1年后还本息 .....) = AC4635D34DEF账本上记录了AC4635D34DEF这样一条记录。

区块头包含很多内容,其中有当前区块的哈希,还有上一个区块的哈希。如果当前区块的哈希变了,或者上一个区块的哈希变了,一定会引起当前区块的哈希改变。

这一点对区块链有重大意义。

如果有人修改了一个区块,该区块的哈希就变了。为了让后面的区块还能连到它(因为下一个区块包含上一个区块的哈希),该人必须依次修改后面所有的区块,否则被改掉的区块就脱离区块链了。由于后面要提到的原因,哈希的计算很耗时,短时间内修改多个区块几乎不可能发生,除非有人掌握了全网51%以上的计算能力。

正是通过这种联动机制,区块链保证了自身的可靠性,数据一旦写入,就无法被篡改。这就像历史一样,发生了就是发生了,从此再无法改变。

6 验证账本

比如现在有这么一个账本,张三想搞点小手段,偷偷的把自己余额改为了300:

那么网络中就会出现一些假数据,如何确认张三修改了数据是假的数据呢?这就是比特币账本如何验证的问题。

hash函数登场!!!!

MD5是一个Hash函数。MD5可以用于校验下载文件是否出错:如果文件的数据有错误,那么文件的hash值就会和网站提供的正确的hash值不一样。这样就可以确定我们下载的文件是否出错。

同样的道理可以用在比特币账本校验中,对一个账本hash之后,就可以得到一个hash值

这样的hash值与其他数据保存下来,就形成了一个区块(也叫打包、记账、挖矿)

假如这时候来了第二个账本:

在对第二个账本进行Hash时,会传入第一个账本的Hash值,和第二个账本的原始数据一起进行Hash(就是通过这种方式将块与块相连接!)。如果hash值结果是正确的,就说明传入的hash值也是正确的。这样再将第二个账本的hash传入第三个账本,这样一直传递下去,产生第四个块,第五个块,第N个块...,连起来就成了区块链。

每个节点核对信息的时候,只需要核对最后一个区块的信息是否正确,如果最后一个区块的hash是正确的话,那么说明整个区块链的账本都是正确的,由此完成高效的验证。

7 区块链应用场景

8 实践(基于GO语言)

https://github.com/AustinDeng/BlockChain

func main(){ bc := core.NewBlockchain() bc.sendData(data:"Send 1 BTC to Jacky") bc.sendData(data:"Send 1 EOSto Jack") bc.Print()}

7.1 创建Block

type Block struct{ Index int64 //区块编号 Timestamp int64 //区块时间戳 PrevBlockHash string //上一个区块哈希值 Hash string //当前区块哈希值 Data string //区块数据}func caculateHash(b Block) string{ blockData := string(b.Index) + string(b.Timestamp) + string(b.PrevBlockHash) + string(b.Data) hashInBytes := sha256.Sum256([]byte(blockData)) return hex.EncodeToString(hashInBytes[:])}func generateNewBlock(preBlock Block, data string) Block{ newBlock := Block{} newBlock.Index = preBlock.Index + 1 newBolck.PrevBlockHash = preBlock.Hash newBlock.Timestamp = time.Now().Unix() newBlock.Data = data newBlock.Hash = calculateHash(newBlock) return newBlock}//生成创世区块func generateGenesisBlock() Block{ preBlock := Block{} preBlock.Index = -1 preBlock.Hash = "" return generateNewBlock(preBlock, data:"Gensis Block") }

7.2 创建Blockchain

type Blockchain struct{ Block []*Block}func (bc *Blockchain) apendBlock(newBlock *Block){ if len(bc.Blocks) == 0{ bc.Blocks = append(bc.Blocks, newBlock) return } if isValid(*newBlock, *bc.Blocks[len(bc.Blocks) - 1]){ bc.Blocks = append(bc.Blocks, newBlock) } else{ log.Fatal(v:"invalid block") }}func isValid(newBlock Block, oldBlock Block) bool{ if newBlock.Index -1 != oldBlock.Index{ return false } if newBlock.PrevBlockHash != oldBlock.Hash{ return false } if calculateHash(newBlock) != newBlock.Hash{ return false } return true}func (bc *Blockchain) SendData(data string){ preBlock := bc.Blocks[len(bc.Blocks) - 1] newBlock := generateNewBlock(*preBlock, data) bc.apendBlock(&newBlock)}func NewBlockchain() *Blockchain{ genesisBlock := generateGenesisBlock() blockchain := Blockchain{} blockchain.apendBlock(&genesisBlock) return &blockchain}func (bc *Blockchain) print(){ for _, block := range bc.Blocks{ fmt.Printf(format:"Index:%dn", block.Index) fmt.Printf(format:"Prev.Hash:%dn", block.PrevBlockHash) fmt.Printf(format:"Curr.Hash:%dn", block.Hash) fmt.Printf(format:"Data:%dn", block.Data) fmt.Printf(format:"Timestamp:%dn", block.Timestamp) }}

7.3 创建Http Server

var blockchain *core.Blockchainfunc run(){ http.HandleFunc(pattern:"/blockchain/get",blockchainGetHanle) http.HandleFunc(pattern:"/blockchain/write",blockchainWriteHanle) http.ListenAndServer(addr:"localhost:8888",handle:nil)}func blockchainGetHandler(w http.ResponseWriter, r *http.Request){ bytes, error := json.Marshal(blockchain) if error != nil{ http.Error(w, error.Error(), http.StatusInternalServerEoor) return } io.WriteString(w, string(bytes))}func blockchainWriterHandler(w http.ResponseWriter, r *http.Request){ blockData := r.URL.Query().Get(key:"data") blockchain.sendData(blockData) blockchainGetHandler(w,r)}func main(){ blockchain = core.NewBlockchain() run()}


学习自:

《区块链技术核心概念与原理讲解》

《用GO语言构建自己的区块链》

《私有区块链,我们一起GO》

阮一峰《区块链入门教程》

以上就上有关区块链初体验的全部内容,学步园全面介绍编程技术、操作系统、数据库、web前端技术等内容。

抱歉!评论已关闭.