VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

如何学习区块链技术|建立第一个离线代码项目

Three learners review open books together at a classroom table, with stacks of textbooks, stationery and a whiteboard in the bright room.

第一个区块链相关代码项目可以很小、离线,而且每步讲得清。不必从钱包、部署合约或在线节点开始。本指南把上一篇读数练习实现,让书面规则、纯函数、预期和测试连接起来。

文内提供完整Python文件及测试:分有界十六进制整数与字节格式,精确格式化整数,组合卡保留原输入。目标是理解实现及限制,不是制造通用区块链工具包。

全部合成数据,没有网络客户端、凭证、签名、账户访问或交易提交。它是本地教学实验,不是生产RPC解析器、安全审计、财务工具或完整标准符合声明。

精选照片说明学习场景,不是已核验区块链课堂。

找到下一步学习

如何学习区块链技术|指南18

选择问题 · 定义对象 · 理解案例 · 核对与变化 · 检查迁移

章节目录 · 完整学习路线

目录

第1—5节

1. 选能讲清的小输出

2. 保住离线权限边界

3. 先复制完整合同

4. 共用语法,不合并类型含义

5. 失败也是规定输出

第6—10节

6. 用整数算精确显示

7. 独立写预期结果

8. 决定测试支持什么

9. 清楚理解运行要求

10. 检查完整程序与测试

第11—15节

11. 自选运行一个本地命令

12. 准确读发布运行记录

13. 编辑前先读失败

14. 检查测试能否发现故意错误

15. 新功能先改合同

第16—20节

16. 保来源到代码对照

17. 用教回讲实现

18. 十分项目评分

19. 有理由选下一路线

20. 交接可重做成果

第1节/共20节|学习与核对

1. 选能讲清的小输出

返回目录

项目定为四函数加测试:NLab串转整数、BLab串转bytes、精确整数及尺度转显示、组合卡保原串整数尺度显示。

它练表示、类型、精确数量及保留证据的解释,这些常见于区块链数据工作,但程序本身不是区块链。无区块、共识、持久账本、密码证明或分布参与者。

项目笔记顶部写这个区别。称完整链或安全钱包只增加未支持含义,不改善学习。那些主题有库路线,需要先修和另定项目。

首里程碑是界面前讲每函数输入、输出、失败。六卡还不会分类就回上一篇,不能让按钮掩盖未解决类型问题。

完成点不是代码行数,而是别人能按合同给一个新输入,你能先预测再检查。一个只会运行却说不明结果的小工具,仍需补概念;一个能逐分支解释的有限程序,已经是有价值的学习成果。

目录 · 下一节

第2节/共20节|学习与核对

2. 保住离线权限边界

返回目录

程序只接显式参数,不读环境变量、不开文件、不连服务、不恢复密钥或查账户。测试仅打印本地结果,不发消息或改远程系统。

不为真实感加服务地址或秘密,合成材料已足够。真实集成新增身份、权限、时间、错误及服务行为,需独立范围和证据。

私钥、客户记录都不需要。安全实验及钱包与托管:看清谁能行动、阻止和恢复可学保管,但此项目不做保管,也不承诺恢复。

列能力清单及缺席能力。若新功能需外部权限或敏感数据,就不再是这个离线练习的无须审查小改动。边界让未来读者也知道文件会做什么。

本地标准库测试不需要申请API,也不应让学习者提交助记词。程序中没有读取这些内容的路径。若以后确需网络,那是另一个任务,不是为当前文件解除某个隐藏前提。

目录 · 上一节 · 下一节

第3节/共20节|学习与核对

3. 先复制完整合同

返回目录

NLab精确字符串、小写0x、1至64小写hex字符,除单0不许前导零,回非负整数。BLab同前缀字符集,正文0至64偶数,回bytes并保零对。

格式器接精确Python整数q、d,排布尔,要求0≤q<2的256次方、0≤d≤6,固定d位显示;d0无点。超合同用ValueError。

