【区块链Go语言实现】第一部分:区块链基本原型

0x00 介绍

区块链(Blockchain)是21世纪最具革命性的技术之一,目前它仍处于逐渐成熟阶段,且其发展潜力尚未被完全意识到。从本质上讲,区块链只是一种记录的分布式数据库。但它之所以独特,是因为它并不是一个私有的数据库,而是一个公共数据库,也就是说,每个使用它的人都有一份完整或部分的数据副本。并且,只有在数据库的其他持有者同意的情况下,才可以向区块链中添加新的记录。此外,正是区块链使得加密货币和智能合约成为可能。

在本系列文章中,我们将基于区块链构建一种简单的加密货币。

0x01 区块

首先,我们从“区块链”中的“区块”介绍开始。在区块链中,区块是存储有价值信息的块。例如,比特币区块用于存储交易,这是任何一种加密货币的本质。除此之外,区块还包含一些技术信息,比如它的版本、当前时间戳和前一区块的散列值(哈希值)。

在本文中,我们不打算实现区块链或比特币规范中描述的那种区块,而是使用它的简化版本,即我们将要实现的区块结构中只包含重要的信息。下面代码中为我们的区块结构:

type Block struct {
    Timestamp     int64
    Data          []byte
    PrevBlockHash []byte
    Hash          []byte
}

Timestamp(时间戳)是区块创建时刻的时间戳,Data是包含在区块中的实际有价值的信息,PrevBlockHas存储前一区块的散列值,而Hash是当前区块的散列值。在比特币规范中,Timestamp、PrevBlockHash和Hash是区块头,它们组成了一个单独的数据结构,而交易(在我们的例子中是Data)也是一个单独的数据结构。为了简单起见,我们此处将它们混合在一起。

那么如何计算散列值呢?散列值的计算方式是区块链的一个十分重要的特性,正是该特性使得区块链变得安全。计算一个区块的散列值是一种计算上十分困难的操作,即使在快速计算机上也需要一些时间(这就是人们会购买强大的GPU来挖比特币的原因)。这是一种有意的架构设计,它使得添加新的区块变得很困难,因此可以防止对已有区块的篡改。我们将在以后的文章中讨论并实现这种机制。

现在,我们仅仅使用区块字段,连接它们,并在连接的组合上计算一个SHA-256散列值。下面,我们使用SetHash方法来实现这一操作:

func (b *Block) SetHash() {
    timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
    headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{})
    hash := sha256.Sum256(headers)

    b.Hash = hash[:]
}

接下来,依照Golang惯例,我们将实现一个函数来简化区块的创建:

func NewBlock(data string, prevBlockHash []byte) *Block {
    block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}}
    block.SetHash()
    return block
}

这样,我们就准备好了区块的工作!

0x02 区块链

现在,我们来实现一个区块链。实质上,区块链只是一个包含某些特定结构的数据库:它是一种有序的反向链接列表。这意味着区块以插入顺序进行存储,并每个区块会链接到前一区块。这个结构能够保证快速获得一个区块链中最新的区块,并能够通过区块散列值高效地获取到该区块。

在Golang中,可以使用一个数组和一个map来实现这种结构:数组用于保存有序的散列(在Go中数组是有序的),而map用于保存散列->区块对(map是无序的)。然而,对于我们的区块链原型来说,我们仅仅使用一个数组,因为现在我们不需要通过区块的散列来获得对应的区块。

type Blockchain struct {
    blocks []*Block
}

这是我们的第一个区块链,我从未想过它会这么容易。

现在我们实现添加区块的功能:

func (bc *Blockchain) AddBlock(data string) {
    prevBlock := bc.blocks[len(bc.blocks)-1]
    newBlock := NewBlock(data, prevBlock.Hash)
    bc.blocks = append(bc.blocks, newBlock)
}

这样就完了么?No!

为了向区块链中添加一个新区块,我们需要确保已经存在了一个区块,但是目前我们的区块链中并未存在任何区块。所以,在任何区块链中,都必须存在至少一个区块,区块链中的首个区块称为创世区块。下面,我们实现一个方法来创建创世区块:

