区块链系统探索之路:比特币核心的编译和探索

news2024/10/7 10:13:33

前几节我们研究了椭圆曲线,有限域等比特币和区块链所依赖的底层算法。问题在于这些算法不是独立存在,而是作为模块嵌入到整个区块链的体系之中。因此不了解区块链的体系组成或应用场景,那么我们就很难理解这些算法衍生出来的概念或者基于他们的作用,所以本节我们把区块链最原始的模态,也就是比特币核心编译和运行起来,先获得初步感性体验,然后在后面的章节中,我们能更好的明白椭圆曲线,有限域,如何组成钱包地址,为何数据在区块链系统中传输还需要各种奇奇怪怪的数据压缩等问题。

首先我们使用ubuntu系统,然后通过git clone https://github.com/bitcoin/bitcoin.git 获取比特币内核代码,注意我们需要使用v0.21.0版本,因为更早以前的版本会因为莫名其妙的原因难以编译通过,使用下面代码进行分支切换:
git checkout v0.21.0

首先我们需要安装一些编译依赖库,使用如下命令进行安装:
sudo apt install libevent-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev

sudo apt install libdb-dev libdb+±dev

sudo apt install libminiupnpc-dev

sudo apt install libzmq3-dev

sudo apt install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools

sudo apt install libqrencode-dev

代码下载后我们进入目录bitcoin,由于比特币内核需要依赖伯克利db4因此我们需要预先安装,我们所下载的代码就包含了对应的安装脚步,进入下载代码的根目录bitcoin,然后执行如下命令:
$ ./contrib/install_db4.sh `pwd`
改命令把db4的依赖库就安装在当前目录。上面代码运行完成后,它会输出如下提示:

 export BDB_PREFIX='/home/ubuntu/bitcoin/db4'
 ./configure BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I${BDB_PREFIX}/include"

这是在设置环境变量,使得比特币内核在编译时知道怎么获取db4代码库所在位置,因此我们也分别执行上面两行代码对应的命令:
export BDB_PREFIX=‘/home/ubuntu/bitcoin/db4’
./configure BDB_LIBS=“-L B D B P R E F I X / l i b − l d b c x x − 4.8 " B D B C F L A G S = " − I {BDB_PREFIX}/lib -ldb_cxx-4.8" BDB_CFLAGS="-I BDBPREFIX/libldbcxx4.8"BDBCFLAGS="I{BDB_PREFIX}/include”