组合器保raw、integer、decimals、display,不查元数据、不猜缺尺度。本地长度和小写不是所有链条件。

用规范指南查类型、条件、限制。接受更多输入可属另一合同,不因此符合当前合同。先规则,再比较代码及测试,避免运行后临时决定正确标准。

将每条要求转换成可观察预期:缺正文时抛什么,空字节时返回什么,尺度缺失时不猜什么。先列失败再实现,可避免把首版程序的偶然行为误当原设计意图。

目录 · 上一节 · 下一节

第4节/共20节|学习与核对

4. 共用语法,不合并类型含义

返回目录

两解码器共需前缀、长度和字符,故共用_body,仅回已验证正文,不决定整数或bytes。

NLab再查非空最短;BLab再查偶数。分支隔离,空正文仅BLab通过,防一套规则漏进另一套。

这是本地职责分离,不是万能架构。架构指南与单体式与模块化区块链:厘清职责与信任边界可读更宽责任;此程序小,可看全部分支,不需框架包。

图中共享助手分两条有类型结果,标int与bytes。若只说“解码数据”,问各输出在合同中是什么。语言能另转类型,不表示这里自动做额外转换。

共享助手允许空正文,因为它还不知道走哪条路。非空规则放NLab,偶数规则放BLab。这解释代码为何不能在助手里提前统一拒绝空串,否则会错改BLab的有效情况。

目录 · 上一节 · 下一节

第5节/共20节|学习与核对

5. 失败也是规定输出

返回目录

本实验对错类型及超条件统一ValueError,是本API选择,不要求所有Python库或生产服务同样报错。

拒绝而不暗中trim、改小写或补零。NLab收到0x01,原表示失败。将来界面若修复,要另标转换规则,不能说原值通过。

测试含缺前缀、大写、空白、非hex、符号、错类型、超长;格式器测布尔、负数、浮点、字符串及尺度越界。每项命要求,不笼统说能处理错误。

学习表列输入、预期异常、要求。失败值若回零,会混成功与拒绝,哪怕界面整齐也违合同。加呈现层前应能解释为何要保区别。

异常类型也是合同的一部分。测试若只检查出现任意错误,可能把不相关崩溃误当预期拒绝。本文件检查ValueError;另一种异常应提示调查,而不是自动算正确处理。

目录 · 上一节 · 下一节

第6节/共20节|学习与核对

6. 用整数算精确显示

返回目录

先查q、d,再专门处理d0;其他用divmod按10的d次方分商余,余数补到d位,不需浮点。

1250、2为12.50;1250、3为1.250;1001、3为1.001;0、2为0.00。显示位不代表测量精度或资产价值。

Python官方说明整数精度及布尔与整数关系。代码用精确类型排布尔,不因子类型便利而接受。Python内置类型

数学要求与语言选择分开,别的实现可选另一精确表示,但需证据。大整数测试使小例不成为唯一检查,通过只支持该环境与材料,不支持全部运行时。

源码里type参数精确检查不是装饰。Python中布尔有整数子类型关系,而此题明确排除它,故便利的通用整数判断不能悄悄扩大API。读分支时把语言行为与要求对照。

目录 · 上一节 · 下一节

第7节/共20节|学习与核对

7. 独立写预期结果

返回目录

运行前保留纸面答案。六卡NLab三、BLab四,显示由商余决定,不询问首个实现“应该返回什么”。

NLab的0x0为0、0xff为255、0x00拒绝;BLab的0x为空、0x00单零字节、0x1拒绝。无在线网络也能暴露规则混淆。

测试实际对独立预期,拒绝查指定异常。unittest官方介绍相等及异常断言;材料和合同为原创。Python unittest文档

命名原因:0x0001测字节长度,1001、3测补位,布尔测类型排除。这样故障可解释,也知道新增用例是否真正扩边界,而非重复刷数量。