func NewGenesisBlock() *Block {
    return NewBlock("Genesis Block", []byte{})
}

现在,我们可以实现一个函数来使用创世区块创建一个区块链:

func NewBlockchain() *Blockchain {
    return &Blockchain{[]*Block{NewGenesisBlock()}}
}

下面,我们来检查一下我们的区块链是否能够正常工作:

func main() {
    bc := NewBlockchain()

    bc.AddBlock("Send 1 BTC to Ivan")
    bc.AddBlock("Send 2 more BTC to Ivan")

    for _, block := range bc.blocks {
        fmt.Printf("Prev. hash: %x\n", block.PrevBlockHash)
        fmt.Printf("Data: %s\n", block.Data)
        fmt.Printf("Hash: %x\n", block.Hash)
        fmt.Println()
    }
}

输出结果如下:

Prev. hash:
Data: Genesis Block
Hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168

Prev. hash: aff955a50dc6cd2abfe81b8849eab15f99ed1dc333d38487024223b5fe0f1168
Data: Send 1 BTC to Ivan
Hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1

Prev. hash: d75ce22a840abb9b4e8fc3b60767c4ba3f46a0432d3ea15b71aef9fde6a314e1
Data: Send 2 more BTC to Ivan
Hash: 561237522bb7fcfbccbc6fe0e98bbbde7427ffe01c6fb223f7562288ca2295d1

通过上面的结果,我们可以确定该区块链可以正常工作。

0x03 结论

本文中,我们创建了一个非常简单的区块链原型:它仅仅是一个区块数组,其中每个区块都有一个链接到前一区块,不过实际的区块链要比这复杂得多。在我们的区块链中,添加新的区块简单快速,但在实际的区块链中添加新区块则需要做一些工作:在获取添加区块的权限之前,区块添加者(或者说节点)必须执行一些繁重的计算(这种机制称为工作证明,Proof-of-Work,POW)。此外,区块链是一种分布式数据库,所以并没有一个唯一的决策者。因此,一个新的区块必须由网络中的其他参与者确认和批准(这种机制称为共识机制)。最后,目前我们的区块链中还没有交易!

在后续的文章中我们将逐步讨论这些功能和特点。

英文链接:https://jeiwan.cc/posts/building-blockchain-in-go-part-1/

原文地址:https://www.cnblogs.com/leejack/p/8259723.html

时间: 2024-11-07 10:13:26

【区块链Go语言实现】第一部分:区块链基本原型的相关文章

GAIAWORLD打造区块链第一游戏公链(上篇)

仍在全球热映票房突破5亿美元的电影<头号玩家>,让观众做了个很美的梦,不愿醒来. 在片中<绿洲>的游戏创造了一个虚拟乌托邦,在这里想象力主宰一切,你可以去任何地方,做任何想做的事,成为任何想成为的人.你可以和蜘蛛侠去埃及金字塔攀岩:你可以在空中走路.舞蹈,用意念两秒钟创造出一辆豪车在空中极速狂飙:你甚至能和经典角色如恐龙.钢铁侠.初代高达.哥斯拉等并肩作战:当你遇上人生无法更改的遗憾时,可以扔出一个"时光球"的道具回到过去,改变自己. 这部电影中,我们看见未来游

用Java编写第一个区块链

原文地址:https://www.cnblogs.com/zacky31/p/9057193.html 目标: 创建一个最基本的"区块链" 实现一个简单的挖矿系统 前提: 对面向对象编程有一定的基础 注意: 值得注意的是,这不会是一个完整的功能,恰恰相反,这是一个概念证明的实例,可以帮助您进一步了解区块链. 准备: 我将会使用Java来实现,当然你也可以使用任何面向对象的语言. 环境: JDK 8 IDEA Maven 开始吧 区块链就好比多个块连接起来.其中每一块都将拥有自己的签名,

GO语言七步打造区块链

GO语言七步打造区块链 1.基础区块链的实现 2.工作量的证明 3.持久化与命令行接口 4.交易类的实现 5.钱包交易 6.交易确认 7.网络同步 原文地址:https://www.cnblogs.com/zhangyafei/p/11888289.html