然后执行本地脚步:
./autogen.sh
然后我们需要通过config.sh脚步设置编译选项,在编译中我们需要忽略掉伯克利db版本,因此执行如下命令:
./configure --with-incompatible-bdb
然后执行如下命令进行源码编译:
make -j “ ( ( (( (((nproc)+1))”
上面命令意思是调用当前所有cpu内核通过并行编译的方式加快速度。成功编译后再执行如下命令将比特币内核的可执行文件进行安装,这样我们就能在系统中直接运行bitcoind命令启动比特币内核:
sudo make install

编译和安装完成后,我们可以直接通过命令行来调用比特币内核,在第一次运行时我们需要设置一个配置文件,在bitcoin的安装目录创建一个bitcoin.conf文件:
vim /home/ubuntu/.bitcoin/bitcoin.conf(注意这是我自己的路径,读者需要确定自己的安装路径)
然后设置用户名和密码,其内容类似如下:
rpcuser=you_name
rpcpassword=your_password
在配置文件中,我们可以设置比特币内核把当前服务器作为“完全节点”,也就是它会把比特币所有链上数据都下载到本地,如果你的服务器有足够的内存和带宽就可以这么做,我估计当前比特币网络的线上数据应该T以上了,由于我的服务器硬盘也就是几十个G,因此我这里必须限制比特币内核跟整个网络的数据交互上限,因此我在配置文件里面增加如下约束:
maxconnections=15
prune=5000
minrelaytxfee=0.0001
maxmempool=200
maxreceivebuffer=2500
maxsendbuffer=500

大家可以查一下这些配置的意义,这里我们不多费唇舌,完成上面配置后,我们就可以运行比特币内核了,使用如下命令启动比特币内核:
bitcoind -daemon

启动后我们就可以使用比特币客户端跟内核交互:
bitcoin-cli -getinfo
执行上面命令后,如果你看到类似如下输出,那表明比特币内核启动正常:
{
“version”: 210000,
“blocks”: 0,
“headers”: 120000,
“verificationprogress”: 1.142581983030402e-09,
“timeoffset”: 1,
“connections”: {
“in”: 0,
“out”: 3,
“total”: 3
},
“proxy”: “”,
“difficulty”: 1,
“chain”: “main”,
“relayfee”: 0.00010000,
“warnings”: “”
}

通过bitcoin-cli 执行的命令本质上是向比特币内核发送rpc请求,然后对方返回相应数据,这些命令其实也是内核对外提供的API接口,我们可以用如下命令去查询某个接口的具体用法,例如执行如下命令:
bitcoin-cli help getblockhash
那么返回的数据为:
请添加图片描述
根据提示,我们可以通过getblockhash接口或命令获得给定标号区块对应的哈希值,例如我们执行如下命令:
bitcoin-cli getblockhash 1000
在我本机上得到的结果就是:
请添加图片描述
在后面我们会看到,区块链使用了多种压缩算法对数据进行压缩编码以便于传输,这里我们可以通过比特币客户端解压一段数据感受一下,执行命令如下:

bitcoin-cli decoderawtransaction
 0100000001186f9f998a5aa6f048e51dd8419a14d8a0f1a8a2836dd734d2804fe65fa35779000000008b483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adfffffffff0260e31600000000001976a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788acd0ef8000000000001976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac00000000

上面命令执行后所得结果如下:

{
  "txid": "0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2",
  "hash": "0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2",
  "version": 1,
  "size": 258,
  "vsize": 258,
  "weight": 1032,
  "locktime": 0,
  "vin": [
    {
      "txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
      "vout": 0,
      "scriptSig": {
        "asm": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
        "hex": "483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf"
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.01500000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA"
        ]
      }
    },
    {
      "value": 0.08450000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK"
        ]
      }
    }
  ]
}

后面我们也会详细的探讨区块链在数据传输过程中,数据的压缩算法和压缩格式。我们也能通过代码的方式跟比特币内核交互,很多编程语言都提供了相应的接口包,例如python就python-bitcoinlib能用来与比特币内核交互,我们看看相关例子,首先安装该库:

pip install python-bitcoinlib

然后创建文件python_bitcoin.py,添加内容如下:

from bitcoin.rpc import RawProxy

#连接比特币内核
p = RawProxy()

info = p.getblockchaininfo()

print(info['blocks'])

上面代码向比特币内核查询当前区块数量,在我本机运行上面代码后返回结果如下:
434100
也就是在我当前机器上,内核下载了 434100 个区块。需要注意的是,如果我们运行的比特币内核没有以“完全节点”的形式启动,那么有些接口就无法返回有效数据,例如执行如下命令获取区块编号为 277316 的哈希:
bitcoin-cli getblockhash 277316
命令执行后返回的结果为:
0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4
如果我们使用getblock 命令并通过上面哈希获取区块数据的话就有可能返回错误,例如执行:
bitcoin-cli getblock 0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4
在我本机上运行上面代码后返回:
error code: -1
error message:
Block not available (pruned data)

由于我本节硬盘空间有限,因此我没有使用“完全节点”模式来运行内核,于是内核在同步区块链数据时,它只把部分区块的头部信息下载到本地,这样就导致本地无法读取区块的数据内容。

下一节我们看看如何使用我们前几节提到的算法实现钱包地址,同时也通过比特币内核提供的接口来验证我们算法的正确性。更多内容请在b站搜索coding迪斯尼

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/679655.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【硬件1】platform/i2c总线

文章目录 1.platform总线:相对于USB/PCI/I2C/SPI等物理总线来说,platform总线是一种虚拟的总线,实际并不存在,总线的工作就是就是完成总线下的设备和驱动之间的匹配。也就是在左手中找到与右手相匹配的设备驱动,并完成…

基于Java+Springboot的智能图书馆座位管理系统设计和实现

博主介绍:擅长Java、微信小程序、Python、Android等,专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟 Java项目精品实战案例…

MySQL实战解析底层---为什么只查一行的语句,也执行这么慢

目录 前言 第一类:查询长时间不返回 第二类:查询慢 前言 一般情况下,如果说查询性能优化,首先会想到一些复杂的语句,想到查询需要返回大量的数据但有些情况下,“查一行”,也会执行得特别慢这…

第11讲:BootService 核心实现解析,Agent 的“地基”原来是这样的

之前介绍了 ServiceManager 加载并初始化 BootService 实现的核心逻辑。下图展示了 BootService 接口的所有实现类,本课时将深入分析这些 BootService 实现类的具体逻辑: 网络连接管理 在前面的介绍中提到 SkyWalking Agent 会定期将收集到的 JVM 监控和…

基于Java+Swing实现雷电小游戏

基于JavaSwing实现雷电小游戏 一、系统介绍二、功能展示三、其他系统四、获取源码 一、系统介绍 基于java的雷电游戏基本功能包括:敌方飞机随机飞行、我方飞机手动控制飞行,射击比拼,游戏闯关等。本系统结构如下: (1&…

Java中线程的创建与使用、Thread类的常用方法

1、什么是进程与线程 1.1 含义 1.1.1 进程 进程是指正在运行的程序的实例。在操作系统中,一个进程代表了一个正在执行的程序,它包括了程序的代码、数据以及程序执行时所需要的系统资源。 最直观的就是我们任务管理器: 任务管理器中的每一…

Centos7安装和配置Mysql5.7

第一步:获取mysql YUM源 进入mysql官网获取RPM包下载地址,下面就是mysql5.7的Yum仓库的rpm包: mysql5.7链接地址: https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm 第二步:下载和安装mysql…

卷福的十年同学会

1.一通电话 某个上班日的午休时间里,小卷正趴在办公桌玩着手机准备睡一会,“叮咚”,一条微信消息弹出来,是大学的班群消息。 “五一期间大家来学校聚一下吧,今年是我们成为同学的十年了,大家提前报名哦&a…

Qt设置软件启动动画(支持图片和视频俩种方式)

目录 软件启动动画效果静态背景动态背景 程序启动动画QSplashScreen启动时加载静态图片启动时加载视频动画将启动动画置于所有窗口顶层 软件启动动画效果 先来看效果。下面录制了加载图片和gif动图的俩种效果。 静态背景 动态背景 这里我加载了一个gif的动图,你也…

AMBA AHB的burst termination

前言 在AMBA AHB协议中,AHB master可以用burst传输连续取多笔数据。AHB定义了4、8和16拍的burst传输、未定义长度的burst传输和单次传输。Burst传输中支持incrementing和wrapping。 Incrementing burst用于访问顺序的memory地址,burst中每个拍的地址都…

数据压缩的常用手段以及方法

0. 简介 之前我们在《经典文献阅读之–R-PCC(基于距离图像的点云压缩方法)》中提到了,我们可以通过一些算法层面来完成数据的压缩,而其实更简单或者说更直接的方法就是使用half这种形式来完成数据压缩。 1. half和float Half是用16位表示浮点数的一种…

什么是 FL Studio?2023年最新版 FL Studio21.0.3.3517中文版图文安装教程

什么是 FL Studio? FL Studio 是一个数字音频工作站 (DAW)。该软件借助各种编辑工具、插件和效果,让您可以录制、混音和掌握高度复杂的音乐作品。FL Studio 还允许您注册和编辑 MIDI 文件,您可以在众多可用乐器之一上演奏这些文件。FL Studi…

树莓派 python3.9降级为python3.7

今天烧录了一个官方烧录器中的最新的镜像,打开之后python的版本是3.9的,之前做的一些东西都是基于python3.7的,再重新架构十分麻烦,于是干脆就把python3.9进行降级,降为python3.7. 这个镜像不像之前的一些镜像&#x…

通用商城项目(上)

通用型产品(电商)发布解决方案落地实现(基于分布式微服务技术栈: SpringBootSpring CloudSpring Cloud Alibaba VueElementUl MyBatis-Plus MySQL Git Maven Linux Nginx Docker 前后端分离) 项目技术栈和前置技术 项…

【软件设计师暴击考点】操作系统知识高频考点暴击系列【一】

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:软件…

Web网页制作-知识点(1)——HTML5介绍、HTML5的DOCTYPE声明、HTML基本骨架、标题标签、段落 换行、水平线图片图片路径、超链接

目录 HTML5介绍 HTML5的DOCTYPE声明 HTML基本骨架 标题标签 段落、换行、水平线 图片 图片路径* 超链接 HTML5介绍 HTML5是用来描述网页的一种语言,被称为超文本标记语言。用HTML5编写的文件,后缀以.html结尾 HTML是一种标记语言,标…

自动化神器AutoIt,告别重复劳动

概要 计算机已经进入大众家庭多年,它给我们带来了便利,却也带来了枯燥、重复、机械的重复工作。今天,我要和大家分享一款自动化工具AutoIt,它能够帮助你告别这些烦恼,并提高工作效率。 AutoIt 是一款完全免费的Windows…

leetcode82. 删除排序链表中的重复元素 II(java)

删除排序链表中的重复元素 leetcode82. 删除排序链表中的重复元素 II题目描述一次遍历代码演示 链表专题 leetcode82. 删除排序链表中的重复元素 II 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/remove-duplicates-fr…

1.1 编写一个简单的C++程序

博主介绍:爱打游戏的计算机专业学生 博主主页:夏驰和徐策 所属专栏:夏驰和徐策带你从零开始学C 1.1.0 这段话告诉我们什么? 这段话解释了一个C程序中的main函数的基本结构和功能。 它告诉我们以下几点: 1. C程序的…

Debian11 编译bluez

之前的几篇文章写过如果编译x86和dv300 版本的bluez,不过那都是在 Centos7 上编译的。然而当我从taobao 上买了一个蓝牙适配器后发现无法使用(淘宝客服说不支持Centos,只支持ubuntu 和 debian)。再者 Centos 现在也停止支持服务了…