当前位置: 首页 > 科技观察

如何用Go实现区块链

时间:2023-03-20 00:21:30 科技观察

本文转载自微信公众号《区块链研究实验室》,作者连三丰。转载本文请联系区块链研究实验室公众号。区块链技术被一些自互联网以来最具影响力的发明称为。尽管公众将区块链解释为投机性加密货币的代名词,但区块链实际上在现代世界中有着令人难以置信的广泛应用。事实上,加密货币只是区块链空间的一小部分,生产中的许多解决方案都是由私人组织主导的。随着区块链技术的快速发展,越来越需要技术领域的专业人士了解区块链的基础知识及其技术影响。毕竟,实现自己的区块链实际上并不像听起来那么复杂。在本文中,我们将使用2021年最流行的编程语言之一GoLang实现一个基本的区块链。那么,让我们开始吧!了解区块链区块链是为数不多的名副其实的技术之一。我们可以将区块链视为通过哈希互连的信息块,哈希是从输入数据生成的加密固定输出。由于每个块都通过哈希相互引用,因此不可能在不实质性更改链的其余部分的情况下更改链的任何部分。区块链中的每个块都可以包含几乎所有内容的数据。一个基本框架将包括每个区块过去交易的所有记录。比特币以类似的方式工作,这就是为什么你可以一直跟踪比特币交易,直到中本聪的第一笔加密货币交易。下面我们用三个块来创建区块链。第一个块是创世块。由于之前什么都没有,所以之前的hash域是空的。我们仍然使用时间戳属性和初始交易作为哈希算法的输入。该算法将吐出一长串数字和字母,代表创世块的哈希值。转到块2,我们使用创世块的哈希值作为块2的前一个哈希值。此操作将创世块链接到块2!接下来,我们将时间戳、交易列表和先前的哈希作为输入提供给我们的哈希算法。该算法将为我们提供一个新的哈希来表示块2。我们将根据需要多次重复该过程,除了块的有效性和存储区块链的能力之外没有任何限制(比特币的区块链约为330GB).在Go中创建一个简单的区块链创建我们的区块链的第一步是定义一个块是什么。Go让我们的生活更容易创建自定义类型,我们可以使用下面的代码来定义一个Block类型。在这里,Block结构有四个字段来匹配我们上面的图表。typeBlockstruct{timestamptime.Timetransactions[]stringprevHash[]byteHash[]byte}下一步是创建构造函数的Go版本以创建新块。该函数的输入将采用表示交易的字符串数组,以及表示与先前制作的块相对应的先前哈希的字节数组。下一个要查看的NewHash()函数是我们接下来要实现的。funcNewBlock(transactions[]string,prevHash[]byte)*Block{currentTime:=time.Now()return&Block{timestamp:currentTime,transactions:transactions,prevHash:prevHash,Hash:NewHash(currentTime,transactions,prevHash),}}NewHash()函数将时间、交易列表和之前的哈希值作为我们的输入参数,同时返回一个表示新生成的哈希值的字节数组。在这个函数中,我们基本上只是将所有输入混合到一个称为输入的单字节数组中。我们使用append()函数的附加时间参数prevHash来执行此操作,方法是使用...将时间转换为字符串以将prevHash切片附加为后缀时间切片。然后,我们遍历交易并将每个单独的交易附加到输入数据blob。有趣的语法string(rune(transaction))...只是Go中将交易的每个元素转换为可以附加到输入的切片的一种方式。这是打字垃圾,所以如果你真的想,请深入研究。funcNewHash(timetime.Time,transactions[]string,prevHash[]byte)[]byte{input:=append(prevHash,time.String()...)fortransaction:=rangetransactions{input=append(input,string(rune(transaction))...)}hash:=sha256.Sum256(input)returnhash[:]}最后,我们使用crypto包调用sha256.Sum256()并将输入作为其参数。这将为我们所有的数据输入提供新的哈希表示。当我们返回hash[:]时,hash[:]使用的[:]语法会在返回时将哈希切碎到适当的长度。这实际上是我们开始链接我们的区块链所需的全部。当然,我们希望在程序中看到某种输出,所以我们可以在打印时使用一些辅助方法:funcprintBlockInformation(block*Block){fmt.Printf("\ttime:%s\n",block.timestamp.String())fmt.Printf("\tprevHash:%x\n",block.prevHash)fmt.Printf("\tHash:%x\n",block.Hash)printTransactions(block)}funcprintTransactions(block*Block){fmt.Println("\tTransactions:")fori,transaction:=rangeblock.transactions{fmt.Printf("\t\t%v:%q\n",i,transaction)}}现在剩下的就是创建新的交易、区块和哈希。我们可以通过我们的主要方法来做到这一点。我们定义了一个字符串数组来记录我们区块链中的交易。另请注意我们如何将空字节数组传递给NewBlock()以生成名为genesisBlock的第一个块。funcmain(){genesisTransactions:=[]string{"IzzysentWill50bitcoin","WillsentIzzy30bitcoin"}genesisBlock:=NewBlock(genesisTransactions,[]byte{})fmt.Println("---FirstBlock---")printBlockInformation(genesisBlock)block2Transactions:=[]string{"JohnsentIzzy30bitcoin"}block2:=NewBlock(block2Transactions,genesisBlock.Hash)fmt.Println("---SecondBlock---")printBlockInformation(block2)block3Transactions:=[]string{"WillsentIzzy45bitcoin","IzzysentWill10bitcoin"}block3:=NewBlock(block3Transactions,block2.Hash)fmt.Println("---ThirdBlock---")printBlockInformation(block3)}为了创建一个新块,我们把之前的哈希block散列值NewBlock()与相应的交易历史一起传递。如果您想要在一个地方查看整个程序,则为:packagemainimport("crypto/sha256""fmt""time")typeBlockstruct{timestamptime.Timetransactions[]stringprevHash[]byteHash[]byte}funcmain(){genesisTransactions:=[]string{"IzzysentWill50bitcoin","WillsentIzzy30bitcoin"}genesisBlock:=NewBlock(genesisTransactions,[]byte{})fmt.Println("---FirstBlock---")printBlockInformation(genesisBlock)block2Transactions:=[]string{"JohnsentIzzy30bitcoin"}block2:=NewBlock(block2Transactions,genesisBlock.Hash)fmt.Println("---SecondBlock---")printBlockInformation(block2)block3Transactions:=[]string{"WillsentIzzy45bitcoin","IzzysentWill10bitcoin"}block3:=NewBlock(block3Transactions,block2.Hash)fmt.Println("---ThirdBlock---")printBlockInformation(block3)}funcNewBlock(transactions[]string,prevHash[]byte)*Block{currentTime:=time.Now()return&Block{timestamp:currentTime,transactions:transactions,prevHash:prevHash,Hash:NewHash(currentTime,transactions,prevHash),}}funcNewHash(timetime.Time,transactions[]string,prevHash[]byte)[]byte{input:=append(prevHash,time.String()...)fortransaction:=rangetransactions{input=append(input,string(rune(transaction))...)}hash:=sha256.Sum256(input)returnhash[:]}funcprintBlockInformation(block*Block){fmt.Printf("\ttime:%s\n",block.timestamp.String())fmt.Printf("\tprevHash:%x\n",block.prevHash)fmt.Printf("\tHash:%x\n",block.Hash)printTransactions(block)}funcprintTransactions(block*Block){fmt.Println("\tTransactions:")fori,transaction:=rangeblock.transactions{fmt.Printf("\t\t%v:%q\n",i,transaction)}}如果要运行这个程序,将会得到以下输出:$gorunexample.go---FirstBlock---time:2021-04-0515:12:18.813294-0600MDTm=+0.000074939prevHash:哈希:43ec51c50d2b9565f221155a29d8b72307247b08eaf6731ccaTransactions:0:“IzzysentWill50bitcoin”1:“WillsentIzzy30bitcoin”---SecondBlock---时间:2021-04-0515:12:18.813477-0600MDTm=+0.000257244prevHash:43ec51c50d2b9565f221155a29d8b72307247b08eaf6731ccaHash:fcce5323a35cb67b45fe75866582db00fd32baeb92aac448c7Transactions:0:"JohnsentIzzy30bitcoin"---ThirdBlock---time:2021-04-0515:12:18.813488-0600MDTm=+0.000269168prevHash:fcce5323a35cb67b45fe75866582db00fd32baeb92aac448c7Hash:fc1d3eee286970d85812b47c3a5bf016ae8c1de4f86b8ace972ffaTransactions:0:"WillsentIzzy45bitcoin"1:"IzzysentWill10bitcoin"过程可能会很粗糙,但这是创建自己的区块链的基础!