区块链,使用 Go-Ethereum 搭建以太坊私有链

1.什么是Ethereum(以太坊) 以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约.开源的底层系统,以太坊从诞生到2017年5月,短短3年半时间,全球已有200多个以太坊应用诞生.以太坊是一个平台和一种编程语言,使开发人员能够建立和发布下一代分布式应用. 以太坊可以用来编程,分散,担保和交易任何事物:投票,域名,金融交易所,众筹,公司管理, 合同和大部分的协议,知识产权,还有得益于硬件集成的智能资产. 以太坊的白皮书:https://github.com/ethe

区块链3.0才能真正推动区块链时代大步向前!

第一代区块链的典型产物就是比特币及其山寨币.因为是第一代产品,区块链1.0的价值仅仅体现在数字币发行与交易上. 第二代区块链的代表是以太坊.同区块链1.0相比,区块链2.0的最大特性就是它引入了智能合约和可编程底层,这使得人们可以基于其架构开发各种用途的区块链引用,至于项目代币则是其的推广激励手段之一.区块链3.0则在区块链2.0的基础上更进一步,它具有更好的性能,其应用范围也更加广泛,诸如物联网.金融.人工智能等都可以是它大展身手的舞台.有人甚至预测,区块链3.0会真正推动区块链技术在现实中的

区块链快速入门(五)——区块链技术的演化

区块链快速入门(五)--区块链技术的演化 一.区块链技术的发展 比特币区块链面向转账场景,支持简单的脚本计算.如果引入更多复杂的计算逻辑,将能支持更多应用场景,即智能合约(Smart Contract).智能合约可以提供除了货币交易功能外更灵活的合约功能,执行更为复杂的操作.引入智能合约的区块链,已经超越了单纯数据记录功能:可以为区块链加入权限管理,高级编程语言支持等,实现更强大的.支持更多商用场景的分布式账本系统.区块链技术的三种典型演化场景如下: 二.区块链技术的分类 根据参与者的不同,区块

区块链技术工坊 - 线下区块链技术分享

区块链技术工坊由一群热爱区块链技术的开发者组织,在全国各主要城市每周举办线下区块链技术分享活动.深圳地区由HiBlock.小牛新能源.登链学院联合主办,由以太零.Qtum.FIBOS.AckBlock.HPB赞助. 区块链技术工坊坚持聚焦区块链技术分享,以技术会友,最新一期交流DAG技术,报名戳链接. 欢迎大家关注微信:upchainedu 及时获取活动信息. 以往各期内容如下: [第五期] 搞明白以太坊DAPP开发 讲师:登链学院 Tiny熊 分享大纲: DAPP与APP 的区别 智能合约开发

终于把区块链与物流的关联搞清楚了 区块链的分类 物流业中区块链技术应用的案例

原文 区块链的分类 区块链可以分为三类:公有链.私有链.联盟链. 1.公有链无官方组织及管理机构,无中心服务器,参与的节点按照系统规则自由接入网络.不受控制,节点间基于共识机制开展工作. 2.私有链建立在某个企业内部,系统的运作规则根据企业要求进行设定,修改甚至是读取权限仅限于少数节点,同时仍保留着区块链的真实性和部分去中心化的特性. 3.联盟链由若干机构联合发起,介于公有链和私有链之间,兼具部分去中心化的特性. 去中心化是区块链的最重要特征 区块链技术提供了一种无需信任单个节点.还能创建共识网

国内知名区块链技术应用研发公司,区块链交易系统开发

[本文由jys-wu编辑/系统开发微信:jys-wu]银行重金投向区块链等科技创新,欲打金融科技翻身仗据上海证券报报道,银行重金投向科技创新,一是加强基础技术研发与平台建设,推进人工智能.区块链等新兴技术落地应用:二是对线下网点进行统一改造,打造数字化银行,降低成本等.一家大行IT部负责人表示,"在金融科技形势倒逼下,银行IT角色已经改变.过去IT部门是配角,现在要起引领作用,IT目标已经上升到战略层面,需要进行顶层设计,全面赋能业务."美国最大医疗保险公司UnitedHealth宣布