不要让expected直接调用同一个被测函数产生,否则两边可能共享相同错误。这里预期小值来自纸面推理,往返测试另验证有限关系;两类证据互补,但没有一类自动覆盖所有输入。

目录 · 上一节 · 下一节

第8节/共20节|学习与核对

8. 决定测试支持什么

返回目录

一次匹配支持该输入、预期及被测实现,不自动证明完整正确、安全或外部符合。保实现版本环境。

十个测试方法中有多子案例,两方法分别对0至255做最短整数和单字节往返。这是有限集合,不穷尽256位整数或所有坏串。

边界查最大NLab值、32字节及下一超长例,是指定限度证据,不是资源耗尽审计或敌对生产流量适用性。

作品集保成功与缺覆盖。可说指定运行时十方法通过,不能说普遍正确。规范指南分文本与有限实现,阅读区块链审计材料:代码版本、证明范围与升级权限提供保证范围路线。

表中“未测”不是失败,也不是通过。例如没有在线节点观察,就不填写节点兼容性。这样报告既保留真实绿测结果,也避免把缺证据涂成积极结论。

目录 · 上一节 · 下一节

第9节/共20节|学习与核对

9. 清楚理解运行要求

返回目录

只用标准库re及unittest,程序不要求安装包、账户或上网。发布准备中在Python3.12.14运行此版本。

这不替读者安装解释器,不证明本地命令同版本。选择运行需用获授权环境并另记版本,也可只读代码及纸面结果。

文件名保持blockchain_data_lab.py,保存整块不只首函数,测试同文件有意减少初学协调对象。

找不到文件未检查合同;语法错未完成测试;断言失败是实际与预期不同。环境、文件路径、实现关系需分问题,不能一概说算法坏。

文件名与实际保存位置也要一致。命令指向另一个旧副本时,输出不能代表眼前代码。保留运行对象身份,是很简单但重要的证据连接,不需为了方便而省略。

目录 · 上一节 · 下一节

第10节/共20节|学习与核对

10. 检查完整程序与测试

返回目录

下方原生代码块含完整文件:导入、共享助手、四公开函数、十测试方法及入口,与本批附件同源,无省略段或秘密配置。

逐函数对合同:_body查语法尺寸;decode_quantity加非空最短;decode_data加偶数;format_units查整数及商余;read_quantity保解释字段。

测试也是解释。找前导零、空bytes和补小数零案例,先预测再看断言,把分支连纸面,不把绿色结果当魔法。

复制不加网络,不把失败预期改成当前输出只为通过。若改合同另标版本并同步理由预期,否则按失败定位原要求违背。

代码块同时提供测试,是为了让读者检查预期如何表达,而不是只相信作者说通过。可以逐条追到上一文的纸面规则;若看不出对应关系,先补对照再扩大项目。

"""Offline teaching profile, not a production blockchain/RPC decoder."""
import re
import unittest

HEX = re.compile(r"[0-9a-f]*", re.ASCII)


def _body(text):
    if type(text) is not str:
        raise ValueError("expected a string")
    if not text.startswith("0x"):
        raise ValueError("expected lowercase 0x prefix")
    body = text[2:]
    if len(body) > 64 or HEX.fullmatch(body) is None:
        raise ValueError("expected at most 64 lowercase hex digits")
    return body


def decode_quantity(text):
    """NLab: zero or a minimal nonnegative hex integer, at most 64 digits."""
    body = _body(text)
    if not body or (len(body) > 1 and body[0] == "0"):
        raise ValueError("expected minimal nonempty quantity")
    return int(body, 16)


def decode_data(text):
    """BLab: zero to 32 bytes; each byte has exactly two hex digits."""
    body = _body(text)
    if len(body) % 2:
        raise ValueError("expected two hex digits per byte")
    return bytes.fromhex(body)


def format_units(amount, decimals):
    """Exact fixed-decimal display for this bounded educational profile."""
    if type(amount) is not int or not 0 <= amount < 2**256:
        raise ValueError("amount must be an integer in [0, 2**256)")
    if type(decimals) is not int or not 0 <= decimals <= 6:
        raise ValueError("decimals must be an integer from 0 to 6")
    if decimals == 0:
        return str(amount)
    whole, fraction = divmod(amount, 10**decimals)
    return f"{whole}.{fraction:0{decimals}d}"


def read_quantity(text, decimals):
    amount = decode_quantity(text)
    return {"raw": text, "integer": amount, "decimals": decimals,
            "display": format_units(amount, decimals)}


class DataLabTests(unittest.TestCase):
    def test_quantity_cases(self):
        for raw, expected in [("0x0", 0), ("0x1", 1), ("0xff", 255),
                              ("0x4e2", 1250), ("0x3e9", 1001)]:
            with self.subTest(raw=raw):
                self.assertEqual(decode_quantity(raw), expected)

    def test_quantity_rejections(self):
        for raw in ["0x", "0x00", "0x01", "0x04e2", "ff", "0X1",
                    "0xFF", " 0x1", "0x1 ", "0x-1", "0xg", True, 1, None]:
            with self.subTest(raw=raw):
                with self.assertRaises(ValueError):
                    decode_quantity(raw)

    def test_data_cases(self):
        for raw, expected in [("0x", b""), ("0x00", b"\x00"),
                              ("0x01", b"\x01"), ("0x0001", b"\x00\x01"),
                              ("0xff", b"\xff")]:
            with self.subTest(raw=raw):
                self.assertEqual(decode_data(raw), expected)

    def test_data_rejections(self):
        for raw in ["0x0", "0x1", "0x4e2", "0xGG", "0xFF", "00",
                    "0X00", "0x00 ", "0x 00", True, None]:
            with self.subTest(raw=raw):
                with self.assertRaises(ValueError):
                    decode_data(raw)

    def test_format_cases(self):
        for amount, decimals, expected in [(1250, 2, "12.50"),
                (1250, 3, "1.250"), (1001, 3, "1.001"),
                (1000, 3, "1.000"), (0, 2, "0.00"), (7, 0, "7"),
                (9007199254740993, 2, "90071992547409.93")]:
            with self.subTest(amount=amount, decimals=decimals):
                self.assertEqual(format_units(amount, decimals), expected)

    def test_format_rejections(self):
        for amount, decimals in [(True, 2), (-1, 2), (1.0, 2),
                ("1", 2), (1, True), (1, -1), (1, 7), (1, 2.0),
                (2**256, 2)]:
            with self.subTest(amount=amount, decimals=decimals):
                with self.assertRaises(ValueError):
                    format_units(amount, decimals)

    def test_read_card(self):
        self.assertEqual(read_quantity("0x4e2", 2),
            {"raw": "0x4e2", "integer": 1250, "decimals": 2, "display": "12.50"})
        with self.assertRaises(ValueError):
            read_quantity("0x4e2", 7)

    def test_bounds(self):
        self.assertEqual(decode_quantity("0x" + "f" * 64), 2**256 - 1)
        self.assertEqual(len(decode_data("0x" + "00" * 32)), 32)
        with self.assertRaises(ValueError):
            decode_quantity("0x1" + "0" * 64)
        with self.assertRaises(ValueError):
            decode_data("0x" + "00" * 33)

    def test_small_quantity_roundtrip(self):
        for amount in range(256):
            with self.subTest(amount=amount):
                self.assertEqual(decode_quantity(hex(amount)), amount)

    def test_single_byte_roundtrip(self):
        for amount in range(256):
            with self.subTest(amount=amount):
                value = bytes([amount])
                self.assertEqual(decode_data("0x" + value.hex()), value)


if __name__ == "__main__":
    unittest.main(verbosity=2)

目录 · 上一节 · 下一节

第11节/共20节|学习与核对

11. 自选运行一个本地命令

返回目录

完整文件放所选目录,有合适Python3时,用python3 blockchain_data_lab.py,从文件所在目录执行或用实际路径。这是读者选择,不是文章在你机器执行。

入口调用详细unittest,列方法及结果,不问钱包、助记词、端点或付款。别处若要求这些,不属于本项目。

真执行才把命令、运行时、源版本、输出存笔记。不能把发布运行结果当自己机器结果;只读应标代码阅读。

先预测0x4e2及尺度2的卡:raw原串、integer1250、decimals2、display12.50。测试已有此组合,显示纸面预期与执行关系。

python3 blockchain_data_lab.py

目录 · 上一节 · 下一节

第12节/共20节|学习与核对

12. 准确读发布运行记录

返回目录

准备时此文件在Python3.12.14十个测试方法全部通过,包括往返循环、合法非法、显示、组合、边界。它不是节点测试。

“Ran 10 tests”这里数方法,不是十输入。子案例更多,两循环各256,不能说十次比较涵盖全部空间。

耗时是附带信息,不是吞吐基准,不能与链交易率比。这里只有小本地转换,没有网络或接受状态终点。

本地运行另记观察。耗时异不等语义异,断言失败才需比结果。负载与观察可回扩容基础设施指南,但解析器通过不自动建立其测量框架。

十方法成功也不等十个独立标准认证。方法内部有多输入,循环覆盖有限256值,数量标签应按实际测试结构解释。报告清楚比把数字写得更大更有价值。

目录 · 上一节 · 下一节

第13节/共20节|学习与核对

13. 编辑前先读失败

返回目录

若预期1.001实得1.1,先看format_units余数补位,不是hex。可解整数正确却显示错。

若NLab接受0x01,查最短条件,不能去BLab禁止零字节,因为那边有意保留。职责内修,不搬错profile。

若接受布尔q,查精确类型及合同。语言数值便利不覆盖API。保其他正确项,修分支后重跑局部及全套。

命令不存在或文件没找到,先查环境路径,尚无解析器断言证据。日志记观察、要求、改动、后测,不只写“好了”。

目录 · 上一节 · 下一节

第14节/共20节|学习与核对

14. 检查测试能否发现故意错误

返回目录

可选另存实验副本,去最短规则、去余数补零或错换字节条件,先预测哪个材料应失败,原参考不改。

这是错误与测试关系,不表示发现几种故意错就能发现全部。未测路径仍可能有缺陷,不能说完整覆盖。

若未发现,查断言是否存在、是否到分支,再加有独立依据材料。发现则说明对应要求并存观察。

结束回参考,实验副本标清。不编辑生产服务、不削弱安全控制,文件离线虚构。目标理解为何某检查重要,保持合同、参考和实验结果不同身份。

这项可选任务不要求你保存有缺陷版本给别人使用。若保留,应命名为故意错误实验,说明预期失败,避免将来误当参考实现。原版和实验版的结果不能混在同一通过记录中。

目录 · 上一节 · 下一节

第15节/共20节|学习与核对

15. 新功能先改合同

返回目录

若要大写也通过,是新profile,不是原小写合同的修错。先写条件、是否保原raw、用例,再改代码。

尺度超6也需改范围、看资源与测试,不因一个例方便删边界。小上限是课堂明确选择。

连真实服务更是新范围,需身份、权限、请求、状态、错误及来源。比较区块链RPC答案:先对齐网络、区块和问题读完整观察问题,当前不提供在线保证。

先版本任务再扩实现,保原源及结果,别人才能分回归与有意变化。规范及治理指南分产物、行为要求和运行观察,不把它们当同标签。

增加功能后,受影响旧测试也要重查。允许大写会改变既有拒绝预期,但不应顺便改变字节长度或显示补位。差异表帮助守住未改要求,使变化范围可解释。

目录 · 上一节 · 下一节

第16节/共20节|学习与核对

16. 保来源到代码对照

返回目录

表列要求、函数、材料、限制:最短到decode_quantity及前导零拒绝;字节保留到decode_data及0x0001;补位到format_units及1001、3;卡保原串到read_quantity。

限制具体:raw不认证RPC来源,bytes转换不验签,显示不建经济价值,本地测试不证网络兼容。这是不同缺关系,不是一句泛警告。

真实文档给词汇与语言行为,边界profile、材料、卡及教育评估原创,64位hex及尺度6不能归所有标准。

作品集对照连初解释和运行证据,读者可从失败追要求函数。方法可迁移另获授权项目,但此整洁表不认证更大项目完整安全。

要求函数材料限制
最短整数decode_quantity拒绝0x01仅本NLab
保字节decode_data0x0001两字节不验签
精确补位format_units1001、3为1.001不建价值精度
保原输入read_quantity原串、整数、尺度、显示不认证RPC来源
原创来源到代码对照,每项贡献另列限制。

目录 · 上一节 · 下一节

第17节/共20节|学习与核对

17. 用教回讲实现

返回目录

关闭源,说0x0为何NLab过BLab拒,0x00相反,0xff两过却不同类型,再说1001、3为何1.001。连概念不背函数名。

再讲不做什么:网络、凭证、签名、远程状态核验、交易提交,以及本地profile限度,避免实现信心扩权限。

能跑却不懂分支,回纸面;懂规则代码错,定向修并测。这是两种缺口,日志不同。

双语保标识符、数值、布尔排除和失败。空bytes翻成整数零就变概念。教回指南给方法,本篇给新对象,按实际结果,不继承别课虚构分。

目录 · 上一节 · 下一节

第18节/共20节|学习与核对

18. 十分项目评分

返回目录

五类各2:完整合同、类型职责、合法拒绝材料、精确显示及类型守卫、执行证据与限度。全对2、部分1、缺或矛盾0。

绿测却称bytes认证记录,扣范围;NLab懂但暗收布尔尺度,类型不能满。评分连修复,不奖功能最多。

局部教育不授软件资格,不证明生产安全或准备运营。发布参考运行属于此工作流,自己阅读执行应如实标。

存初解释、改动、测试、新变化。复制参考应称学习运行参考,不称独立设计全部。支持标签使作品集更有信息,显示已能讲什么及更宽声明还缺什么。

目录 · 上一节 · 下一节

第19节/共20节|学习与核对

19. 有理由选下一路线

返回目录

类型不清回上一篇,写码时要求漂移回规范,运行却讲不明回教回,不必重启全库。

密码核验读相应密码学,不加verified字段冒充;状态用执行练习;网络用基础设施。新能力各需前提任务检查。

下一可仍离线:另定材料读取器或状态模拟器,完整前提独立预期。通过本文件不自动要求合约账户集成。

作品集写一项下一任务及停点,例如解释小写规则变化并提用例,不做在线接入。进度是可声明、实现、检查关系扩大,同时保护当前任务边界。

目录 · 上一节 · 下一节

第20节/共20节|学习与核对

20. 交接可重做成果

返回目录

完成说明识别文件、profile、运行时、测试及限制:“blockchain_data_lab.py实现本NLab、BLab和精确显示合同,准备中Python3.12.14十方法通过。材料有限虚构,无网络、签名或区块链核验。”

只读就改写代码检查和纸面预测;自己运行记自己版本输出;修改给新合同版本。证据句匹配实际工作,不借发布结果。

完整代码、测试、对照、初解释并存,别人可查结果、追要求、懂修正。项目虽小,这是强而有限成果。

下一缺口回总导航,文章库给深度,实验示范一小片如何变可理解实现。价值在规则、代码、观察及限制连接清楚,不在主张宽。

目录 · 上一节 · 下一节

继续学习

技术文章库

来源与范围

NLab、BLab、有界显示规则、材料及学习评分为原创教学格式。离线文件不是通用RPC解码器、安全审计、财务工具或区块链实现。链接技术文保留各自例子与条件。来源与路线于2026年10月15日核验。阅读和纸面练习不认证实现能力。

Python built-in types

Python unittest