邀请好友 注册并登录 ,获取价值高达 60000 元的数字货币盲盒,100%中奖!
门户网站:安区块链代码是什么语言百里工程学院
3.添加数据库和客户端
区块链是我们区之前创建的,但是程序终止后,数据丢失了!为了在下次引导后继续,我们需要引入一个小数据库。这一次,我们选择了-bolt,与短跑世界纪录保持者同名的数据库。
这里不详细描述bolt的内容。可以参考文章:Bolt,一个和sprinters同名的数据库。
定义数据库文件和存储桶
const dbFile = " block chain . db "
const blocks bucket = " blocks "
重新定义
//区块链保持区块序列
类型区块链struct {
tip[]byte
db * bolt。DB
}
的已定义迭代器
// BlockchainIterator用于迭代区块链块
类型block chain iterator struct {
current hash[]byte
db * bolt。DB
}
使用boltdb处理创建块
func NewBlockchain() *Blockchain {
var tip []byte
db, err := bolt.Open(dbFile, 0600, nil)
if err != nil {
log.Panic(err)
}
err = db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(blocksBucket))
if b == nil {
fmt.Println("No existing blockchain found. Creating a new one...")
genesis := NewGenesisBlock()
func new block chain()* block chain {
var tip[]byte
db,err := bolt。Open(dbFile,0600,nil)
if err!= nil {
log。Panic(err)
}
err = db。更新(func(tx *bolt。Tx)错误{
b := tx。bucket([]byte(blocks bucket))
if b = = nil {
fmt。Println("未找到现有的区块链。正在创建新的...")
genesis:= new genesis block()
b, err := tx.CreateBucket([]byte(blocksBucket))
if err != nil {
log.Panic(err)
}
err = b.Put(genesis.Hash, genesis.Serialize())
if err != nil {
log.Panic(err)
}
err = b.Put([]byte("l"), genesis.Hash)
if err != nil {
log.Panic(err)
}
tip = genesis.Hash
} else {
tip = b.Get([]byte("l"))
}
return nil
})
if err != nil {
log.Panic(err)
}
bc := Blockchain{tip, db}
return amp;bc
}
上面的代码将创建块的数据写入数据库用键入的区块链码是什么,并返回创建块。请注意,生成此块仍然需要POW工作的证明。
接下来,让我们编写一个客户端并创建一个cli.go文件。
Cli必须记录区块链的数据。
type CLI struct {
BC * block chain
}
提供命令行启动帮助。
func(CLI * CLI)print usage(){
fmt。Println("用法:")
fmt。println(" add BLOCK-DATA BLOCK _ DATA-向区块链添加块")
fmt。Println(" printchain -打印区块链的所有区块")
}
检查参数是否正确。
func(CLI * CLI)validate args(){
if len(OS。args) lt;2 {
cli.printUsage()
os。exit(1)
}
}
@ gt;
在需要添加函数之前,需要取出前一个块的hash。
// AddBlock saves provided data as a block in the blockchain
func (bc *Blockchain) AddBlock(data string) {
var lastHash []byte
err := bc.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(blocksBucket))
lastHash = b.Get([]byte("l"))
return nil
})
if err != nil {
log.Panic(err)
}
newBlock := NewBlock(data, lastHash)
err = bc.db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(blocksBucket))
err := b.Put(newBlock.Hash, newBlock.Serialize())
// AddBlock将提供的数据保存为区块链
func(BC * block chain)add block(数据字符串){
var last hash[]byte
err:= BC . db . view(func(tx * bolt。Tx)错误{
b := tx。bucket([]byte(blocks bucket))
last hash = b . Get([]byte(" l "))
return nil
})
if err!= nil {
log。panic(err)
}
new block:= new block(data,last hash)
err = BC . db . update(func(tx * bolt。Tx)错误{
b := tx。bucket([]byte(blocks bucket))
err:= b . Put(new block。哈希,新块。Serialize())
if err != nil {
log.Panic(err)
}
err = b.Put([]byte("l"), newBlock.Hash)
if err != nil {
log.Panic(err)
}
bc.tip = newBlock.Hash
return nil
})
}
打印区块链信息
p gt
func(CLI * CLI)print chain(){
BCI:= CLI . BC . iterator()
for {
block:= BCI。Next()
fmt。Printf("Prev。哈希:%xn”,块。PrevBlockHash)
fmt。Printf("Data: %sn ",block。Data)
fmt。Printf("Hash: %xn ",块。hash)
pow:= newprooffwork(block)
fmt。Printf("PoW: %sn ",strconv。FormatBool(pow。Validate()))
fmt。Println()
if len(block。prev block hash)= = 0 {
break
}
}
}
上面的代码需要区块链迭代器来支持下一个函数遍历。
// Next returns next block starting from the tip
// Next返回从提示开始的下一个块
func (i *BlockchainIterator) Next() *Block {
var block *Block
err := i.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte(blocksBucket))
encodedBlock := b.Get(i.currentHash)
block = DeserializeBlock(encodedBlock)
return nil
})
if err != nil {
log.Panic(err)
}
i.currentHash = block.PrevBlockHash
return block
}
是读取和解码区块链的数据。
// DeserializeBlock反序列化一个Block
func deserialize Block(d[]byte)* Block {
var Block Block
decoder:= gob。NewDecoder(字节。NewReader(d))
err := decoder。解码( ampblock)
if err!= nil {
log。panic(err)
}
return amp;block
}
下一个核心部分是在cli中添加run函数。
// Run解析命令行参数并处理命令
func(CLI * CLI)Run(){
CLI . validate args()
addBlockCmd:= flag。NewFlagSet("addblock ",标志。exit error)
print chain cmd:= flag。NewFlagSet("printchain ",标志。exit on error)
addBlockData:= addBlockCmd。String("data "," Block data")
switch os。args[1]{
case " add block ":
err:= addblock cmd。解析(操作系统。Args[2:])
if err!= nil {
log。panic(err)
}
case " print chain ":
err:= print chain cmd。解析(操作系统。Args[2:])
if err!= nil {
log。Panic(err)
}
默认值:
cli.printUsage()
os。exit(1)
}
if addblock cmd。parsed(){
if * addBlockData = = " " {
addBlockCmd。用法()
os。exit(1)
}
CLI . add block(* add block data)
}
if print chain cmd。parsed(){
CLI . print chain()
}
}
根据不同的命令行,输入用键入什么区块链码,执行不同的功能。
Ethos是一个简单易用的矿业系统,为矿业提供教程软件和矿机评估及交易信息,以数字货币比较计算各种矿业利润,介绍矿业工具,矿业网站最新消息。http://www.ethospool.com/
本站所有软件信息均由用户上传发布,版权归原著所有。如有侵权/违规内容,敬请来信告知邮箱:86-77-55-65@qq.com,我们将及时撤销! 转载请注明出处::https://qkl.gxams168.com/bk/24286.html