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 students in school uniforms work through open books at a classroom table, with textbooks and stationery nearby and study notes on the whiteboard behind them.

离线状态模拟器把区块链学习规则连到可执行转换,不必运营网络。初态、请求、条件、结果和后态都在小程序中可检查。本指南将教回课的笔记例子变成完整Python学习项目。

你会分独立材料与顺序重放,保留拒绝请求,检查旧输入不变,并解释有限测试运行。完整源码及十二测试方法在文内。下一篇使用同一参考项目,演示具体错误怎样产生具体失败模式。

这是虚构应用状态练习,不是区块链实现或Ethereum模拟器。真实性是给定布尔前提;无签名、账户、费用、共识、网络、持久记录或交易,published仅为模型字段。

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

找到下一步学习

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

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

章节目录 · 完整学习路线

目录

第1—5节

1. 选代码前写学习目标

2. 分应用模型与真实虚拟机

3. 完整定义State与Request

4. 写四条件转换

5. 让输入保留可见

第6—10节

6. 五个独立材料

7. 独立测试与顺序重放

8. 重放输入输出合同

9. 运行前读完整程序

10. 检查完整参考源码

第11—15节

11. 准确解释十二方法运行

12. 检查原因优先

13. 检查不变量及终值

14. 只改owner做迁移

15. 字段错误与拒绝请求

第16—20节

16. 保离线证据边界

17. 建要求到测试表

18. 十分学习评分

19. 改前先备回归笔记

20. 完成声明匹配运行

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

1. 选代码前写学习目标

返回目录

目标是实现指定转换并按给定顺序重放,不是建账本或真发布笔记。小项目有用,但不能因名字而获得未实现能力。

上一篇代码处理表示:字符串、整数、字节、显示;本项目处理请求与当前状态如何决定接受及后态。输入解析正确,不等于转换正确。

能力句可写“给合法State和Request,按合同算Result且不改输入”;重放另写“把每后态给下一请求,保所有结果”。两任务均可观察。

先让学习者分别预测接受标记和后态,再检查两者是否来自同一条规则。只猜中最后修订号,可能仍没理解拒绝请求;只说拒绝,却把状态改掉,也没有满足合同。代码项目需要同时连接决定及效果。

概念不清回重放或教回指南。会运行却讲不清拒绝为何不变,应补精确推理,不自动加真实集成。绿色指示不能替代关系解释。

目录 · 下一节

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

2. 分应用模型与真实虚拟机

返回目录

模型是声明的简化,练条件与转换,不重现生产执行。Ethereum官方EVM文档是另一技术路线,本文件不实现其指令、记账或失败规则。Ethereum EVM文档

这里无gas、账户随机数、区块选择、最终性或网络状态。拒绝不改三个字段是给定规则,不能推所有真实失败交易的每个变量都不变。

相似术语不使系统相同。state、request、revision在别处可有不同定义,代码旁保本合同,超范围再查技术库。

范围说明写研究什么、缺什么。完整解释小模型可正确却只支持窄结论。叫模拟器不会增加权威,也不能作为生产验证代码交付。

真实系统可能在应用结果外另有协议记账。这里不模拟这些字段,因此“拒绝不变”必须带上“本模型三个追踪字段”范围。这样学习者以后看到真实平台的不同结果,不会误以课堂规则应覆盖全部实现。

目录 · 上一节 · 下一节

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

3. 完整定义State与Request

返回目录

State含owner、revision、published。owner为精确非空Python字符串,作不透明课堂标识;revision为精确非负整数,排布尔;published精确布尔。纯空白owner未另禁止,字符串不带身份权威。

Request含caller、expected_revision、authentic:非空精确字符串、非负精确整数排布尔、精确布尔。True由材料给定,不是签名算法输出。

S为owner A、revision2、published False。B请求expected2、authentic True在字段上合法,却可能无应用权限。

错字段构造时ValueError;格式合法但不允许时返回拒绝Result。两路径分开,不能把类型正确说成符合用途。规范阅读指南可修这种层次混淆。

owner与caller用精确字符串相等比较,没有姓名解析、组织认证或密钥注册。A和B只是材料标识,不代表已经核验某真实人物。这个小选择让权限条件可计算,同时明确现实身份连接尚未实现。

目录 · 上一节 · 下一节

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

4. 写四条件转换

返回目录

接受需authentic True、caller等当前owner、expected等当前revision、published False,全部满足,不投票、不平均、不以信任替代某项。

成功owner不变、revision加1、published True;拒绝全部字段不变。Result保accepted、reason、before、after,决定与作用都可查。

实现按authenticity、owner、revision、published报告首个失败。这是明确报告选择,使多失败确定;首因不表示后项都过。

先分开合取与更新。未决定就增号改了合同;把拒绝说成字段错误混了层。四条件卡保留到能解释每项并预测新材料。

Result的before使读者知道检查针对哪个状态,after则显示决定后的状态。两者不应只靠一张最终截图替代。reason也不能单独替代accepted,因为报告文本和决定标记各有合同,测试分别保留。

目录 · 上一节 · 下一节

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

5. 让输入保留可见

返回目录

使用frozen dataclass。Python官方说明生成方法及模拟只读的frozen选项,这是便利,不是密码防篡改。Python dataclasses文档

成功用replace构造新State,不对输入赋新值;拒绝before、after指未变状态。当前字段为简单类型,方便与基线比。

frozen不是不可改区块链历史,无持久历史或对抗保护。测试只检查正常字段赋值被阻,以及调用后基线保留,不能扩大。

若C1修改共享基线,下一独立题会无意从后态开始。新结果和明示重置保护题目;顺序重放则有意传后态,是另一任务,不是偶然副作用。

frozen在这里帮助阻止普通字段赋值,不等于抵抗恶意修改的安全边界。我们也没有保存带签名的审计记录。不要把程序语言的只读便利与分布式账本的证据、治理或恢复能力混为一谈。

目录 · 上一节 · 下一节

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

6. 五个独立材料

返回目录

C1从S,A、expected2、True,接受到A、3、True。C2独立从S,B、2、True,因owner拒绝,S不变。

C3从S,A、1、True,revision拒绝。C4另给A、2、True初态,A、2、True请求因published拒绝,保该不同初态。

C5从S,A、2、False,因authenticity拒绝。关系同教回指南,现变可执行材料,不是新真实协议。

一成功四拒绝,拒绝仍保成功项:C2真实性True,C3 caller是owner。合取失败不是全部失败,输出含身份、初态、请求、决定、原因、后态供重做。

C4的初状态有意另给,不需从C1推它怎样形成。C1成功后号为3,而C4初号为2,混接会改材料。独立案例可以检查某一条件,顺序案例才要求前后历史连接,读题时先确认属于哪一种。

独立材料初owner/revision/publishedcaller/expected/authentic结果/后态
C1A/2/FalseA/2/True接受;A/3/True
C2A/2/FalseB/2/Trueowner;不变
C3A/2/FalseA/1/Truerevision;不变
C4A/2/TrueA/2/Truepublished;不变
C5A/2/FalseA/2/Falseauthenticity;不变
各材料独立使用声明初态;不真实发布或核验。

目录 · 上一节 · 下一节

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

7. 独立测试与顺序重放

返回目录

独立材料按各声明重置,顺序将前一后态给下一。差异是输入合同,不只是表格外观,暗混会改题。

一次从S:T1 A、2、True;T2 A、2、True;T3 A、3、True,中途不重置。

T1接受到A、3、True;T2因expected2不等3报revision,published也True但后查;T3号匹配却已发布,报published。最终A、3、True。

flags为True、False、False;理由accepted、revision、published。每后续before等前after。若每次重置,第二错成功,第三在错revision上判断,下一篇会实验此错误。

特别注意T2同时不满足修订号及未发布,报告只选较早的revision。T3的号已经匹配,才报告published。相同终态下,两次拒绝原因不同;保逐步记录,才能解释为什么不是重复的同一种失败。

步骤预期号接受原因之后号/published
T12Trueaccepted3 / True
T22Falserevision3 / True
T33Falsepublished3 / True
一次从A/2/False顺序运行,caller全A且真实性True。

目录 · 上一节 · 下一节

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

8. 重放输入输出合同

返回目录

replay接精确State及list或tuple,所有成员为精确Request。先验整个集合,坏成员ValueError,不把半份结果当完整运行返回。

合法时回最终State及顺序Result tuple。空集合回初态和空tuple,不因函数调用虚增号或造成功操作。

顺序由课堂给,不决定谁有排序权、不处理并发或独立运营者协议,相关问题回共识架构。

只留终态可藏错路径,只留理由可藏错更新,所以决定、解释、转换一起保。纸面过程由此成为可检查实现,不补未实现能力。

空序列也是有意义边界:没有请求就没有更新。它不说明系统停机或所有请求失败,只表明这次给定输入为空。返回初态及空结果,使调用者能把“没有操作”与“操作被拒绝”分开。

目录 · 上一节 · 下一节

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

9. 运行前读完整程序

返回目录

下一节是完整blockchain_state_lab.py,字段、转换、重放及十二unittest方法,仅标准库,无包、账户、API密钥、端点。

先State、Request,再apply_request,再replay,每分支指合同句,最后看对应测试。先预测,再把执行视为证据。

发布准备于Python3.12.14测试,不替设备安装解释器,也不建立本地环境。可只读,真跑则识别文件及运行时。

下一调试伴随按此模块名导入,两个文件同选定目录。它是普通文件依赖,不藏网络。伴随完整提供,故意错误与参考清楚分开。

若命令找到的是另一个旧副本,输出也不代表眼前文件。记录源文件身份和实际路径,属于简单但必要的运行证据。不能仅凭屏幕同样显示OK,就把不同版本的观察合并。

目录 · 上一节 · 下一节

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

10. 检查完整参考源码

返回目录

原生代码块为整文件,含测试入口,与附件相同,不需猜省略部分。

注解本身不是字段验证逻辑,显式初始化后检查执行本地合同。转换入口再查对象类型,非法构造与合法拒绝分开。

读源码时可从测试反向追到分支,再回合同句。例如test_stale_revision应走revision拒绝,而不是真实性分支。这样的对照帮助你理解测试在观察什么,而不是把测试名称当已证明全部机制的标签。

测试含成功、owner、旧号、已发布、真实性、多失败优先、输入保留、顺序、空序列、owner变化、坏输入,共十二方法,有多断言。

不加凭证或真实记录。讲不清分支回纸面,跑完整不等理解全部连接,下一任务按缺口,而非自动扩项目。

"""Offline note-state teaching model; not a blockchain protocol."""
from dataclasses import dataclass, replace, FrozenInstanceError
import unittest


@dataclass(frozen=True)
class State:
    owner: str
    revision: int
    published: bool

    def __post_init__(self):
        if type(self.owner) is not str or not self.owner:
            raise ValueError("owner must be a nonempty string")
        if type(self.revision) is not int or self.revision < 0:
            raise ValueError("revision must be a nonnegative integer")
        if type(self.published) is not bool:
            raise ValueError("published must be Boolean")


@dataclass(frozen=True)
class Request:
    caller: str
    expected_revision: int
    authentic: bool

    def __post_init__(self):
        if type(self.caller) is not str or not self.caller:
            raise ValueError("caller must be a nonempty string")
        if type(self.expected_revision) is not int or self.expected_revision < 0:
            raise ValueError("expected revision must be a nonnegative integer")
        if type(self.authentic) is not bool:
            raise ValueError("authentic must be Boolean")


@dataclass(frozen=True)
class Result:
    accepted: bool
    reason: str
    before: State
    after: State


def apply_request(state, request):
    if type(state) is not State or type(request) is not Request:
        raise ValueError("expected State and Request")
    if not request.authentic:
        return Result(False, "authenticity", state, state)
    if request.caller != state.owner:
        return Result(False, "owner", state, state)
    if request.expected_revision != state.revision:
        return Result(False, "revision", state, state)
    if state.published:
        return Result(False, "published", state, state)
    after = replace(state, revision=state.revision + 1, published=True)
    return Result(True, "accepted", state, after)


def replay(initial, requests):
    if type(initial) is not State or type(requests) not in (list, tuple):
        raise ValueError("expected State and a list or tuple of Request")
    if any(type(request) is not Request for request in requests):
        raise ValueError("every item must be a Request")
    current = initial
    results = []
    for request in requests:
        result = apply_request(current, request)
        results.append(result)
        current = result.after
    return current, tuple(results)


class StateLabTests(unittest.TestCase):
    def setUp(self):
        self.initial = State("A", 2, False)

    def test_success(self):
        result = apply_request(self.initial, Request("A", 2, True))
        self.assertEqual(result, Result(True, "accepted", self.initial,
                                      State("A", 3, True)))

    def test_wrong_owner(self):
        result = apply_request(self.initial, Request("B", 2, True))
        self.assertEqual(result, Result(False, "owner", self.initial, self.initial))

    def test_stale_revision(self):
        result = apply_request(self.initial, Request("A", 1, True))
        self.assertEqual(result.reason, "revision")
        self.assertFalse(result.accepted)
        self.assertEqual(result.after, self.initial)

    def test_already_published(self):
        state = State("A", 2, True)
        self.assertEqual(apply_request(state, Request("A", 2, True)),
                         Result(False, "published", state, state))

    def test_authenticity(self):
        self.assertEqual(apply_request(self.initial, Request("A", 2, False)),
                         Result(False, "authenticity", self.initial, self.initial))

    def test_reason_priority(self):
        self.assertEqual(apply_request(self.initial,
                         Request("B", 1, False)).reason, "authenticity")
        self.assertEqual(apply_request(self.initial,
                         Request("B", 1, True)).reason, "owner")

    def test_unchanged_input(self):
        apply_request(self.initial, Request("A", 2, True))
        self.assertEqual(self.initial, State("A", 2, False))
        with self.assertRaises(FrozenInstanceError):
            self.initial.revision = 9

    def test_sequential_replay(self):
        final, results = replay(self.initial, [Request("A", 2, True),
                               Request("A", 2, True), Request("A", 3, True)])
        self.assertEqual(final, State("A", 3, True))
        self.assertEqual([r.accepted for r in results], [True, False, False])
        self.assertEqual([r.reason for r in results],
                         ["accepted", "revision", "published"])
        self.assertEqual(results[1].before, results[0].after)
        self.assertEqual(results[2].before, results[1].after)

    def test_empty_replay(self):
        self.assertEqual(replay(self.initial, []), (self.initial, ()))

    def test_changed_owner(self):
        state = State("B", 2, False)
        self.assertFalse(apply_request(state, Request("A", 2, True)).accepted)
        self.assertEqual(apply_request(state, Request("B", 2, True)).after,
                         State("B", 3, True))

    def test_field_validation(self):
        for args in [("", 2, False), ("A", True, False),
                     ("A", -1, False), ("A", 2, 0)]:
            with self.subTest(state=args):
                with self.assertRaises(ValueError):
                    State(*args)
        for args in [("", 2, True), ("A", True, True),
                     ("A", -1, True), ("A", 2, 1)]:
            with self.subTest(request=args):
                with self.assertRaises(ValueError):
                    Request(*args)

    def test_api_validation(self):
        with self.assertRaises(ValueError):
            apply_request({}, Request("A", 2, True))
        with self.assertRaises(ValueError):
            replay(self.initial, [Request("A", 2, True), {}])
        with self.assertRaises(ValueError):
            replay(self.initial, "requests")


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

目录 · 上一节 · 下一节

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

11. 准确解释十二方法运行

返回目录

准备中该文件Python3.12.14十二方法通过,记录给定程序材料,不是部署、安全审查或真实链执行,无交易。

成功覆盖这些正负路径、重放、验证,不穷尽所有owner、revision、列表和运行时,也不证明无缺陷。

自选本地命令python3 blockchain_state_lab.py,保自己的版本输出;只读标检查预测,不把发布记录当自己的运行。

耗时不比链吞吐。小本地负载无网络接受或最终性终点,重要是实际是否匹配转换预期,不是看起来快。

python3 blockchain_state_lab.py

目录 · 上一节 · 下一节

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

12. 检查原因优先

返回目录

B、expected1、False对S会先报authenticity;只改True则报owner。严格按声明顺序。

首例owner和revision也失败,次例revision仍失败。reason是报告政策下选一因,不是所有条件真值向量。

若将来要输出全部失败项,那是新报告接口,要明确顺序、类型及测试。当前函数只承诺首项,不能因为读者想看到更多,就把没有返回的项写成通过。缺省输出与条件真假是不同层。

合取与报告分开。换检查顺序可不改接受,却改变reason测试,因为API承诺顺序。应标变化,不把每个新reason当新接受结果。

教回问报告因、另一个失败项、后态,三关系都保。若误以一因表示其余过,回条件表逐项评,再重建有序报告。

目录 · 上一节 · 下一节

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

13. 检查不变量及终值

返回目录

拒绝after等before;接受owner不变、号恰加1、published True;顺序下一before等前after;输入不被调用修改。

局部不变量帮助组织,不证明安全或替代接受依据。错误程序可保拒绝态却错接受无权请求,也可拒绝对却增号错。

因此要求表要同时有决定见证和状态见证。下一篇的两类故意错误会分别击穿这两种检查。先理解为什么单看flag不够,再运行实验,更容易把失败解释为具体关系而不是笼统程序坏了。

决定材料与不变量都用:C2查权限及不变,C1查依据及精确更新,顺序查连接及终值,胜于只查最终号。

卡写范围及反例:拒绝加1违反不变。下一篇只在隔离变体做,不推广到真实失败交易全部记账,模型明排那些字段。

目录 · 上一节 · 下一节

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

14. 只改owner做迁移

返回目录

S2为B、2、False,C1及C2请求与True保留,各独立从S2,不接旧成功态。

C1因A非B拒绝保S2;C2因B等B等条件接受到B、3、True。真实性未变。

测当前状态依赖,不背A总成功B总失败。原S及新S2并存,各按初态正确,不互删。

作品集写单变事实、未变、新决定、限制。说A密钥坏,指出True未变;初号错,修材料身份。纸面受控比较现有具体代码测试支持。

目录 · 上一节 · 下一节

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

15. 字段错误与拒绝请求

返回目录

布尔revision或整数1的authentic超合同,构造ValueError,无合法Result。语言可数值用True不覆盖此要求。

B、2、True格式合法,对S才owner拒绝。期待构造失败问错层,类型不授权限。

如果replay材料后面有一个字典,程序先验全体并抛错,不返回前面请求的部分结果。这里没有外部写入可回滚,输入也不变。这个明确API选择不应被解释为真实交易系统的原子提交保证。

重放含普通dict也拒绝,全部预查。此局部行为不是内存池、传输解析或批交易说明。

诊断表分非法对象与合法被拒,列预期及负责函数。上一数据实验也分表示失败,本项目扩到状态决定但不合并证据。

目录 · 上一节 · 下一节

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

16. 保离线证据边界

返回目录

authentic True是输入,不是独立签名证据;published True不证明有人收到;revision3不是区块号、时间戳或最终性证书。

无持久化、认证服务、权限注册、共享排序或对抗网络,字段检查与frozen不能补这些。名字含blockchain也不赋能力。

执行可读从用户意图到交易证据:构造、授权与执行、把智能合约读成状态机:核对调用者、条件与边界、合约存储、事件与索引:核对同一记录的三种视图、诊断失败的区块链交易:区分拒绝、回退与调用边界,排序协议回共识,各例不成为隐藏行为。

“按本规则重放给定请求”有支持,“验证区块链交易”没有。有限并非无用,目的是先看清机制,再学其他层关系。

目录 · 上一节 · 下一节

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

17. 建要求到测试表

返回目录

字段到构造及field_validation;接受到test_success;权限到wrong_owner;报告序到reason_priority;连接到sequential_replay;基线到unchanged_input。

限制同表:owner测试不测全部权限设计,冻结赋值不证防篡改存储,重放不证并发协议。表用于路由,不装饰保证。

unittest官方提供断言框架,材料和规则原创,工具文档不背书模型或认证覆盖。Python unittest文档

作品集保表、纸面、源码、运行时、结果,再加新解释。学习参考不说独立设计全部,诚实支持标签有利选下一步。

目录 · 上一节 · 下一节

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

18. 十分学习评分

返回目录

五类各2:完整合同;分字段与接受;独立及顺序结果;保留及原因序;本地证据和范围。全对2、部分1、缺或矛盾0。

终态碰对却每步重置不能满重放分;本地都懂却称True为算出的签名证明,扣范围。

教育标准不授工程资格,十二通过不自动个人精通分。写实际读、预测、运行、修改或新变化解释。

存初答修正,伙伴或模型给连接标辅助,再无模型新题测迁移。作品集和教回提供记录方法,本篇给新可执行对象。

目录 · 上一节 · 下一节

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

19. 改前先备回归笔记

返回目录

保存参考身份、完整合同、纸面预期、基线运行,未来可比已知任务,不是不断改的描述。

先选一错:漏owner、拒绝增号、成功加2、重放重置。看实验前预测哪材料受影响,它们有不同诊断图样。

不往生产或覆盖参考练错。伴随用另名离线函数,参考保留,对独立探针,避免制造误导线上补丁。

下一输出含问题、版本、失败、违规则、修复目标、复测。解释为何失败转匹配,比不明改动后绿灯更有学习证据。

目录 · 上一节 · 下一节

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

20. 完成声明匹配运行

返回目录

示范:“blockchain_state_lab.py实现给定笔记转换及有序重放,准备时Python3.12.14十二方法通过,含独立拒绝、连接及owner变化,无真实密码核验、网络、持久化或共识。”

自己的说明换实际观察,只读就说只读,修改注明版本合同。读者应可查,不靠自信。

完整源码、测试、纸面、要求表并存,小但可重做可理解修正,是有限成果,不假装完整链。

下一调试篇看四种错误及回归笔记,大库给技术深度,学习项目把声明切片变可执行、可测、可讲,同时保假设边界。

目录 · 上一节 · 下一节

继续学习

技术文章库

来源与范围

笔记规则、材料、诊断变体及学习评分为原创离线教学练习。真实性是给定布尔,不是计算核验。程序不是区块链实现、审计或生产补丁。链接技术文保留各自例子与条件。来源与路线于2026年10月15日核验。阅读和纸面练习不认证实现能力。

Python dataclasses

Python unittest

Ethereum EVM documentation — separate real execution environment