在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一.创建项目 按照Go语言最佳实践的思路, 在工作空间下的src目录下创建 github.com/hangzhou-huxin/blokcchain目录作为我们的项目目录,然后用GoLand工具选中这个项目并打开:
二.项目源码 先在项目目录下添加block.go、blockchain.go这两个文件,分别封装了区块和区块链这两个类,当然在Go语言中是定义struct 1.blokc.go源码 package main import ( "strconv" "bytes" "crypto/sha256" "time" ) // Block keeps block headers type Block struct { Timestamp int64 Data []byte PrevBlockHash []byte Hash []byte } // SetHash calculates and sets block hash 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[:] //初始化切片,是数组hash的引用 } // NewBlock creates and returns Block func NewBlock(data string, prevBlockHash []byte) *Block { block := &Block{time.Now().Unix(), []byte(data), prevBlockHash, []byte{}} block.SetHash() return block } // NewGenesisBlock creates and returns genesis Block func NewGenesisBlock() *Block { return NewBlock("Genesis Block", []byte{}) } 代码说明: (1) time.Now().Unix() :返回从1970年1月1日开始的秒数。 (2) bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{}) :bytes.Join函数可以把多个字节数组连接成一个新的切片返回bytes.Join的第一参数以[][]byte二维字节数组的方式提供要连接的字节数组,第二个参数的作用是生成的新的字节数组时,在每个字节数组中间插入的间隔符,当然这个间隔符也是以字节数组的形式来提供。 (3) timestamp := []byte(strconv.FormatInt(b.Timestamp, 10)) : 字符串转字节数组 (4) b.Hash = hash[:] //初始化切片,是数组hash的引用 (5) NewGenesisBlock() 和 NewBlock 都是构造性质的函数,按惯例一般以NewXxxx这样来命名
2. blockchain.go package main // Blockchain keeps a sequence of Blocks type Blockchain struct { blocks []*Block } // AddBlock saves provided data as a block in the blockchain func (bc *Blockchain) AddBlock(data string) { prevBlock := bc.blocks[len(bc.blocks)-1] newBlock := NewBlock(data, prevBlock.Hash) bc.blocks = append(bc.blocks, newBlock) } // NewBlockchain creates a new Blockchain with genesis Block func NewBlockchain() *Blockchain { return &Blockchain{[]*Block{NewGenesisBlock()}} }
下面是main函数: package main import "fmt" 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() } }
三.项目编译 下面是当前在GoLand的工具下,项目的一个图: 此时要编译这个代码,必须在blockchain上点右键,如图: 而不能在main.go上点右键运行,因为main.go中会调用block.go 和 blockchain.go中的函数和struct ,直接在main.go进行编译,go build是看到block.go 和 blockchain.go的。 以上项目的代码是参照该文所写:https://github.com/liuchengxu/blockchain-tutorial |
请发表评论