笔者一直致力于区块链底层技术研究。本文将讲下第一代区块链(比特币),go语言版本BTCD源码整体架构。
如果你是刚入门区块链技术,那么笔者建议可以先学习下blockchain_go。
blockchain_go:一个简单的go语言实现的区块链工程(A simplified blockchain implementation in Golang)
blockchain_go将从区块(Block),工作证明机制(Pow),数据存储(BoltDB),UTXO,地址(address),网络(P2P)等方面讲解区块链基础版本的实现。
BTCD 是用go语言实现的完整节点的比特币实现。
BTCD和Bitcoin Core之间的区别是Btcd不包括钱包(wallet)功能,即交易部分。这是一个有意义的设计决策,可以通过Etcd同步比特币区块和挖矿。
Btcd包括部分P2P网络、BlockChain、交易池TxPool、挖矿Pow、Rpc接口。
地址管理、连接管理、协议数据。
地址管理:p2p连接地址的管理,包括未连接地址和连接成功地址。
连接管理:通过tcp协议连接外部节点,打开自己的tcp服务器;同时用于接收比特币协议数据(Peer.go inHandler())
同步管理器:用于统一处理各个节点发送和接收到的数据,以便同步区块链和同步交易。
BlockChain(区块链)包括ffldb存储,数据结构和Chain基本逻辑。
ffldb存储:是基于goleveldb(嵌入式数据库leveldb的go语言版本),开发了上成api。
数据结构:顾名思义包括BlockChain的地址数据结构,块数据结构,链的数据结构。还包括Merkle树的逻辑,椭圆曲线算法的接口,比特币脚本Script逻辑。
交易池TxPool是用来管理所有接收到的交易Tx。
pool map[chainhash.Hash]*TxDesc //交易池
orphans map[chainhash.Hash]*orphanTx //孤立交易池
定时获取交易池TxPool中的交易池Tx 算出头Hash,遍历*maxExtraNonce*int64数,输出一定难度值的hash值。
CPUMiner.go generateBlocks方法。
配置sample-btcd.conf文件,到btcd.exe 同一级目录
[Application Options]
rpcuser=myuser
rpcpass=SomeDecentp4ssw0rd
datadir=D:/btcd/data
logdir=D:/btcd/logs
configfile=D:/btcd/config/btcd.conf
rpccert=D:/btcd/config/rpc.cert
rpckey=D:/btcd/config/rpc.key
debuglevel=debug
启动btcd
.\btcd.exe
配置btcctl.conf文件,到btcctl.exe 同一级目录
[Application Options]
rpcuser=WD6r9pYx/q8k/rywvrwclShlHd4=
rpcpass=bjKKPvzWEaQbNpgo3Ium5YB0N38=
rpccert=D:/btcd/config/rpc.cert
启动btcctl:
getinfo启动一个指令,其他指令请执行.\btcctl.exe -l
.\btcctl.exe -C .\btcctl.conf getinfo
addmgr - 地址管理
blockchain - 实现比特币区块处理和链选择规则
blockchain / fullblocktests - 提供一组用于测试共识验证规则的块测试
btcec - 实现对比特币脚本所需的椭圆曲线密码函数的支持
btcjson - 为底层的JSON-RPC命令和返回值提供一个扩展的API
chaincfg/chainhash - 提供通用的散列类型和相关函数,允许抽象特定的散列算法。
connmgr - 链接管理器
database - 为比特币区块链提供数据库接口,实现了ffldb
mempool - 未发掘的比特币交易池。
mining - pow挖矿
netsync - 同步管理器,同步区块链和交易
peer - 创建和管理比特币对等网络,及上行下行数据包的处理
rpcclient - 实现一个强大且易于使用的支持Websocket的比特币JSON-RPC客户端
txscript - 实现比特币交易脚本语言
wire - 实现比特币网络协议
btcd的运行过程主要在server.start
1.启动地址管理器addrManager (savePeers 保存地址)
addrManager.go
peersFile //保存在文件中的连接节点信息
addrIndex //addrNew 与 addrTried地址集合
addrNew //map[桶树编号][地址map集合],未被确定可连接的集合
addrTried //连接成功集合
nTried //addrTried大小
nNew //addrNew大小
knownaddress.go
attempts //连接次数
lastattempt //最后一次连接时间
lastsuccess //最后一次成功连接时间
refs //节点被连接次数
2.启动同步管理器syncManager, blockHandler接收数据
manager.go
txMsg //交易信息
blockMsg //下载的块消息
invMsg //区块和交易的哈希值
headersMsg //header消息
processBlockMsg //挖到新块
3.启动连接管理 connManage
connHandler
开启监听handleConnected与handleDisconnected服务,connReq链接成功的去调用OnConnection,由outboundPeerConnected处理请求
listenHandler
OnAccept开启服务,由inboundPeerConnected处理请求
NewConnReq
Connect链接线上节点
4.启动Peer服务
//peer 链接监控
go p.stallHandler()
//接受其他节点发送的报文
go p.inHandler()
//需要发送的报文需由queueHandler处理后发送至其他节点
go p.queueHandler()
//发送报文
go p.outHandler()
//心跳检测
go p.pingHandler()
go s.rebroadcastHandler()// 确保用户提交的tx 上链
s.rpcServer.Start() //开启http和websocket请求
s.cpuMiner.Start()
节点链接到一个线上节点后,就开始同步区块。
同时节点会把未确定交易下载到TxPool
tx(ProcessTransaction)处理流程:
1. handleTxMsg 处理交易入口
2. 检测该交易Hash是否已经存在于交易池或者孤立池
3. 检查交易大小金额是否正确,标准交易验证
4. 检查是否有双花
5. 检查交易输入是否有效、签名等
6. 将交易封装加入到交易池,更新lastUpdate
7. 如果输入不存在,则进入孤立交易处理流程
以上别说笔者是Btcd架构和启动过程的大致理解,可能不是很到位。后续笔者将对Btcd数据同步和挖矿做详细的介绍。
作者:niyuelin(区块链极客,一直致力于区块链底层技术的研究)
欢迎大家加入区块链技术探讨群,QQ群号21911041