使用 Go PT 构建区块链:I - 区块链的 Hello World
致谢/资源
致谢/资源
大家好!
我最近一直在学习围棋,考虑到最近 NFT 和加密货币的热潮,我决定与其学习 Solidity,不如继续学习围棋。不过,我还是想获得超级潮流的开发者的赞誉,因为他在区块链领域有所成就。我查阅了一些教程,在学习过程中遇到了一些问题,所以想和大家分享一下。
在整个过程中,我学习了两件事:Go 和区块链。如果说我在写作和分享知识的过程中学到了什么,那就是我们应该坚持一次解释一件事。鉴于这个新发现的智慧,我不会教你太多 Go 语法,因为我认为 Go 语法更容易理解。Go 确实有一些围绕通道和例程的复杂范例,但在本教程中我们不会用到它们。
我会教你一些关于 Golang 的知识。我们需要配置 Go 语言,以便在本地机器上进行编译。我使用的是 Windows 系统,所以你在这里看到的是 Windows 系统。说实话,据我所知,在 macOS/Linux 上应该也差不多。
Go 配置
您将需要安装这里
通常,如果你查看 Go 的教程以及如何配置它,你会听到很多关于 GOPATH 的内容。这很麻烦,后来我才发现其实不需要设置所有这些。Go 有一个模块系统,其工作原理类似于 npm 或 pip。
此时我们需要做的就是安装 go。
现在我们创建一个新的项目文件夹并添加一些代码。
mkdir learnBlockChain && cd learnBlockChain
太棒了!现在我们可以启动 Go 模块系统了。你可以随意命名,但我建议你按照我的格式,但用你的用户名代替。
go mod init github.com/nheingit/learnBlockChain
这应该会在您的项目文件夹中生成一个名为go.mod
//go.mod
1 module github.com/nheingit/learnBlockChain
您将能够使用任何第三方软件包,然后每当您使用运行命令时,它都会加载相关的软件包并将其导入到您的项目中。如果您尚未下载该软件包,它通常会在错误消息中显示相关命令。非常简洁。
现在我们已经配置好了 mod 系统,你无需导入任何代码即可继续操作。你可以直接调用该方法,就像它已经是你项目的一部分一样,剩下的事情它会处理好。
不过,如果不是这种情况,我会把这段代码放在这里作为备份。我们只导入 3 项内容,所以如果你在这部分遇到困难,可以直接复制这段代码继续。
进口
//main.go
1 package main
2
3 import (
4 "bytes"
5 "crypto/sha256"
6 "fmt"
7 )
//rest of code here
//..
//..
//..
让我们封锁吧!
既然配置之神已经满足了,我们现在可以开始真正的仪式了。只需跟着我做,记住,虽然我在这里给出了全部代码,但如果你把所有代码都写出来,你会学到更多。
你需要建立对 Go 语法的肌肉记忆,并真正思考你的代码在做什么。如果你对实际学习不感兴趣,你可以直接去 git 仓库复制粘贴代码,但这样做不会有太大的收获。
在你的终端我们可以运行touch main.go
//go.main
1 package main
2
3 func main() {
4
5 }
现在main.go
文件已经准备好了,我们需要从底层来推导区块链的概念。幸运的是,就像大多数复合词一样,我们可以将单词分解成各个部分,并从中推断出一些含义。
堵塞
让我们从区块开始。区块链中的区块需要由三个不同的字段组成。由于区块链的主要吸引力在于其安全性,因此我们需要进行一些哈希运算。除非区块中包含一些值得以某种方式保护或保存的数据,否则哈希运算不会特别有用,因此我们还需要一些数据。最后一个元素是区块如何链接在一起,因此我们还需要之前区块的哈希值。
如果我们把我刚才说的一切都翻译成 golang,我们应该得到类似这样的结果
// main.go
type Block struct {
Hash []byte
Data []byte
PrevHash []byte
}
恭喜你,你现在拥有了积木®。好吧,单单一个积木现在用处不大,不是吗?我们给这玩意儿装个链条,让它动起来吧!
链
区块链的链部分就是所有区块的集合。我觉得这听起来像是数组的一个很好的用例。
// main.go
type BlockChain struct{
blocks []*Block
}
太棒了!现在你就是古老区块链的骄傲主人了。
但现在有个问题,我们真的没法用这个做任何事情。它需要一些功能。我猜一个函数可以帮我们解决这个问题。
功能
// All of these functions will be in main.go
我认为一个有用的起点是对我们赋予区块的数据进行哈希处理。我们将对区块中的当前数据以及之前的区块进行哈希处理,以创建依赖链。对前一个区块的哈希处理对于区块链的可靠性至关重要。如果没有这串连接,我们将无法以编程方式验证系统的完整性。
func (b *Block) DeriveHash() {
info := bytes.Join([][]byte{b.Data, b.PrevHash}, []byte{})
// This will join our previous block's relevant info with the new blocks
hash := sha256.Sum256(info)
//This performs the actual hashing algorithm
b.Hash = hash[:]
//If this ^ doesn't make sense, you can look up slice defaults
}
既然我们能够按照自己喜欢的方式对数据进行哈希处理,我认为下一步就是实际使用这种哈希功能。创建一个新的区块听起来是展示我们哈希技能的好地方。
func CreateBlock(data string, prevHash []byte) *Block {
block := &Block{[]byte{}, []byte(data), prevHash}
//If this is gibberish to you look up
// pointer syntax in go
block.DeriveHash()
return block
}
干得好!现在我们可以创建所有区块了。
不过,在这种情况下,创建太多区块并不会有什么意义。我们需要一个区块链来把所有东西连接起来。
func (chain *BlockChain) AddBlock(data string) {
prevBlock := chain.blocks[len(chain.blocks)-1]
new := CreateBlock(data, prevBlock.Hash)
chain.blocks = append(chain.blocks, new)
}
有了链上操作的能力AddBlock
,我们就可以开始总结了。但有一个问题:我们无法创建链上的第一个区块。这是因为我们所有的函数都依赖于PrevHash
之前的区块。所以我们需要为链创建原始区块。
func Genesis() *Block {
return CreateBlock("Genesis", []byte{})
}
在我们尽情地进行 Blockin' n' Chainin' 之前,我们需要做的最后一件事是使用Genesis
我们创建的新区块来初始化一个新的区块链。
func InitBlockChain() *BlockChain {
return &BlockChain{[]*Block{Genesis()}}
}
现在我们已经拥有了创建区块链所需的所有功能!这意味着我们可以开始编写主函数了。按照“hello world”区块链教程的思路,我想打印出我的所有字段,Blocks
然后BlockChain
就结束了。
func main() {
chain := InitBlockChain()
chain.AddBlock("first block after genesis")
chain.AddBlock("second block after genesis")
chain.AddBlock("third block after genesis")
for _, block := range chain.blocks {
fmt.Printf("Previous hash: %x\n", block.PrevHash)
fmt.Printf("data: %s\n", block.Data)
fmt.Printf("hash: %x\n", block.Hash)
}
}
我们现在把它放到终端里go run main.go
这应该会给你带来类似这样的输出:
Previous hash:
data: Genesis
hash: 81ddc8d248b2dccdd3fdd5e84f0cad62b08f2d10b57f9a831c13451e5c5c80a5
Previous hash:
data: first block after genesis
hash: ce6cc03696fed9f5d0f45d0b26fd4f654df50201281be273248e2184e507586e
Previous hash:
data: second block after genesis
hash: 7e964d1d2887bb2def988d7dfc85d935836d686ce7d101cbcb61716229d74386
Previous hash:
data: third block after genesis
hash: f5fc87251c9c8d0be886c0d180b42beb9662de3224c2d87df4ee75427655dc45
您应该注意到,第一个 Genesis 块没有 Previous hash,这就是我们需要该特殊功能的原因。
希望你喜欢阅读,没有发现任何太简单或太难的内容!最后,我会展示一些我用来制作这个应用程序的资源!
致谢/资源
您最终应该得到的代码。
如果你想看我教你如何做区块链的视频,就在这里。你将从这位优秀的先生那里以视频的形式学习如何编写这个项目的代码。
这是 repo:https://github.com/tensor-programming/golang-blockchain
如果你真的想尝试用 Solidity 开发加密货币和以太坊,另一个很棒的学习资源是DappUniversity
致谢/资源
如果你想看我教你如何做区块链的视频,就在这里。你将从这位优秀的先生那里以视频的形式学习如何编写这个项目的代码。
这是 repo:https://github.com/tensor-programming/golang-blockchain
如果你真的想尝试用 Solidity 开发加密货币和以太坊,另一个很棒的学习资源是DappUniversity
文章来源:https://dev.to/nheindev/build-the-hello-world-of-blockchain-in-go-bli