Blockchainr源码剖析

前言

2014HITB-Exploiting ECDSA Failures in the Bitcoin Blockchain中他所使用提取签名的方法是通过Bloomfilter实现的,作者提到:

  • first pass:把签名添加到Bloomfilter里面,作者所使用的是:dablooms,如果过滤器中已经存在了该签名,则把该签名放到一个map中叫做:potentialValues
  • second pass:重新遍历signature,如果签名存在于potentialValues中,导出签名以及它的其他信息到map:rMap中

下面具体展开对源码的剖析

blockchainr

代码整体架构

  • main函数
  • btcdbSetup函数
  • getSignatures函数
  • search函数
getSignature

此函数的目的是导出区块中所有的Signature,作者定义了一个结构体,用于存放与签名相关的信息

type rData struct {
	sig  *btcec.Signature
	H    int64
	Tx   int
	TxIn int
	Data int
}
  • sig:签名(包含r、s)
  • H:交易所在区块的高度
  • Tx:区块中的第几笔交易
  • TxIn:交易中第几个TxIn
  • Data:

该函数的返回值是这个类型:

func getSignatures(maxHeigth int64, log btclog.Logger, db btcdb.Db) chan *rData {}

具体过程就不说了,它主要就是通过一层层的循环将数据导出的(思想如下):

for block in chain:
	for tx in block:
		for input in tx:
		...
search函数

使用dablooms这个Bloom过滤器,设置了容量、错误率等,都定义了常量

const (
	tickFreq  = 10
	bloomSize = 100000000
	bloomRate = 0.005
)

这里作者设置的容量是100000000,我觉得在2014年这个数据容量应该足够了

filter := dablooms.NewScalingBloom(bloomSize, bloomRate, "blockchainr_bloom.bin")

主要的提取过程前面提到了分为两步代码如下:

if step == 1 {
				b := rd.sig.R.Bytes()
				if filter.Check(b) {
					matches++
					potentialValues.Add(rd.sig.R.String())
				} else {
					if !filter.Add(b, 1) {
						log.Warn("Add failed (?)")
					}
				}
			} else if step == 2 {
				if potentialValues.Contains(rd.sig.R.String()) {
					matches++
					rMap[rd.sig.R.String()] = append(rMap[rd.sig.R.String()], rd)
				}

Signatures是调用getSignatures获得的,前文有提到过

signatures := getSignatures(maxHeigth, log, db)//获取签名
  • 第一步,通过循环导出的signatures将签名R赋值给b然后通过过滤器过滤,判断签名是否在过滤器中出现过,如果出现过那么就把它添加到potentialValues中
  • 第二步,再一次循环signatures判断R是否存在于第一步生成的集合potentialValues中,如果存在将其详细信息添加到rMap中,说一下rMap的类型:
rMap := make(map[string][]*rData)

key是string类型,value是rData类型,所以它的索引中存储的是签名R,value存储的是该签名R的其它信息。最后search函数返回rMap

main函数

首先给出了区块数据的路径以及数据库类型:

var (
		dataDir = flag.String("datadir", filepath.Join(btcutil.AppDataDir("btcd", false), "data"), "BTCD: Data directory")
		dbType  = flag.String("dbtype", "leveldb", "BTCD: Database backend")
	)

之后通过btcdbSetup函数设置了btcdb:

log, db, dbCleanup := btcdbSetup(*dataDir, *dbType)

再调用search函数导出区块中重复R的各个签名以及它们的相关信息

duplicates := search(log, db)//返回值是rMap

作者新定义一个与导出集合类型一致的map,(value是存储的该签名R相关的信息的一个数组,也就是说存储着多组不同的rData)这段代码非常重要,是作者整个思想的核心,通过循环判断value数组的长度是否大于一,若是则证明签名R是重复的,若不是则签名R不重复。

realDuplicates := make(map[string][]*rData)
for k, v := range duplicates {
		if len(v) > 1 {
			realDuplicates[k] = v
		}
	}

最后将上文代码中的realDuplicates导出成文件,至此完成了整个比特币网络中相同签名r及其相关信息的导出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值