从0到1简易区块链开发手册V0.6-实现打印区块

八. 打印区块

以上的转账交易中,我们共计创建了四个区块,其中一个区块为创世区块,另外三个区块都是对我们的交易进行打包后产生的新区块,本文将介绍如何将区块信息打印出来。

1.命令行代码

func (cli *CLI) PrintChains() {
    //cli.BlockChain.PrintChains()
    bc := GetBlockChainObject() //bc{Tip,DB}
    if bc == nil {
        fmt.Println("没有BlockChain,无法打印任何数据。。")
        os.Exit(1)
    }
    defer bc.DB.Close()
    bc.PrintChains()
}
  • 获取区块链对象
  • 调用PrintChains方法

2.创建迭代器

在上文中,我们将所有生成的区块均存储至BoltDB中,我们需要通过操作数据对区块进行获取,此处,我们创建一个迭代器用于对数据库进行遍历查询。

2.1 迭代器结构体

type BlockChainIterator struct {
    DB          *bolt.DB
    CurrentHash []byte
}

迭代器属性有两个,DB对象以及当前Hash

func (bc *BlockChain) Iterator() *BlockChainIterator {
    return &BlockChainIterator{bc.DB, bc.Tip}
}

通过Iterator方法获取一个BlockChainIterator的对象

2.2 结构体方法

func (bcIterator *BlockChainIterator) Next() *Block {
    block := new(Block)
    err := bcIterator.DB.View(func(tx *bolt.Tx) error {
        b := tx.Bucket([]byte(BlockBucketName))
        if b != nil {
            //根据current获取对应的区块的数据
            blockBytes := b.Get(bcIterator.CurrentHash)
            //反序列化后得到block对象
            block = DeserializeBlock(blockBytes)
            //更新currenthash
            bcIterator.CurrentHash = block.PrevBlockHash
        }
        return nil

    })
    if err != nil {
        log.Panic(err)
    }
    return block
}

我们定义一个结构体方法Next用于对区块链进行遍历操作

  • 根据bcIterator,操作DB对象,读取数据库
  • 打开存储区块的Bucket表名
  • 根据current获取对应的区块的数据
  • 对获取到的数据进行反序列化得到block对象
  • 更新bcIterator的CurrentHash属性为上一个区块,方便进行对上一个区块(因为对区块链的遍历是从后往前知直至创世区块的)的获取操作.

3.创建打印区块函数

func (bc *BlockChain) PrintChains() {
    /*
    .bc.DB.View(),
        根据hash,获取block的数据
        反序列化
        打印输出
     */

    //获取迭代器
    it := bc.Iterator()
    for {
        //step1:根据currenthash获取对应的区块
        block := it.Next()
        fmt.Printf("第%d个区块的信息:\n", block.Height+1)
        fmt.Printf("\t高度:%d\n", block.Height)
        fmt.Printf("\t上一个区块Hash:%x\n", block.PrevBlockHash)
        fmt.Printf("\t自己的Hash:%x\n", block.Hash)
        //fmt.Printf("\t数据:%s\n", block.Data)
        fmt.Println("\t交易信息:")
        for _, tx := range block.Txs {
            fmt.Printf("\t\t交易ID:%x\n", tx.TxID) //[]byte
            fmt.Println("\t\tVins:")
            for _, in := range tx.Vins { //每一个TxInput:Txid,vout,解锁脚本
                fmt.Printf("\t\t\tTxID:%x\n", in.TxID)
                fmt.Printf("\t\t\tVout:%d\n", in.Vout)
                fmt.Printf("\t\t\tsign:%v\n", in.Signature)
                fmt.Printf("\t\t\tPublicKey:%v\n", in.PublicKey)
            }
            fmt.Println("\t\tVouts:")
            for _, out := range tx.Vouts { //每个以txOutput:value,锁定脚本
                fmt.Printf("\t\t\tValue:%d\n", out.Value)
                fmt.Printf("\t\t\tPubKeyHash:%v\n", out.PubKeyHash)
            }
        }

        fmt.Printf("\t随机数:%d\n", block.Nonce)
        //fmt.Printf("\t时间:%d\n", block.TimeStamp)
        fmt.Printf("\t时间:%s\n", time.Unix(block.TimeStamp, 0).Format("2006-01-02 15:04:05")) // 时间戳-->time-->Format("")

        //step2:判断block的prevBlcokhash为0,表示该block是创世取块,将结束循环
        hashInt := new(big.Int)
        hashInt.SetBytes(block.PrevBlockHash)
        if big.NewInt(0).Cmp(hashInt) == 0 {
            /*
            x.Cmp(y)
                -1 x < y
                0 x = y
                1 x > y
             */
            break
        }

    }
}
  • 获取迭代器对象
  • 通过for循环对迭代器对象的Next方法获取到的区块进行遍历
    • 高度
    • 上一个区块的哈希
    • 区块自己的哈希
    • 交易数组Txs
    • 随机数
    • 时间戳
  • 对交易数组Txs进行遍历
    • 获取交易输入数组
    • 获取交易输出数组
  • 对交易输入数组进行遍历
  • 对交易输出数组进行遍历
  • 判断区块的上一个区块哈希是否为0 (bigInt的Cmp方法进行对比),结束循环

4.代码测试

4.1 命令行测试

$ ./mybtc printchain

返回结果

第4个区块的信息:
        高度:3
        上一个区块Hash:0000c728b52f7a988060ef97252582bb55a076fbd3724bf6c54ca3d28e8a48c1
        自己的Hash:000029e6e3277d493ad0e70f4e9b0bb4fff718ccddcb4613fcc89fa3c2ab89a1
        交易信息:
                交易ID:635c6c2f6953c5216ac3848e2bf4ca29cb366da4b7f9f6d7465fb0437a25ae7b
                Vins:
                        TxID:268d659bc26b71f9c2c55e8105d63d7e3530d10bcce3078616083473c9815015
                        Vout:0
                        sign:[85 157 86 124 207 101 13 172 227 166 145 49 177 229 142 158 89 23 182 80 124 19 202 98 221 132 94 20 127 92 28 116 37 101 222 98 194 235 49 225 137 224 178 22 139 224 44 233 252 8 79 180 86 76 134 224 98 41 31 24 68 3 222 226]
                        PublicKey:[66 142 153 19 22 156 166 189 181 22 189 55 146 33 114 142 83 182 186 21 123 4 65 4 37 102 107 204 42 175 161 23 22 72 233 146 175 105 179 65 173 128 40 5 150 252 196 116 246 22 109 178 26 63 146 87 203 4 196 201 99 61 94 206]
                        TxID:5228a9c85bb44b2b5f33517c73322901cae2e27544e90a4e0f6f6da92377ff3a
                        Vout:1
                        sign:[122 108 188 57 39 164 121 50 33 92 96 116 217 251 120 187 221 148 177 33 157 155 195 116 75 109 197 49 151 154 135 175 253 64 60 168 22 117 164 150 31 53 156 6 150 162 212 55 138 98 209 86 11 119 149 190 54 82 5 212 29 220 57 194]
                        PublicKey:[66 142 153 19 22 156 166 189 181 22 189 55 146 33 114 142 83 182 186 21 123 4 65 4 37 102 107 204 42 175 161 23 22 72 233 146 175 105 179 65 173 128 40 5 150 252 196 116 246 22 109 178 26 63 146 87 203 4 196 201 99 61 94 206]
                        TxID:815c7c3969c256a053e99d44f8e1353ff7eaa99748efa7c94b2f066d9415a847
                        Vout:1
                        sign:[111 172 102 14 142 119 85 153 6 77 239 71 107 217 109 204 96 167 61 202 77 178 149 83 9 221 80 201 198 54 195 166 75 246 106 131 250 89 69 28 0 174 236 129 123 249 146 38 190 211 59 107 202 75 134 5 0 131 111 99 183 138 131 214]
                        PublicKey:[66 142 153 19 22 156 166 189 181 22 189 55 146 33 114 142 83 182 186 21 123 4 65 4 37 102 107 204 42 175 161 23 22 72 233 146 175 105 179 65 173 128 40 5 150 252 196 116 246 22 109 178 26 63 146 87 203 4 196 201 99 61 94 206]
                Vouts:
                        Value:23
                        PubKeyHash:[185 54 48 129 7 167 52 127 211 86 64 241 25 244 56 134 188 202 162 55]
                        Value:2
                        PubKeyHash:[134 186 213 244 81 129 0 161 13 161 102 238 69 121 251 18 154 152 44 233]
                交易ID:af5b0f1b76c3ec72cfd86c0c3d356c0d8fc6799955bd1e97597b693e0df2ff0b
                Vins:
                        TxID:
                        Vout:-1
                        sign:[]
                        PublicKey:[]
                Vouts:
                        Value:10
                        PubKeyHash:[134 186 213 244 81 129 0 161 13 161 102 238 69 121 251 18 154 152 44 233]
        随机数:30579
        时间:2018-08-22 16:13:26
第3个区块的信息:
        高度:2
        上一个区块Hash:000002abf5db3196927ebd2160fa3903010d38e5eefc9f61fe18d3860e115986
        自己的Hash:0000c728b52f7a988060ef97252582bb55a076fbd3724bf6c54ca3d28e8a48c1
        交易信息:
                交易ID:5228a9c85bb44b2b5f33517c73322901cae2e27544e90a4e0f6f6da92377ff3a
                Vins:
                        TxID:4578ddd18b4cc57c2e6ef91679232bdf75f85d1100a41f49ab546293657642e9
                        Vout:0
                        sign:[145 176 153 168 48 184 239 181 110 195 176 77 86 239 96 184 93 217 185 191 192 48 131 0 187 237 129 59 181 145 133 150 88 61 109 59 186 248 11 30 138 238 124 232 62 96 147 208 180 211 120 35 114 6 79 2 221 100 214 215 121 39 41 197]
                        PublicKey:[66 142 153 19 22 156 166 189 181 22 189 55 146 33 114 142 83 182 186 21 123 4 65 4 37 102 107 204 42 175 161 23 22 72 233 146 175 105 179 65 173 128 40 5 150 252 196 116 246 22 109 178 26 63 146 87 203 4 196 201 99 61 94 206]
                Vouts:
                        Value:3
                        PubKeyHash:[185 54 48 129 7 167 52 127 211 86 64 241 25 244 56 134 188 202 162 55]
                        Value:7
                        PubKeyHash:[134 186 213 244 81 129 0 161 13 161 102 238 69 121 251 18 154 152 44 233]
                交易ID:268d659bc26b71f9c2c55e8105d63d7e3530d10bcce3078616083473c9815015
                Vins:
                        TxID:
                        Vout:-1
                        sign:[]
                        PublicKey:[]
                Vouts:
                        Value:10
                        PubKeyHash:[134 186 213 244 81 129 0 161 13 161 102 238 69 121 251 18 154 152 44 233]
        随机数:60270
        时间:2018-08-22 16:03:10
第2个区块的信息:
        高度:1
        上一个区块Hash:00005c7b4246aa88bd1f9664c665d6424d1522f569d981691ac2b5b5d15dd8d9
        自己的Hash:000002abf5db3196927ebd2160fa3903010d38e5eefc9f61fe18d3860e115986
        交易信息:
                交易ID:815c7c3969c256a053e99d44f8e1353ff7eaa99748efa7c94b2f066d9415a847
                Vins:
                        TxID:31cb0a3fcf70ccf7cd2d5ec5564d266b022acd4aca28f0eee8b465a21863315f
                        Vout:0
                        sign:[76 117 6 102 34 72 16 65 232 180 248 176 20 134 206 63 75 128 51 217 41 238 50 173 165 178 36 54 57 92 11 4 134 121 96 210 16 18 129 160 109 183 213 110 195 54 101 48 198 89 12 76 174 216 80 198 232 32 77 253 55 157 87 229]
                        PublicKey:[66 142 153 19 22 156 166 189 181 22 189 55 146 33 114 142 83 182 186 21 123 4 65 4 37 102 107 204 42 175 161 23 22 72 233 146 175 105 179 65 173 128 40 5 150 252 196 116 246 22 109 178 26 63 146 87 203 4 196 201 99 61 94 206]
                Vouts:
                        Value:2
                        PubKeyHash:[185 54 48 129 7 167 52 127 211 86 64 241 25 244 56 134 188 202 162 55]
                        Value:8
                        PubKeyHash:[134 186 213 244 81 129 0 161 13 161 102 238 69 121 251 18 154 152 44 233]
                交易ID:4578ddd18b4cc57c2e6ef91679232bdf75f85d1100a41f49ab546293657642e9
                Vins:
                        TxID:
                        Vout:-1
                        sign:[]
                        PublicKey:[]
                Vouts:
                        Value:10
                        PubKeyHash:[134 186 213 244 81 129 0 161 13 161 102 238 69 121 251 18 154 152 44 233]
        随机数:25508
        时间:2018-08-22 15:45:06
第1个区块的信息:
        高度:0
        上一个区块Hash:0000000000000000000000000000000000000000000000000000000000000000
        自己的Hash:00005c7b4246aa88bd1f9664c665d6424d1522f569d981691ac2b5b5d15dd8d9
        交易信息:
                交易ID:31cb0a3fcf70ccf7cd2d5ec5564d266b022acd4aca28f0eee8b465a21863315f
                Vins:
                        TxID:
                        Vout:-1
                        sign:[]
                        PublicKey:[]
                Vouts:
                        Value:10
                        PubKeyHash:[134 186 213 244 81 129 0 161 13 161 102 238 69 121 251 18 154 152 44 233]
        随机数:32325
        时间:2018-08-20 22:11:28

4.2 区块关联图

上图整合了区块的相关属性以及关联信息,希望能帮助大家,功能实现模块暂时告一段落,后期我不定期更新一些比特币原理中其他比较重要的知识点跟大家一起学习,谢谢大家。

原文地址:http://blog.51cto.com/clovemfong/2163211

时间: 2024-08-21 03:40:28

从0到1简易区块链开发手册V0.6-实现打印区块的相关文章

从0到1简易区块链开发手册V0.3-数据持久化与创世区块

1.BoltDB简介 Bolt是一个纯粹Key/Value模型的程序.该项目的目标是为不需要完整数据库服务器(如Postgres或MySQL)的项目提供一个简单,快速,可靠的数据库. BoltDB只需要将其链接到你的应用程序代码中即可使用BoltDB提供的API来高效的存取数据.而且BoltDB支持完全可序列化的ACID事务,让应用程序可以更简单的处理复杂操作. 其源码地址为:https://github.com/boltdb/bolt 2.BoltDB特性 BoltDB设计源于LMDB,具有以

从0到1简易区块链开发手册V0.2-创建钱包

1.概念 创建钱包其实就是创建比特币地址,在比特币世界中,没有账户概念,不需要也不会在任何地方存储个人数据(比如姓名,×××件号码等).但是,我们总要有某种途径识别出你是交易输出的所有者(也就是说,你拥有在这些输出上锁定的币),这就是比特币地址(address)需要完成的使命. 关于钱包这个概念,我个人觉得imtoken在用户引导那部分写得很清楚,此处将链接给到大家,有兴趣的可以去看看 https://www.cnblogs.com/fangbei/p/imToken-clearance.htm

从0到1简易区块链开发手册V0.4-实现转账交易的思路分析

六.转账交易 创世区块创建完毕之后,按照我们的正常思路,是继续创建新的区块,并加入至区块链中,没错,这确实是学习路线,但是我们首先来了解一个区块是如何生成的,转账交易 ===>打包交易 ===>工作量证明 ===>生成区块 在上文,我们提到了钱包地址这个概念,我们一般可以简单将钱包地址理解为一个银行账户,那么交易也就可以理解为是地址与地址之间的转账过程. 因为这部分内容非常重要,设置可以说交易就是比特币原理的核心,所以,为了保证大家对概念有充分的了解,本章节的理论描述部分此处摘录liuc

从0到1简易区块链开发手册V0.5-实现余额查询

七. 查询余额 其实这个章节的一些知识点在转账交易那一章节均有所涉及,所以,查询余额这个功能相对而言比较简单,只要熟悉了UTXO模型,加上对交易流程的了解之后,对查询余额基本上已经有了思路. 1.命令行代码 func (cli *CLI) GetBalance(address string) { bc := GetBlockChainObject() if bc == nil { fmt.Println("没有BlockChain,无法查询..") os.Exit(1) } defer

区块链开发公司如何应用?聊区块链+积分联盟

区块链技术开发至今已有十年,从概念的现世到如今初步应用,区块链开发公司在各个领域开始发光发热,很多人都想参与其中,通过区块链开发实现企业转型来适应未来市场,也有一些初创者希望借此实现创业意图,但在诸多的区块链开发中,先达区块链基于FBA模式下开发的"区块链+积分联盟"就是一个应用实体的过程!为区块链开发解决实际社会问题做出了积极贡献! 面对传统的积分联盟不足之处,"区块链+积分联盟"打破不同种类积分系统之间的壁垒!而构建去中心化积分资产的发行.流通.管理和交易体系就

区块链开发公司人才紧缺 企业区块链开发如何加入?

查看一些招聘网站,搜索"区块链开发"的相关招聘职位多达二十多页,岗位接近390个,热门岗位有区块链开发工程师.区块链研究员.区块链专家.区块链负责人等,月薪最高可达10万元.这和两年前形成鲜明对比. 而企业招聘一年支付的基础套餐在1.6万元左右,可以进行岗位的发布基本操作,如果要增加曝光量,覆盖更多的人群,在首页banner位展示一周收费大概4.8万元.参加大型招聘专题活动收费会更高,接近18万元.即便这样,企业也不容易招到合适的人才.他们也没办法,因为区块链这块儿人才很稀缺,几乎没有

区块链开发公司 论区块链实现开发的价值

历史上每一次生产关系的革命,都大大促进了生产力和整个时代的发展.就如商业风口的区块链开发,有人说区块链开发公司"没有创造新的价值""只是财富的转移",没错,进一步而言,区块链开发并不能像人工智能一样直接提升生产力,但是这并不代表它没有价值. --大航海时代的荷兰,创造性地发明了"股份制"公司的思路,让民间资本可以参与到航海探险中,一改只有王室参与的旧习,让荷兰一跃成为"海上马车夫": --工业革命前夕的英国,通过用篱笆划分草场

区块链开发中使用的最流行的编程语言

我们目前正处于一个新兴的区块链开发行业中.区块链技术处于初期阶段,然而这种颠覆性技术已经成功地风靡全球,并且最近经历了一场与众不同的繁荣.由于许多资金充足的项目现在急于建立区块链网络并在其上部署分散的应用程序,因此缺乏能力强大的区块链开发人员.随着数十亿人进入这一领域,区块链开发商的薪酬和需求不断升级,项目互相竞标,以吸引留在市场上的最佳区块链人才.这种淘金热可能让一些开发人员怀疑他们是否具备了进入这个行业所需要的东西,特别是在这个新行业中最受追捧的编程语言.几乎所有流行的编程语言都在区块链行业

区块链开发公司的落地应用难在哪里

随着区块链开发技术的风口在打开,现在市场上区块链开发公司数量在不断增加,希望能够在区块链开发领域上有所创新,抢占时代热点.但是还是有一部分区块链开发公司打退堂鼓,市场上区块链开发人才难求,更别说那些懂技术又懂应用落地的复合型人才,这导致很多区块链开发公司面临区块链应用落地难,那么今天我们就简单分析一下其中的原因吧. 第一:关乎技术 目前区块链开发技术还是处于不成熟的状态,虽然已经是在一些领域上有所应用,但是其实还是存在一定问题,区块链最佳的落地应用场景是金融领域,那么区块链存在固有的规模限制,能