实验四:区块链浏览器&常见区块链钱包

一、实验概述

本实验一方面以比特币和以太坊的区块链浏览器为例,首先介绍获取区块链数据的基本技巧;进而利用区块链浏览器解析并学习区块链账本层与合约层的构造,结合多个典型事务,加深学生对于多种区块链状态的认知与体会;对批量获取区块链数据进行数据挖掘的相关技巧进行点拨,该实验也是后续所有区块链实践的必备积淀。另一方面,针对于存储私钥的应用——区块链钱包,本实验旨在让学生掌握主流货币系统生成密钥和地址、签发交易的基本方法,以及掌握区块链钱包的基本分类,了解并体验不同类型的区块链钱包,并针对学有余力的同学组队展开进阶实验。

二、预备知识

  1. 区块链浏览器

作为浏览区块链信息的主要窗口,区块链浏览器向用户提供其感兴趣的区块链相关信息,并且区块链浏览器还可能额外提供对于测试网络的支持,数据可视化服务,钱包服务(和开放 API(方便用户精确、批量的获取数据)。

  1. Base58

用于 Bitcoin 中使用的一种独特的编码方式,主要用于产生 Bitcoin 的账户地址。相比于 Base64 去除了易于混淆的 0OIl 和作为标点的+/,使得地址的表述更加清晰,但该种编码方式也因此付出了编码效率上的妥协

  1. 比特币脚本

是比特币使用的一种基于堆栈的执行语言,比特币将一系列带有特定功能的执行脚本 OPCODE 进行特定编码,通过合理组合后按照“先入后出”的顺序执行,辅助完成交易的验证功能。

  1. API

Application Programming Interface,即应用程序接口,规定了运行在一个端系统上的软件请求因特网基础设施向运行在另一个端系统上的特定目的地软件交付数据的方式。API的使用使得软件系统的职责得到合理划分,有助于提高系统的可维护性和可扩展性。

  1. JSON

JavaScript Object Notation,是一种常用的轻量级数据交换格式,因其具有简洁和清晰的层次结构,而成为理想的数据交换语言,既易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

6. 区块链钱包的分类

区块链钱包常按照下面几种方法分类:按照节点数据是否存储完整,可分为全节点钱包(完整存储区块链所有交易数据)和轻节点钱包(只保存了区块链钱包的基本功能);按照区块链钱包是否联网,可分为冷钱包(私钥在本地存储,不联网)和热钱包(联网);按用户是否自行持有私钥,可分为中心化钱包(第三方机构代管用户私钥)和去中心化钱包(用户自行持有钱包的私钥);按是否支持多种币种,可分为单、多币种钱包,及全币种钱包。

三、实验内容

实验 4-1:区块链浏览器的基本操作与功能

  1. 请在区块链浏览器中查询区块000000000000000003dd2fdbb484d6d9c349d644d8bbb3cbfa5e67f639a465fe 并对该区块进行分析,该区块有何异常,造成该异常的原因是什么,这可能体现了区块链系统设计中的哪些问题?

image-20231015161329711

image-20231015162109365

出现了确切的付款金.(无变化)发送准确金额(0.00001BTC )且不找零的付款很可能表明比特币没有移动。
这通常意味着用户使用“发送最大金额”钱包功能将资金转移到她的新钱包、交易所账户、闪电通道或其他类似情况下,比特币仍归同一所有权所有。
发送不更改的确切金额的其他可能原因是,硬币选择算法足够聪明和幸运,能够为不需要更改的预期支付金额找到一组合适的输入(或需要可以忽略不计的更改金额以放弃更改),或者高级用户使用手动硬币选择来明确避免更改。
  1. 观察浏览器对于比特币挖矿难度变化的可视化实时结果 ,尝试回答:难度调整的间隔;难度变化的趋势和其带来的影响;推测平均算力的计算方法。

难度调整时间间隔:每2016个区块(13-15天左右)
难度变化趋势及其影响:2018年以前难度很低(接近0),且平缓;2018年之后难度整体上以指数级别进行增长,不过在2021年底有一次明显幅度的难度降低。
推测平均算力的计算方法:对网络产生前2016个区块的实际总算力求平均值
  1. 参考 blockstream API 的调用说明,调用 API 回答以下问题:

    • 当前比特币待验证的交易数目为多少?数据量为多大?大概几个区块才能处理完这些交易?

      使用API:/mempool

      mempool

      因返回数据量较大,故将返回值输出到mempool.json中
      1
      curl https://blockstream.info/api/mempool | python3 -m json.tool > mempool.json
      mempooljson

      故可知待验证交易数量为25777,数据量大小为74535373vB;比特币一个区块上限1MB,大约承载4000笔交易,故需约25777/4000=7\lceil25777/4000\rceil=7个区块才能处理完。

    • 给出高度在 9991-10000 间区块内包含的总交易数目。

      使用API:

      apiblocks

因返回数据量较大,故将返回值输出到blocks10.json中
1
curl https://blockstream.info/api/blocks/10000 | python3 -m json.tool > blocks10.json

blocksjson

统计高度在 9991-10000 间区块内包含的总交易数目:tx_count10=110=10tx\_count*10=1*10=10

实验 4-2:利用区块链浏览器学习区块链账本层构造

观察 P2SH 交易的赎回脚本,说明该脚本规定的解锁条件和运行机理,并拟写其解锁脚本

1
OP_3DUP OP_ADD OP_PUSHNUM_9 OP_EQUALVERIFY OP_ADD OP_PUSHNUM_7 OP_EQUALVERIFY OP_ADD OP_PUSHNUM_8 OP_EQUALVERIFY OP_PUSHNUM_1
  • 锁定脚本
    1
    OP_HASH160 OP_PUSHBYTES_20<target_redeemScriptHash> OP_EQUAL
  • 赎回脚本
    • 解锁条件:满足以下方程组

      {X+Y=9Z+X=7Y+Z=8\begin{cases} X+Y=9\\ Z+X=7\\ Y+Z=8 \end{cases}

  • 解锁脚本:
    1
    OP_PHSHNUM_Z OP_PUSHNUM_Y OP_PUSHNUM_X OP_PUSHBYTES_7(6f938893889388)

    reedhash

  • 运行机理:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    //首先运行解锁脚本
    //初始状态:空堆栈
    [] //压入常数Z
    [Z] //压入常数Y
    [Z, Y] //压入常数X
    [Z, Y, X] //入栈完整赎回脚本
    [Z, Y, X, redeemScript]

    // 复制堆栈后运行锁定脚本
    [Z, Y, X, redeemScriptHash] //HASH160取出栈顶脚本计算脚本哈希后压入
    [Z, Y, X, redeemScriptHash, target_redeemScriptHash] //压入目标脚本哈希
    [Z, Y, X, TRUE]// EQUAL 取出栈顶两个哈希,判断是否相等,压入检测结果

    // 取出栈顶结果,如果非真,则验证失败,否则运行原始脚本
    [Z, Y, X] //准备运行赎回脚本
    [Z, Y, X, Z, Y, X] //运行3DUP,复制栈顶的三个元素
    [Z, Y, X, Z, X+Y] //运行ADD,取出栈顶两个元素,将二者之和压入
    [Z, Y, X, Z, X+Y, 9] //压入常数9
    [Z, Y, X, Z] //运行EQUALVERIFY,取出栈顶常数,确认它们等值,否则验证失败
    [Z, Y, Z+X] //运行ADD,取出栈顶两个元素,将二者之和压入
    [Z, Y, Z+X, 7] //压入常数7
    [Z, Y] //运行EQUALVERIFY,取出栈顶常数,确认它们等值,否则验证失败
    [Y+Z] //运行ADD,取出栈顶两个元素,将二者之和压入
    [Y+Z, 8] //压入常数8
    [] //运行EQUALVERIFY,取出栈顶常数,确认它们等值,否则验证失败
    [1(TRUE)] //压入常数1

    // 栈顶为真值则验证成功

    参考文章:12

实验 4-3:利用区块链浏览器解析并学习区块链合约层构造

根据实验 3 中的描述尝试上述操作,并在实验报告中写出你对这部分的学习总结,不少于 80 字,截图不少于 1 张即可。

  1. 点击区块8413441详情
    4-3-1
    • 可以发现区块的大小不再有固定上限,而是由事务费用上限 Gaslimit决定,而事务费用则直接与矿工所执行合约的总复杂度相关联。
  2. 查看合约CryptoKitties
    4-3-2
    • 在其合约首页上便可以看到其代币的价值以及合约定义的所有方法,方便用户的学习、检测与调用,用户可以发布事务通过自己的账户或驱动其他合约与该合约交互。
  3. 查看合约事件一栏

    4-3-3
    • 可以看到该合约最近的状态变动,触发改动的事务地址以及事务所调用的具体方法
  4. 点击具体的事务地址

    4-3-4
    • 可以获得关于该次状态变动更加详细的信息
  5. 通过Etherscan API 接口获取以太坊的状态:
    • 注册用户并生成免费API 密钥令牌:
      4-3-5
    • 参考API文档测试「获取单个地址的以太币余额」的API:

4-3-6

注:使用curl命令会报超时错误(无法连接服务器)

4-3-e

  1. Etherscan 收集的一系列有助于合约开发和学习的在线工具
    4-3-7
    • 有助于智能合约的开发学习与漏洞检测
  2. 感悟:
    • 我遵循指导书的步骤,通过逐步访问以太坊区块链浏览器 Etherscan,学习了智能合约的基本构造,了解了合约层部署的不同,探究了合约和其触发事务的状态,体验了Etherscan API的密钥生成与调用,认识了一系列有助于智能合约开发学习与漏洞检测的工具,收获颇丰!

实验 4-4:体验比特币靓号地址

  • 由于主机为Mac OS,故实验材料所提供的windows版本vanitygen并不能使用。

    • 在Github上找到vanitygen项目,git clone到本地,查看安装说明书直接make编译即可

    1
    git clone git@github.com:samr7/vanitygen.git
    • 但是由于项目过于古老,编译报错,貌似是OpenSSL库并没有链接
    • 又在GitHub上找到了vanitygen-plusplus项目(应该是大佬魔改升级的,此外还发现有plus项目(雾))

    1
    git clone git@github.com:10gic/vanitygen-plusplus.git
    • 根据安装说明更改Makefile的部分语句(看起来就是在链接OpenSSL库)后,再次执行make进行编译

    • 虽然warning*n,但是经过测试均可以正常使用,故接下来的实验都使用「vanitygen-plusplus」进行。

  1. 包含"ccc"的地址:

    4-4-1

  2. 以 11 开头且以 77 结尾的地址

    4-4-2

  3. 以 3 个数字结尾的地址

    4-4-3

  4. 以 3 个数字再接"88"结尾的地址

    4-4-4

附:正则表达式参考指南

实验 4-5:体验在线生成不同种类的钱包地址

  • 打开实验提供的 html 文件,选择“简体中文”模式,体验各类钱包地址的生成

    • 虚荣钱包:
      虚荣
    • 普通钱包:
      single
    • 分裂钱包:
split

拓展实验 4-7:利用开源项目部署自己的区块链浏览器

blockscout

拓展实验 4-8:藏头诗

  • 因为在Mac故选择shell脚本文件实现批处理:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/zsh
    cd vanitygen-plusplus

    declare -i i=1
    declare -i one=1
    for ch in $@
    do
    ./vanitygen++ -r "^[^\s]{$i}$ch" | grep Address: --color
    i=$i+$one;
    done
    • 运行脚本结果如下

image-20231018171107087