我写了个“教学版”比特币,用 10 个 Python 脚本带你彻底搞懂核心原理 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
freekindom
V2EX    Bitcoin

我写了个“教学版”比特币,用 10 个 Python 脚本带你彻底搞懂核心原理

  •  
  •   freekindom 13 小时 4 分钟前 807 次点击

    比特币、区块链,一问到 UTXO 、PoW 、数字签名这些核心细节,可能就有点模糊了。看理论文章又常常觉得枯燥,不够直观。

    为了彻底搞懂它,我决定用纯 Python 从零撸一个简化版的比特币,并把过程整理成了 10 个循序渐进的脚本,希望能帮到有同样困惑的 V2EXer 。

    这个项目最大的特点就是 “为教学而生”

    项目地址: https://github.com/picasso250/my-bitcoin/


    这个项目有什么不同?

    • 100% 循序渐进:从 step1 (生成密钥) 到 step10 (模拟网络共识),每个脚本只专注一个核心概念。你可以python step1_... python step2_... 这样一步步执行下来,看着它从无到有,完全没有学习断层。
    • 代码即文档:我写了大量“保姆级”的注释,不仅解释代码“做了什么”,更解释了“为什么这么设计”。比如,为什么地址需要校验和?为什么交易要确定性序列化?
    • 聚焦核心,抛弃噪音:项目砍掉了复杂的 P2P 网络层和 Base58 编码,让你能把全部精力放在 密码学 (ECDSA)、交易结构 (UTXO) 和工作量证明 (PoW) 这些真正奠定比特币大厦的基石上。
    • 鼓励与 AI 结对学习:项目 README 和注释风格都非常适合与 Gemini 这样的 AI 助手互动。看不懂的地方,直接把代码和问题丢给它,把它当成你的 24/7 助教,学习效率翻倍。

    10 步学习路径概览:

    1. step1_generate_keys.py: 生成你的第一对公私钥。
    2. step2_sign_and_verify.py: 理解签名的本质。
    3. step3_public_key_to_address.py: 从公钥到我们熟悉的地址。
    4. step4_build_simple_transaction.py: 构建第一笔“交易”。
    5. step5_create_a_block.py: 把交易打包进区块。
    6. step6_mine_a_block.py: 引入工作量证明 (挖矿)!
    7. step7_single_utxo_transaction.py: 核心概念! 理解 UTXO 和“找零”。
    8. step8_multi_input_utxo_transaction.py: 模拟“凑钱”支付。
    9. step9_coinbase_in_utxo_block.py: 搞懂矿工奖励和手续费。
    10. step10_simulated_network_consensus.py: 上帝视角,看多个节点如何达成共识。

    这个项目不求生产可用,只求能让一个聪明的开发者在一个下午的时间里,通过亲手跑代码,对 比特币 的运作原理有一个清晰、深刻、代码级的认知。

    项目完全开源,代码和文档都在 GitHub 上了。

    如果你觉得有帮助,求个 Star 就是最大的鼓励!也欢迎随时提 Issue 或 PR 交流。

    谢谢大家!

    10 条回复    2025-11-10 14:18:52 +08:00
    sillydaddy
        1
    sillydaddy  
       12 小时 35 分钟前   1
    感谢分享。请问是什么开源协议呢?我想后面在做比特币的科普视频时,可能会引用你的代码(执行代码、给出运行结果)。
    prefect
        2
    prefect  
       12 小时 32 分钟前
    已加入书架(等想起来、有机会、可能、再学)
    NoCash
        3
    NoCash  
       12 小时 10 分钟前
    感谢制作,在看第一个脚本的时候,感觉有两处可以完善:
    1 、公钥 (Public Key): 由私钥通过椭圆曲线算法推算得出,可以公开。地址是公钥的另一种表现形式
    这里“地址”,如果是刚入门的小白可能不太清楚,可能会疑惑:怎么突然蹦出来说“地址”?楼主可以完善一下地址的解释

    2 、private_key = ecdsa.SigningKey.generate(curve=curve)
    方法里面,左边 curve 是形参名吧?右边是实参名,我认为楼主定义的时候是否应该给实参名相对于实参名给区别开来呢?不然阅读性上其实有问题
    Rainwater
        4
    Rainwater  
       12 小时 4 分钟前
    运行这些脚本会占电脑很多性能吗,不会的话可以摸鱼的时候试试
    freekindom
        5
    freekindom  
    OP
       11 小时 50 分钟前
    @sillydaddy GPL 总之你做科普视频,我非常欢迎。
    freekindom
        6
    freekindom  
    OP
       11 小时 48 分钟前
    @NoCash 多谢你的反馈。1 地址这个事情鼓励问 AI 2 curve=curve 这种在 python 开发的时候非常常见,是实践上经常使用的开发习惯。
    freekindom
        7
    freekindom  
    OP
       11 小时 48 分钟前
    @Rainwater 非常不占用性能……
    IndexOutOfBounds
        8
    IndexOutOfBounds  
       9 小时 13 分钟前   1
    亲自 star ,亲自留言
    dobelee
        9
    dobelee  
       9 小时 13 分钟前
    已收藏(等想起来、有机会、可能、再学)
    scyuns
        10
    scyuns  
       9 小时 10 分钟前
    已经 star 并且打算好好学习一下
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2479 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 21ms UTC 15:29 PVG 23:29 LAX 07:29 JFK 10:29
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86