0

区块链,中心去,何曾着眼看君王?用Go语言实现区块链技术,通过Golang秒懂区块链

 1 year ago
source link: https://v3u.cn/a_id_248
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

区块链,中心去,何曾着眼看君王?用Go语言实现区块链技术,通过Golang秒懂区块链

首页 - Go & Ruby /2022-08-27
区块链,中心去,何曾着眼看君王?用Go语言实现区块链技术,通过Golang秒懂区块链

    区块链技术并不是什么高级概念,它并不比量子力学、泡利不相容原则、哥德巴赫猜想更难以理解,但却也不是什么类似“时间就是金钱”这种妇孺皆知的浅显道理。区块链其实是一套统筹组织记录的方法论,或者说的更准确一些,一种“去中心化”的组织架构系统。

    众所周知,任何一个公司、组织、或者是机构,都遵循同一套组织架构原则,那就是“下级服从上级、少数服从多数”原则。而对于区块链技术来说,只遵循这个原则的后半句,那就是“少数服从多数”,不存在“下级服从上级”。

    进而言之,在区块链中,根本就没有什么所谓“上级”的概念。

    什么是“上级”?

    一艘在大海中航行的货船上,一定会有一位船长,游荡在非洲大草原上的狮群里,一定会有一个狮王,同样的,群狼之首,是为头狼,群猴之首,是为猴王。在地球上生活着的群居动物中,你很难找出一种群体是没有“首领”或者是“上级”的。

    这就是最朴素的“中心化”概念,绝对中心化系统负责制定系统规则,负责监控系统运作,负责系统未来走向,中心化系统可以是一个个体,也可以由多个个体组成的小群体,中心化系统以外的个体,则没有中心化本身的权力。

    换句话说,绝对中心化系统往往会带来一个负面,那就是:信息不对等(asymmetric information)。指在中心化群体中,中心化主体掌握的信息比较充分,往往处于比较有利的地位,而其他信息贫乏的个体,则处于比较不利的地位。

    去中心化,就是把绝对中心化这一套拿掉,所有个体都是平等的,所有行为都记录在数据区块中,行为的合法性遵循“少数服从多数”原则。

    说白了,就是一个班级里,没有了“老师”的概念,大家都是学生,或者说,大家也都可以是“老师”,每个人都有主导个体行为的能力,而行为的合法性需要所有个体“投票”决定,这就是所谓的去中心化。

    区块链(BlockChain)

    区块链本质上就是实现上面去中心化组织架构系统的一种容器,或者说的更准确一些,区块链是一种特殊的数据结构。

    一个区块链,就和其他基于数组的数据结构一样,由一个一个的区块构成,它可以存储一个数据集,以及一些把区块合并在一起的机制。

    区块链有一个显著的特性,就是有序:

下标	区块
0 第一个区块
1 第二个区块
2 第三个区块

    但是区块链本身是可变的,所以多个区块的逻辑连接成一个序列,通常可以采用指针的形式,指向存储器中前一个区块和后一个区块的网络地址:

下标	区块	上一个下标	下一个下标
0 第一个区块 - 1
1 第二个区块 0 2

    除此之外,每一个区块还存储前一个区块的 Hash。不连续和随机离散的 Hash 非常适合检查数据的完整性,因为如果输入的数据有哪怕一位字符的变化,它产生的 Hash 也将明显不同。说白了就是把具体数据通过哈希算法散列成对应的字符串,这些字符串可以验证区块的合法性:

下标  上一个区块的 Hash 内容  上一个区块   下一个区块
0 创世块 第一个区块 - 1
1 哈希 第二个区块 0 2
2 哈希 第三个区块 2 3

    需要注意的是,第一个区块是没有上一个区块的Hash值的,也被称之为“创世区块”,这个区块是唯一的,所有通过合法性验证的区块往回追溯,一定可以追溯至创世区块的位置。

    也就是说,所有在回溯路线上的区块,都是合法的,没有被篡改过的区块。

    根据区跨链特点,我们应该先实现区块链中的区块:

type Block struct {
Data string
Hash string
PrevBlockHash string
}

    这里定义一个结构体,字段有三个,分别存储区块数据,当前区块数据散列后的哈希以及上一个区块数据的哈希。

    随后定义加密算法函数:

func Sha256(src string) string {
m := sha256.New()
m.Write([]byte(src))
res := hex.EncodeToString(m.Sum(nil))
return res
}

    该函数可以将具体数据散列成为hash

    接着定义创世区块函数:

func InitBlock(data string) *Block {
block := &Block{data, Sha256(data), ""}

return block
}

    创世区块并不存储上一个区块的hash,因为它是开风气之先的区块。

    随后声明创建普通区块函数:

func NodeBlock(data string, prevhash string) *Block {
block := &Block{data, Sha256(data), prevhash}

return block
}

    该函数负责生成创世区块其后的区块,将会存储之前一个区块的数据hash。

    开始创建创世区块:

newblock := InitBlock("创世区块数据")

fmt.Println(newblock)

    数据返回:

&{创世区块数据 62a034a244fbffbffda75fbe9c0ca7b86e40ce5329c957c180847ed210e1225a }

    接着声明区块链对象:

blockchain := []*Block{}

    这里我们使用切片,切片的每一个元素是区块结构体指针。

    将创世区块添加到区块链中:

newblock := InitBlock("创世区块数据")

fmt.Println(newblock)

blockchain := []*Block{}

blockchain = append(blockchain, newblock)

fmt.Println(blockchain)

    程序返回:

&{创世区块数据 62a034a244fbffbffda75fbe9c0ca7b86e40ce5329c957c180847ed210e1225a }
[0x14000114180]

    如此,创世区块就“上链”了,接着添加普通区块:

block2 := NodeBlock("第二个区块数据", blockchain[len(blockchain)-1].Hash)

blockchain = append(blockchain, block2)

block3 := NodeBlock("第三个区块数据", blockchain[len(blockchain)-1].Hash)

blockchain = append(blockchain, block3)

fmt.Println(blockchain)

    每一个普通区块都会存储上一个区块的数据hash,程序返回:

&{创世区块数据 62a034a244fbffbffda75fbe9c0ca7b86e40ce5329c957c180847ed210e1225a }
[0x1400006e180]
[0x1400006e180 0x1400006e1e0 0x1400006e210]

    完整流程:

package main

import (
"crypto/sha256"
"encoding/hex"
"fmt"
)

type Block struct {
Data string
Hash string
PrevBlockHash string
}

func Sha256(src string) string {
m := sha256.New()
m.Write([]byte(src))
res := hex.EncodeToString(m.Sum(nil))
return res
}

func InitBlock(data string) *Block {
block := &Block{data, Sha256(data), ""}

return block
}

func NodeBlock(data string, prevhash string) *Block {
block := &Block{data, Sha256(data), prevhash}

return block
}

func main() {

newblock := InitBlock("创世区块数据")

fmt.Println(newblock)

blockchain := []*Block{}

blockchain = append(blockchain, newblock)

fmt.Println(blockchain)

block2 := NodeBlock("第二个区块数据", blockchain[len(blockchain)-1].Hash)

blockchain = append(blockchain, block2)

block3 := NodeBlock("第三个区块数据", blockchain[len(blockchain)-1].Hash)

blockchain = append(blockchain, block3)

fmt.Println(blockchain)
}

    至此,一个完整的区块链实体结构就完成了。

    通过golang实现具体的区块链结构,我们可以看出来,所谓的“去中心化”,并不是字面意义上的去掉中心,而是中心的多元化,任何节点都可以成为中心,任何中心也都不是持久化的,中心对每个节点不具备强制作用,只需要达成“少数服从多数”的共识即可。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK