分享
  1. 首页
  2. 文章

2020 区块链 golang 版本(8)

zidea · · 1340 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

封面

查询余额(UTXO)

上面代码实现 Alice 通过挖矿得到她的第一笔交易 12.5 比特币奖励,现在我们需要实现可以查询 Alice 余额(UTXO)的方法。


我们可以通过追踪 John 交易来计算其 UTXO,如图

  • 蓝色表示交易输入
  • 黄色和绿色表示交易输出,其中绿色表示没有被话费的输出
    那么我们在统计某一个用户UTXO 不仅要看和他相关输出,还要看和他相关输入,以便确认某一笔输出是否被使用,如果被使用我们就可以跳过该输入对应输出,这里大家可能对输入和输出还不算理解,这里输入和输出可以理解对象,输入就是用户花费的,而输出用户得到比特币。这个方法我们写到区块链(BlockChain)下命名为 FindUTXOs。我先把代码抛出来
func (bc *BlockChain) FindUTXOs(address string) []TXOutput {
 //定义 UTXO 然后将每一笔UTXO都写入这个数组
 var UTXO []TXOutput
 //定义 map 来保存消费过的output key ouput 所在交易id value 这个交易索引的数组
 // map[交易id][]int64
 spentOutputsMap := make(map[string][]int64)
 //获取 blockchain 的迭代器
 it := bc.NewIterator()
 for {
 //1. 遍历区块
 block := it.Next()
 //2 遍历交易
 for _, tx := range block.Transactions {
 //输出当前交易 TXID
 fmt.Printf("current txid: %x\n", tx.TXID)
 //3 遍历 output 找到和用户相关的 UTXO (在添加 output 到数组 UTXO 之前,需要检查一下是否已经使用过该 output)
 OUTPUT:
 for i, output := range tx.TXOutputs {
 fmt.Printf("current index: %d\n", i)
 //在这里做一个过滤,将所有消耗过的 outputs 和当前的所即将添加 output 对比一下
 //如果当前这个 output 相同跳过,否则添加
 //如果当前的交易 id 存在我们已经标识的 map 说明这个交易中有消耗过的
 if spentOutputsMap[string(tx.TXID)] != nil {
 for _, j := range spentOutputsMap[string(tx.TXID)] {
 if int64(i) == j {
 //当前准备添加output已经消耗过
 continue OUTPUT
 }
 }
 }
 //判断地址是否想要查询用户,通过 address ,如果 output 的 PubKeyHash 和 address 相同,则添加到返回集合 UTXO 数组中
 if output.PubKeyHash == address {
 UTXO = append(UTXO, output)
 }
 }
 // 如果当前交易是挖矿交易 那么不做遍历直接跳过
 if !tx.IsCoinbase() {
 //4 遍历 input 找到目标用户话费过的 UTXO 集合(把自己话费过的标识出来)
 //还需要遍历每一个区块 input 看其有没有和目标用户的相关交易记录
 for _, input := range tx.TXInputs {
 //判断当前一下当前input和目标用户是否一致,如果相同,就添加添加的哦消耗的output
 if input.Sig == address {
 indexArray := spentOutputsMap[string(input.TXid)]
 indexArray = append(indexArray, input.Index)
 }
 }
 } else {
 fmt.Printf("this is coinbase jumpout iteration\n")
 }
 }
 //完成对区块链的遍历
 if len(block.PrevHash) == 0 {
 fmt.Printf("block iteratoration finished ")
 break
 }
 }
 return UTXO
}

先整理一下思路,我们分别遍历区块、遍历交易然后遍历ouput和input

  • 遍历 ouput, 找到和用户相关 utxo,在添加ouput之前检查是否已经使用过
  • 遍历 input, 找到用户花费过的 utxo 的集合,标识用户使用过的ouput

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:zidea

查看原文:2020 区块链 golang 版本(8)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1340 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