<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Yao</title>
        <link>https://paragraph.com/@yao-9</link>
        <description>undefined</description>
        <lastBuildDate>Fri, 08 May 2026 11:08:38 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[保姆级教程：如何参与 Manta 可信设置登记？（内含如何处理refused报错）]]></title>
            <link>https://paragraph.com/@yao-9/manta-refused-2</link>
            <guid>KYIB93uV2ptavGqew8M6</guid>
            <pubDate>Sat, 17 Dec 2022 07:20:11 GMT</pubDate>
            <description><![CDATA[感谢 Manta社区成员 推特**@deepbluuest** 大力协助与支持。 1/ 需全程开启 VPN。\ 2/ 本文以苹果笔记本 MacBook 为例。\ 3/ 留 KMA 地址，之后可获得官方 NFT 奖励。 教程包含两部分内容：\ 1/ 正常步骤\ 2/ 正常步骤出现问题，如何处理？ 简中互联网因受官方防火墙不可抗力影响，在输出指令时，可能会出现如下图所示，接口连接被拒的问题。下文将提供解决该问题的办法。一、正常步骤1/ 在“应用程序”——“实用工具”里，打开“终端”。也可在右上角搜索框内直接搜索“终端”或“Terminal”。2/ 打开 https://docs.manta.network/docs/guides/TrustedSetup ，可直接点击红框位置，复制代码，粘贴进“终端”内，按下回车键。 若在末尾显示“DONE”，则可继续正常步骤。 若在末尾显示“Connection refused”，则受到了官方防火墙不可抗力影响。需查看第二部分教程。3/ 依次复制第二、第三段代码，粘贴进“终端”，按下回车键。4/ 之后按照要求输入推特账号、邮箱。（不会要求连接推特或...]]></description>
            <content:encoded><![CDATA[<p>感谢 Manta社区成员 推特**@deepbluuest** 大力协助与支持。</p><p>1/ 需全程开启 VPN。\ 2/ 本文以苹果笔记本 MacBook 为例。\ 3/ 留 KMA 地址，之后可获得官方 NFT 奖励。</p><p><strong>教程包含两部分内容：</strong>\ 1/ 正常步骤\ 2/ 正常步骤出现问题，如何处理？</p><p>简中互联网因受官方防火墙不可抗力影响，在输出指令时，可能会出现如下图所示，接口连接被拒的问题。下文将提供解决该问题的办法。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/4ac29b585a5c61726d10dc5cdb993a3996e5ab488acb1230a4ffd252d956b7f1.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">一、正常步骤</h2><p>1/ 在“应用程序”——“实用工具”里，打开“终端”。也可在右上角搜索框内直接搜索“终端”或“Terminal”。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/16832e80d656edf7f32ff8ebe7e826503966cc1c4fa6c9d14b6ee3f0896ef678.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>2/ 打开 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.manta.network/docs/guides/TrustedSetup">https://docs.manta.network/docs/guides/TrustedSetup</a> ，可直接点击红框位置，复制代码，粘贴进“终端”内，按下回车键。</p><p>若在末尾显示“DONE”，则可继续正常步骤。</p><p>若在末尾显示“Connection refused”，则受到了官方防火墙不可抗力影响。需查看第二部分教程。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/871fcec2e8b7f3a1a1cce31c43c5a3270b438e6692a612e423ff72f7b9430c69.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/3bc65cbe097f5f84bee95536316918af4ad78d9da9b35e9d3e4ee96484e60121.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>3/ 依次复制第二、第三段代码，粘贴进“终端”，按下回车键。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/77677625cc71b0c9b84b93e0f97ef41087bca2dd94dbf93c8a336b114672c440.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/31be7d196bb822c8a0acd0a42c0b1f925cb3b5063bb3cfeaecb332272ab3ddef.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>4/ 之后按照要求输入推特账号、邮箱。（不会要求连接推特或邮箱，不会泄露信息，仅作为之后识别身份，分发奖励用。  注意：推特账号是个人资料里 @后面的内容，不是推特昵称，如下图所示）</p><p>按下回车键，会得到邮箱、公钥、签名和私钥。私钥千万保存好，不要随意泄露。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/fd6edbebfe2fc55652ebbf3b8eedb0139feda901dce9c5bfa08812d33a813766.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/6a58b9ee85bcc441b4a8ebd56bfa14928eb9b24bc9391852a3c2be6e58304af0.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>5/ 打开登记表格 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mantanetwork.typeform.com/TrustedSetup">https://mantanetwork.typeform.com/TrustedSetup</a> ，\ 第一个问题：昵称\ 第二个问题：邮箱\ 第三个问题：签名 （如上图所示，终端内复制）\ 第四个问题：公钥 （如上图所示，终端内复制）\ 第五个问题：Discord ID （官方Discord链接：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/PRDBTChSsF%EF%BC%8C%E4%B9%9F%E5%8F%AF%E5%9C%A8%E5%AE%98%E7%BD%91https://www.manta.network/">https://discord.com/invite/PRDBTChSsF，也可在官网https://www.manta.network/</a> 底部找到）\ 第六个问题：推特账号\ 第七个问题：隐私对你来说为什么重要？ （随意发挥）\ 第八个问题：你的KMA地址 （用来接 NFT 空投奖励）</p><p>6/ 关于如何拥有 KMA 地址，你可以查看该文（<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/godotsancho.eth/zU6t4p3rnEFU84-YThCXsRMoUfDbYwO0kBAzRU-tWR4%EF%BC%89">https://mirror.xyz/godotsancho.eth/zU6t4p3rnEFU84-YThCXsRMoUfDbYwO0kBAzRU-tWR4）</a></p><p>需注意的是，你的钱包地址内，需保留至少1枚 KMA，否则根据 Kusama 网络规则，钱包或可能被删除。</p><p>目前，KMA 已上线 huobi、Kucoin、Gate、MEXC，可从交易平台购买并提到链上。</p><p>7/ 可信设置登记，已完成。之后等待官方第二阶段开启。</p><h2 id="h-connection-refused" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">二、Connection refused 报错处理</h2><p>1/ 同样打开“终端”，复制代码：</p><pre data-type="codeBlock" text="/bin/bash -c &quot;$(curl -fsSL https://gitee.com/wejectchan/brew/raw/master/install.sh)&quot;
"><code><span class="hljs-operator">/</span>bin<span class="hljs-operator">/</span>bash <span class="hljs-operator">-</span>c <span class="hljs-string">"$(curl -fsSL https://gitee.com/wejectchan/brew/raw/master/install.sh)"</span>
</code></pre><p>粘贴进去，按回车键。然后会要求你输入电脑密码 [Password]。直接输入，按回车。（输入密码过程中，密码本身不会在输入框内显示）</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/6ea431bf59f8ed7bfe1f04e32644dad2c6d74ff10808321639d1dff67f6ff9f1.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>2/ 遇到“<strong>RETURN/ENTER</strong>”，按下回车键。还需要输入一次密码，之后安装XCODE。安装完成后按下任意键。之后可输入代码</p><pre data-type="codeBlock" text="brew -v
"><code>brew <span class="hljs-operator">-</span>v
</code></pre><p>若显示 Homebrew 3.6.5，则表示安装成功。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/442450d3c95e1832f295b86d1535895f1641b70da143940ce019e01b251e661b.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/debe82350e6f826b6219f18921ca2fccf85329f1ddf1c7a9c17ab2cdc63ba329.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>3/ 输入代码</p><pre data-type="codeBlock" text="brew install rust
"><code></code></pre><p>按下回车键，安装 rust 环境。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/35e32e4eaac69513119829540bfc38594ef42eb07d2be1bfea891174806c3f6d.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>4/ rust 环境安装完成后，可输入</p><pre data-type="codeBlock" text="rustc –version
"><code></code></pre><p>检查 rust 是否安装成功</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/1ca3f14feaef804e8bd5026280d697fe8348c33022af2c9298c7777f3994ee87.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>5/ 输入代码</p><pre data-type="codeBlock" text="cd manta-rs
"><code><span class="hljs-built_in">cd</span> manta-rs
</code></pre><p>选择安装文件夹为“manta-rs”，再输入</p><pre data-type="codeBlock" text="cargo run --release --package manta-trusted-setup --all-features --bin groth16_phase2_client register
"><code>cargo run <span class="hljs-operator">-</span><span class="hljs-operator">-</span>release <span class="hljs-operator">-</span><span class="hljs-operator">-</span>package manta<span class="hljs-operator">-</span>trusted<span class="hljs-operator">-</span>setup <span class="hljs-operator">-</span><span class="hljs-operator">-</span>all<span class="hljs-operator">-</span>features <span class="hljs-operator">-</span><span class="hljs-operator">-</span>bin groth16_phase2_client register
</code></pre><p>会出现输入推特账号的指令。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/dd427f4f4ee5bf43a01bdd741ddb217298a62d9173e61aa698eda1b211cfc74d.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/95c4b325fdb51bec6453be21cf1766948fa3ec268458343ff7a9993e68319f74.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>6/ 之后按照要求输入推特账号、邮箱。（不会要求连接推特或邮箱，不会泄露信息，仅作为之后识别身份，分发奖励用。  注意：推特账号是个人资料里 @后面的内容，不是推特昵称，如下图所示）</p><p>按下回车键，会得到邮箱、公钥、签名和私钥。私钥千万保存好，不要随意泄露。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/fd6edbebfe2fc55652ebbf3b8eedb0139feda901dce9c5bfa08812d33a813766.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/6a58b9ee85bcc441b4a8ebd56bfa14928eb9b24bc9391852a3c2be6e58304af0.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>7/ 打开登记表格 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mantanetwork.typeform.com/TrustedSetup">https://mantanetwork.typeform.com/TrustedSetup</a> ，\ 第一个问题：昵称\ 第二个问题：邮箱\ 第三个问题：签名 （如上图所示，终端内复制）\ 第四个问题：公钥 （如上图所示，终端内复制）\ 第五个问题：Discord ID （官方Discord链接：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/PRDBTChSsF%EF%BC%8C%E4%B9%9F%E5%8F%AF%E5%9C%A8%E5%AE%98%E7%BD%91https://www.manta.network/">https://discord.com/invite/PRDBTChSsF，也可在官网https://www.manta.network/</a> 底部找到）\ 第六个问题：推特账号\ 第七个问题：隐私对你来说为什么重要？ （随意发挥）\ 第八个问题：你的KMA地址 （用来接 NFT 空投奖励）</p><p>8/ 关于如何拥有 KMA 地址，你可以查看该文（<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/godotsancho.eth/zU6t4p3rnEFU84-YThCXsRMoUfDbYwO0kBAzRU-tWR4%EF%BC%89">https://mirror.xyz/godotsancho.eth/zU6t4p3rnEFU84-YThCXsRMoUfDbYwO0kBAzRU-tWR4）</a></p><p>需注意的是，你的钱包地址内，需保留至少1枚 KMA，否则根据 Kusama 网络规则，钱包或可能被删除。</p><p>目前，KMA 已上线 huobi、Kucoin、Gate、MEXC，可从交易平台购买并提到链上。</p><p>9/ 可信设置登记，已完成。之后等待官方第二阶段开启。</p>]]></content:encoded>
            <author>yao-9@newsletter.paragraph.com (Yao)</author>
        </item>
        <item>
            <title><![CDATA[保姆级教程：如何参与 Manta 可信设置登记？（内含如何处理refused报错）]]></title>
            <link>https://paragraph.com/@yao-9/manta-refused</link>
            <guid>0OhTvqvSVDEufMCQJFYh</guid>
            <pubDate>Sat, 17 Dec 2022 07:14:34 GMT</pubDate>
            <description><![CDATA[感谢 Manta社区成员 推特**@deepbluuest** 大力协助与支持。 1/ 需全程开启 VPN。\ 2/ 本文以苹果笔记本 MacBook 为例。\ 3/ 留 KMA 地址，之后可获得官方 NFT 奖励。 教程包含两部分内容：\ 1/ 正常步骤\ 2/ 正常步骤出现问题，如何处理？ 简中互联网因受官方防火墙不可抗力影响，在输出指令时，可能会出现如下图所示，接口连接被拒的问题。下文将提供解决该问题的办法。一、正常步骤1/ 在“应用程序”——“实用工具”里，打开“终端”。也可在右上角搜索框内直接搜索“终端”或“Terminal”。2/ 打开 https://docs.manta.network/docs/guides/TrustedSetup ，可直接点击红框位置，复制代码，粘贴进“终端”内，按下回车键。 若在末尾显示“DONE”，则可继续正常步骤。 若在末尾显示“Connection refused”，则受到了官方防火墙不可抗力影响。需查看第二部分教程。3/ 依次复制第二、第三段代码，粘贴进“终端”，按下回车键。4/ 之后按照要求输入推特账号、邮箱。（不会要求连接推特或...]]></description>
            <content:encoded><![CDATA[<p>感谢 Manta社区成员 推特**@deepbluuest** 大力协助与支持。</p><p>1/ 需全程开启 VPN。\ 2/ 本文以苹果笔记本 MacBook 为例。\ 3/ 留 KMA 地址，之后可获得官方 NFT 奖励。</p><p><strong>教程包含两部分内容：</strong>\ 1/ 正常步骤\ 2/ 正常步骤出现问题，如何处理？</p><p>简中互联网因受官方防火墙不可抗力影响，在输出指令时，可能会出现如下图所示，接口连接被拒的问题。下文将提供解决该问题的办法。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/4ac29b585a5c61726d10dc5cdb993a3996e5ab488acb1230a4ffd252d956b7f1.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">一、正常步骤</h2><p>1/ 在“应用程序”——“实用工具”里，打开“终端”。也可在右上角搜索框内直接搜索“终端”或“Terminal”。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/16832e80d656edf7f32ff8ebe7e826503966cc1c4fa6c9d14b6ee3f0896ef678.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>2/ 打开 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.manta.network/docs/guides/TrustedSetup">https://docs.manta.network/docs/guides/TrustedSetup</a> ，可直接点击红框位置，复制代码，粘贴进“终端”内，按下回车键。</p><p>若在末尾显示“DONE”，则可继续正常步骤。</p><p>若在末尾显示“Connection refused”，则受到了官方防火墙不可抗力影响。需查看第二部分教程。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/871fcec2e8b7f3a1a1cce31c43c5a3270b438e6692a612e423ff72f7b9430c69.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/3bc65cbe097f5f84bee95536316918af4ad78d9da9b35e9d3e4ee96484e60121.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>3/ 依次复制第二、第三段代码，粘贴进“终端”，按下回车键。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/77677625cc71b0c9b84b93e0f97ef41087bca2dd94dbf93c8a336b114672c440.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/31be7d196bb822c8a0acd0a42c0b1f925cb3b5063bb3cfeaecb332272ab3ddef.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>4/ 之后按照要求输入推特账号、邮箱。（不会要求连接推特或邮箱，不会泄露信息，仅作为之后识别身份，分发奖励用。  注意：推特账号是个人资料里 @后面的内容，不是推特昵称，如下图所示）</p><p>按下回车键，会得到邮箱、公钥、签名和私钥。私钥千万保存好，不要随意泄露。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/fd6edbebfe2fc55652ebbf3b8eedb0139feda901dce9c5bfa08812d33a813766.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/6a58b9ee85bcc441b4a8ebd56bfa14928eb9b24bc9391852a3c2be6e58304af0.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>5/ 打开登记表格 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mantanetwork.typeform.com/TrustedSetup">https://mantanetwork.typeform.com/TrustedSetup</a> ，\ 第一个问题：昵称\ 第二个问题：邮箱\ 第三个问题：签名 （如上图所示，终端内复制）\ 第四个问题：公钥 （如上图所示，终端内复制）\ 第五个问题：Discord ID （官方Discord链接：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/PRDBTChSsF%EF%BC%8C%E4%B9%9F%E5%8F%AF%E5%9C%A8%E5%AE%98%E7%BD%91https://www.manta.network/">https://discord.com/invite/PRDBTChSsF，也可在官网https://www.manta.network/</a> 底部找到）\ 第六个问题：推特账号\ 第七个问题：隐私对你来说为什么重要？ （随意发挥）\ 第八个问题：你的KMA地址 （用来接 NFT 空投奖励）</p><p>6/ 关于如何拥有 KMA 地址，你可以查看该文（<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/godotsancho.eth/zU6t4p3rnEFU84-YThCXsRMoUfDbYwO0kBAzRU-tWR4%EF%BC%89">https://mirror.xyz/godotsancho.eth/zU6t4p3rnEFU84-YThCXsRMoUfDbYwO0kBAzRU-tWR4）</a></p><p>需注意的是，你的钱包地址内，需保留至少1枚 KMA，否则根据 Kusama 网络规则，钱包或可能被删除。</p><p>目前，KMA 已上线 huobi、Kucoin、Gate、MEXC，可从交易平台购买并提到链上。</p><p>7/ 可信设置登记，已完成。之后等待官方第二阶段开启。</p><h2 id="h-connection-refused" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">二、Connection refused 报错处理</h2><p>1/ 同样打开“终端”，复制代码：</p><pre data-type="codeBlock" text="/bin/bash -c &quot;$(curl -fsSL https://gitee.com/wejectchan/brew/raw/master/install.sh)&quot;
"><code><span class="hljs-operator">/</span>bin<span class="hljs-operator">/</span>bash <span class="hljs-operator">-</span>c <span class="hljs-string">"$(curl -fsSL https://gitee.com/wejectchan/brew/raw/master/install.sh)"</span>
</code></pre><p>粘贴进去，按回车键。然后会要求你输入电脑密码 [Password]。直接输入，按回车。（输入密码过程中，密码本身不会在输入框内显示）</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/6ea431bf59f8ed7bfe1f04e32644dad2c6d74ff10808321639d1dff67f6ff9f1.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>2/ 遇到“<strong>RETURN/ENTER</strong>”，按下回车键。还需要输入一次密码，之后安装XCODE。安装完成后按下任意键。之后可输入代码</p><pre data-type="codeBlock" text="brew -v
"><code>brew <span class="hljs-operator">-</span>v
</code></pre><p>若显示 Homebrew 3.6.5，则表示安装成功。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/442450d3c95e1832f295b86d1535895f1641b70da143940ce019e01b251e661b.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/debe82350e6f826b6219f18921ca2fccf85329f1ddf1c7a9c17ab2cdc63ba329.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>3/ 输入代码</p><pre data-type="codeBlock" text="brew install rust
"><code></code></pre><p>按下回车键，安装 rust 环境。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/35e32e4eaac69513119829540bfc38594ef42eb07d2be1bfea891174806c3f6d.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>4/ rust 环境安装完成后，可输入</p><pre data-type="codeBlock" text="rustc –version
"><code></code></pre><p>检查 rust 是否安装成功</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/1ca3f14feaef804e8bd5026280d697fe8348c33022af2c9298c7777f3994ee87.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>5/ 输入代码</p><pre data-type="codeBlock" text="cd manta-rs
"><code><span class="hljs-built_in">cd</span> manta-rs
</code></pre><p>选择安装文件夹为“manta-rs”，再输入</p><pre data-type="codeBlock" text="cargo run --release --package manta-trusted-setup --all-features --bin groth16_phase2_client register
"><code>cargo run <span class="hljs-operator">-</span><span class="hljs-operator">-</span>release <span class="hljs-operator">-</span><span class="hljs-operator">-</span>package manta<span class="hljs-operator">-</span>trusted<span class="hljs-operator">-</span>setup <span class="hljs-operator">-</span><span class="hljs-operator">-</span>all<span class="hljs-operator">-</span>features <span class="hljs-operator">-</span><span class="hljs-operator">-</span>bin groth16_phase2_client register
</code></pre><p>会出现输入推特账号的指令。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/dd427f4f4ee5bf43a01bdd741ddb217298a62d9173e61aa698eda1b211cfc74d.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/95c4b325fdb51bec6453be21cf1766948fa3ec268458343ff7a9993e68319f74.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>6/ 之后按照要求输入推特账号、邮箱。（不会要求连接推特或邮箱，不会泄露信息，仅作为之后识别身份，分发奖励用。  注意：推特账号是个人资料里 @后面的内容，不是推特昵称，如下图所示）</p><p>按下回车键，会得到邮箱、公钥、签名和私钥。私钥千万保存好，不要随意泄露。</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/fd6edbebfe2fc55652ebbf3b8eedb0139feda901dce9c5bfa08812d33a813766.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/6a58b9ee85bcc441b4a8ebd56bfa14928eb9b24bc9391852a3c2be6e58304af0.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>7/ 打开登记表格 <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mantanetwork.typeform.com/TrustedSetup">https://mantanetwork.typeform.com/TrustedSetup</a> ，\ 第一个问题：昵称\ 第二个问题：邮箱\ 第三个问题：签名 （如上图所示，终端内复制）\ 第四个问题：公钥 （如上图所示，终端内复制）\ 第五个问题：Discord ID （官方Discord链接：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://discord.com/invite/PRDBTChSsF%EF%BC%8C%E4%B9%9F%E5%8F%AF%E5%9C%A8%E5%AE%98%E7%BD%91https://www.manta.network/">https://discord.com/invite/PRDBTChSsF，也可在官网https://www.manta.network/</a> 底部找到）\ 第六个问题：推特账号\ 第七个问题：隐私对你来说为什么重要？ （随意发挥）\ 第八个问题：你的KMA地址 （用来接 NFT 空投奖励）</p><p>8/ 关于如何拥有 KMA 地址，你可以查看该文（<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/godotsancho.eth/zU6t4p3rnEFU84-YThCXsRMoUfDbYwO0kBAzRU-tWR4%EF%BC%89">https://mirror.xyz/godotsancho.eth/zU6t4p3rnEFU84-YThCXsRMoUfDbYwO0kBAzRU-tWR4）</a></p><p>需注意的是，你的钱包地址内，需保留至少1枚 KMA，否则根据 Kusama 网络规则，钱包或可能被删除。</p><p>目前，KMA 已上线 huobi、Kucoin、Gate、MEXC，可从交易平台购买并提到链上。</p><p>9/ 可信设置登记，已完成。之后等待官方第二阶段开启。</p>]]></content:encoded>
            <author>yao-9@newsletter.paragraph.com (Yao)</author>
        </item>
        <item>
            <title><![CDATA[Alchemy University 学习教程，Blockchain Cryptography]]></title>
            <link>https://paragraph.com/@yao-9/alchemy-university-blockchain-cryptography</link>
            <guid>CchkWP5puHfrudrltDRU</guid>
            <pubDate>Sat, 10 Dec 2022 18:28:08 GMT</pubDate>
            <description><![CDATA[估值102亿融资5.45亿的Alchemy 项目，大学每周任务逐步开始。持有大学生早期卡的伙伴们可以开始大学生活了： 了解更多，请关注作者：https://twitter.com/bitc2024 部分章节是看文章和视频的，自行查看哈，这里从实际操作开始。The First PrimitiveCryptographic Hashes1: Find Favorite Color 查看要求：输入：const { sha256 } = require("ethereum-cryptography/sha256"); const { toHex, utf8ToBytes } = require("ethereum-cryptography/utils"); // the possible colors that the hash could represent const COLORS = ['red', 'green', 'blue', 'yellow', 'pink', 'orange']; // given a hash, return the color that created...]]></description>
            <content:encoded><![CDATA[<p>估值102亿融资5.45亿的Alchemy 项目，大学每周任务逐步开始。持有大学生早期卡的伙伴们可以开始大学生活了：</p><p>了解更多，请关注作者：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/bitc2024">https://twitter.com/bitc2024</a></p><p>部分章节是看文章和视频的，自行查看哈，这里从实际操作开始。</p><h2 id="h-the-first-primitive" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The First Primitive</h2><h3 id="h-cryptographic-hashes" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Cryptographic Hashes</h3><p>1: Find Favorite Color</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/4b81e9ed6057b20e584a6b7f9039acba0992a9e921e22fc0e95e6a1139d2b653.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const { sha256 } = require(&quot;ethereum-cryptography/sha256&quot;);
const { toHex, utf8ToBytes } = require(&quot;ethereum-cryptography/utils&quot;);

// the possible colors that the hash could represent
const COLORS = [&apos;red&apos;, &apos;green&apos;, &apos;blue&apos;, &apos;yellow&apos;, &apos;pink&apos;, &apos;orange&apos;];

// given a hash, return the color that created the hash
function findColor(hash) {
    hex = toHex(hash);
    for(let i = 0; i &lt; COLORS.length; i++) {
        b = utf8ToBytes(COLORS[i]);
        h = sha256(b);
        if (toHex(h) === hex) {
            return COLORS[i];
        }
    }
}

module.exports = findColor;
"><code>const { <span class="hljs-built_in">sha256</span> } <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"ethereum-cryptography/sha256"</span>);
const { toHex, utf8ToBytes } <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"ethereum-cryptography/utils"</span>);

<span class="hljs-comment">// the possible colors that the hash could represent</span>
const COLORS <span class="hljs-operator">=</span> [<span class="hljs-string">'red'</span>, <span class="hljs-string">'green'</span>, <span class="hljs-string">'blue'</span>, <span class="hljs-string">'yellow'</span>, <span class="hljs-string">'pink'</span>, <span class="hljs-string">'orange'</span>];

<span class="hljs-comment">// given a hash, return the color that created the hash</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">findColor</span>(<span class="hljs-params">hash</span>) </span>{
    hex <span class="hljs-operator">=</span> toHex(hash);
    <span class="hljs-keyword">for</span>(let i <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i <span class="hljs-operator">&#x3C;</span> COLORS.<span class="hljs-built_in">length</span>; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
        b <span class="hljs-operator">=</span> utf8ToBytes(COLORS[i]);
        h <span class="hljs-operator">=</span> <span class="hljs-built_in">sha256</span>(b);
        <span class="hljs-keyword">if</span> (toHex(h) <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> hex) {
            <span class="hljs-keyword">return</span> COLORS[i];
        }
    }
}

module.exports <span class="hljs-operator">=</span> findColor;
</code></pre><p>点击运行。</p><h2 id="h-digital-signatures" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Digital Signatures</h2><h3 id="h-public-key-exercise" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Public Key Exercise</h3><p>1: Hash Message\ 查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/58d86b2e6833ea02155263630f9efc18c3163599744884588c552cf85d79f88f.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const { keccak256 } = require(&quot;ethereum-cryptography/keccak&quot;);
const { utf8ToBytes } = require(&quot;ethereum-cryptography/utils&quot;);

function hashMessage(message) {
    return keccak256(utf8ToBytes(message));
}

module.exports = hashMessage;
"><code>const { <span class="hljs-built_in">keccak256</span> } <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"ethereum-cryptography/keccak"</span>);
const { utf8ToBytes } <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"ethereum-cryptography/utils"</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">hashMessage</span>(<span class="hljs-params">message</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">keccak256</span>(utf8ToBytes(message));
}

module.exports <span class="hljs-operator">=</span> hashMessage;
</code></pre><p>点击运行。</p><p>2: Sign Message</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/9ca99c71cbfa2493b960ca09c579710a193b7a99945923fde9cb0ead5034652d.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const secp = require(&quot;ethereum-cryptography/secp256k1&quot;);
const hashMessage = require(&apos;./hashMessage&apos;);

const PRIVATE_KEY = &quot;6b911fd37cdf5c81d4c0adb1ab7fa822ed253ab0ad9aa18d77257c88b29b718e&quot;;

async function signMessage(msg) {
    return secp.sign(hashMessage(msg), PRIVATE_KEY, { recovered : true});
}

module.exports = signMessage;
"><code>const secp <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"ethereum-cryptography/secp256k1"</span>);
const hashMessage <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./hashMessage'</span>);

const PRIVATE_KEY <span class="hljs-operator">=</span> <span class="hljs-string">"6b911fd37cdf5c81d4c0adb1ab7fa822ed253ab0ad9aa18d77257c88b29b718e"</span>;

async <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">signMessage</span>(<span class="hljs-params"><span class="hljs-built_in">msg</span></span>) </span>{
    <span class="hljs-keyword">return</span> secp.sign(hashMessage(<span class="hljs-built_in">msg</span>), PRIVATE_KEY, { recovered : <span class="hljs-literal">true</span>});
}

module.exports <span class="hljs-operator">=</span> signMessage;
</code></pre><p>点击运行。</p><p>3: Recover Key</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/c2cd784bed637e63364a4aa0de0e61bfea3c1341f03a0cdacc86780d0953a18e.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const secp = require(&quot;ethereum-cryptography/secp256k1&quot;);
const hashMessage = require(&quot;./hashMessage&quot;);

async function recoverKey(message, signature, recoveryBit) {
    return secp.recoverPublicKey(hashMessage(message), signature, recoveryBit);
}

module.exports = recoverKey;
"><code>const secp <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"ethereum-cryptography/secp256k1"</span>);
const hashMessage <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"./hashMessage"</span>);

async <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">recoverKey</span>(<span class="hljs-params">message, signature, recoveryBit</span>) </span>{
    <span class="hljs-keyword">return</span> secp.recoverPublicKey(hashMessage(message), signature, recoveryBit);
}

module.exports <span class="hljs-operator">=</span> recoverKey;
</code></pre><p>点击运行。</p><p>4: Key to Address</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/bafc527f0d21a28e2c8e348926c8cbbedef0d1eaab0e9fb958195cb99e8d7565.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const secp = require(&quot;ethereum-cryptography/secp256k1&quot;);
const { keccak256 } = require(&quot;ethereum-cryptography/keccak&quot;);

function getAddress(publicKey) {
    return keccak256(publicKey.slice(1)).slice(-20);
}

module.exports = getAddress;
"><code>const secp <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"ethereum-cryptography/secp256k1"</span>);
const { <span class="hljs-built_in">keccak256</span> } <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">"ethereum-cryptography/keccak"</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getAddress</span>(<span class="hljs-params">publicKey</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">keccak256</span>(publicKey.slice(<span class="hljs-number">1</span>)).slice(<span class="hljs-number">-20</span>);
}

module.exports <span class="hljs-operator">=</span> getAddress;
</code></pre><p>点击运行。</p><h2 id="h-proof-of-work" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Proof of Work</h2><h3 id="h-proof-of-work-miner" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Proof of Work Miner</h3><p>1: Mempool</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/d620c3b18da9c8df37cb864e6182e886757119fc28c3fc18fb551ec3a5edf57a.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const SHA256 = require(&apos;crypto-js/sha256&apos;);
const TARGET_DIFFICULTY = BigInt(0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
const MAX_TRANSACTIONS = 10;

const mempool = [];
const blocks = [];

function addTransaction(transaction) {
    mempool.push(transaction);
}

function mine() {
}

module.exports = {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
"><code>const <span class="hljs-attr">SHA256</span> = require(<span class="hljs-string">'crypto-js/sha256'</span>)<span class="hljs-comment">;</span>
const <span class="hljs-attr">TARGET_DIFFICULTY</span> = BigInt(<span class="hljs-number">0</span>x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)<span class="hljs-comment">;</span>
const <span class="hljs-attr">MAX_TRANSACTIONS</span> = <span class="hljs-number">10</span><span class="hljs-comment">;</span>

const <span class="hljs-attr">mempool</span> = []<span class="hljs-comment">;</span>
const <span class="hljs-attr">blocks</span> = []<span class="hljs-comment">;</span>

function addTransaction(transaction) {
    mempool.push(transaction)<span class="hljs-comment">;</span>
}

function mine() {
}

<span class="hljs-attr">module.exports</span> = {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
}<span class="hljs-comment">;</span>
</code></pre><p>点击运行。</p><p>2: Mine Block</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/16a00a324de89ad60b65841843ee30320f6924732f38f6b71566c1d38b309b42.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const SHA256 = require(&apos;crypto-js/sha256&apos;);
const TARGET_DIFFICULTY = BigInt(0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
const MAX_TRANSACTIONS = 10;

const mempool = [];
const blocks = [];

function addTransaction(transaction) {
    mempool.push(transaction);
}

function mine() {
    let block = {id:blocks.length};
    blocks.push(block);
}

module.exports = {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
"><code>const SHA256 <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'crypto-js/sha256'</span>);
const TARGET_DIFFICULTY <span class="hljs-operator">=</span> BigInt(<span class="hljs-number">0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff</span>);
const MAX_TRANSACTIONS <span class="hljs-operator">=</span> <span class="hljs-number">10</span>;

const mempool <span class="hljs-operator">=</span> [];
const blocks <span class="hljs-operator">=</span> [];

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTransaction</span>(<span class="hljs-params">transaction</span>) </span>{
    mempool.<span class="hljs-built_in">push</span>(transaction);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mine</span>(<span class="hljs-params"></span>) </span>{
    let <span class="hljs-built_in">block</span> <span class="hljs-operator">=</span> {id:blocks.<span class="hljs-built_in">length</span>};
    blocks.<span class="hljs-built_in">push</span>(<span class="hljs-built_in">block</span>);
}

module.exports <span class="hljs-operator">=</span> {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
</code></pre><p>点击运行。</p><p>3: Block Hash</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/d39c1936df31ba27021c340e3ef85bdc485ab5c5ca03c817ee2bdb761a7628c1.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const SHA256 = require(&apos;crypto-js/sha256&apos;);
const TARGET_DIFFICULTY = BigInt(0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
const MAX_TRANSACTIONS = 10;

const mempool = [];
const blocks = [];

function addTransaction(transaction) {
    mempool.push(transaction);
}

function mine() {
    let block = {id:blocks.length};
    block.hash = SHA256(JSON.stringify(block));
    blocks.push(block);
}

module.exports = {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
"><code>const SHA256 <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'crypto-js/sha256'</span>);
const TARGET_DIFFICULTY <span class="hljs-operator">=</span> BigInt(<span class="hljs-number">0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff</span>);
const MAX_TRANSACTIONS <span class="hljs-operator">=</span> <span class="hljs-number">10</span>;

const mempool <span class="hljs-operator">=</span> [];
const blocks <span class="hljs-operator">=</span> [];

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTransaction</span>(<span class="hljs-params">transaction</span>) </span>{
    mempool.<span class="hljs-built_in">push</span>(transaction);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mine</span>(<span class="hljs-params"></span>) </span>{
    let <span class="hljs-built_in">block</span> <span class="hljs-operator">=</span> {id:blocks.<span class="hljs-built_in">length</span>};
    <span class="hljs-built_in">block</span>.hash <span class="hljs-operator">=</span> SHA256(JSON.stringify(<span class="hljs-built_in">block</span>));
    blocks.<span class="hljs-built_in">push</span>(<span class="hljs-built_in">block</span>);
}

module.exports <span class="hljs-operator">=</span> {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
</code></pre><p>点击运行。</p><p>4: Mine TX</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/f7fe9650ce0ab1ec39dd08b138cf1a58b9e2b78bee3d708019d636d606df65f4.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const SHA256 = require(&apos;crypto-js/sha256&apos;);
const TARGET_DIFFICULTY = BigInt(0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
const MAX_TRANSACTIONS = 10;

const mempool = [];
const blocks = [];

function addTransaction(transaction) {
    mempool.push(transaction);
}

function mine() {
    let block = {id:blocks.length, transactions:[]};
    if (mempool.length &gt; 0) {
        for (let i = 0; i &lt; MAX_TRANSACTIONS; i++) {
            block.transactions.push(mempool[0]);
            mempool.shift();
            if (mempool.length &lt;= 0) {
                break;
            }
        }
    }
    block.hash = SHA256(JSON.stringify(block));
    blocks.push(block);
}

module.exports = {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
"><code>const SHA256 <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'crypto-js/sha256'</span>);
const TARGET_DIFFICULTY <span class="hljs-operator">=</span> BigInt(<span class="hljs-number">0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff</span>);
const MAX_TRANSACTIONS <span class="hljs-operator">=</span> <span class="hljs-number">10</span>;

const mempool <span class="hljs-operator">=</span> [];
const blocks <span class="hljs-operator">=</span> [];

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTransaction</span>(<span class="hljs-params">transaction</span>) </span>{
    mempool.<span class="hljs-built_in">push</span>(transaction);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mine</span>(<span class="hljs-params"></span>) </span>{
    let <span class="hljs-built_in">block</span> <span class="hljs-operator">=</span> {id:blocks.<span class="hljs-built_in">length</span>, transactions:[]};
    <span class="hljs-keyword">if</span> (mempool.<span class="hljs-built_in">length</span> <span class="hljs-operator">></span> <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">for</span> (let i <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i <span class="hljs-operator">&#x3C;</span> MAX_TRANSACTIONS; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
            <span class="hljs-built_in">block</span>.transactions.<span class="hljs-built_in">push</span>(mempool[<span class="hljs-number">0</span>]);
            mempool.shift();
            <span class="hljs-keyword">if</span> (mempool.<span class="hljs-built_in">length</span> <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
                <span class="hljs-keyword">break</span>;
            }
        }
    }
    <span class="hljs-built_in">block</span>.hash <span class="hljs-operator">=</span> SHA256(JSON.stringify(<span class="hljs-built_in">block</span>));
    blocks.<span class="hljs-built_in">push</span>(<span class="hljs-built_in">block</span>);
}

module.exports <span class="hljs-operator">=</span> {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
</code></pre><p>点击运行。</p><p>5: Difficulty</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/dd20d904fdbdfad84fdfa959c369d340aae60e3853d85d72b83c97aa987e899d.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const SHA256 = require(&apos;crypto-js/sha256&apos;);
const TARGET_DIFFICULTY = BigInt(0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
const MAX_TRANSACTIONS = 10;

const mempool = [];
const blocks = [];

function addTransaction(transaction) {
    mempool.push(transaction);
}

function mine() {
    let block = {id:blocks.length, transactions:[]};
    if (mempool.length &gt; 0) {
        for (let i = 0; i &lt; MAX_TRANSACTIONS; i++) {
            block.transactions.push(mempool[0]);
            mempool.shift();
            if (mempool.length &lt;= 0) {
                break;
            }
        }
    }
    block.nonce = 0;
    block.hash = SHA256(JSON.stringify(block));
    let hash = block.hash;
    while (BigInt(`0x${hash}`) &gt;= TARGET_DIFFICULTY) {
        block.nonce = block.nonce + 1;
        block.hash = SHA256(JSON.stringify(block));
        hash = block.hash;
    }
    blocks.push(block);
}

module.exports = {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
"><code>const SHA256 <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'crypto-js/sha256'</span>);
const TARGET_DIFFICULTY <span class="hljs-operator">=</span> BigInt(<span class="hljs-number">0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff</span>);
const MAX_TRANSACTIONS <span class="hljs-operator">=</span> <span class="hljs-number">10</span>;

const mempool <span class="hljs-operator">=</span> [];
const blocks <span class="hljs-operator">=</span> [];

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTransaction</span>(<span class="hljs-params">transaction</span>) </span>{
    mempool.<span class="hljs-built_in">push</span>(transaction);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">mine</span>(<span class="hljs-params"></span>) </span>{
    let <span class="hljs-built_in">block</span> <span class="hljs-operator">=</span> {id:blocks.<span class="hljs-built_in">length</span>, transactions:[]};
    <span class="hljs-keyword">if</span> (mempool.<span class="hljs-built_in">length</span> <span class="hljs-operator">></span> <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">for</span> (let i <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i <span class="hljs-operator">&#x3C;</span> MAX_TRANSACTIONS; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
            <span class="hljs-built_in">block</span>.transactions.<span class="hljs-built_in">push</span>(mempool[<span class="hljs-number">0</span>]);
            mempool.shift();
            <span class="hljs-keyword">if</span> (mempool.<span class="hljs-built_in">length</span> <span class="hljs-operator">&#x3C;</span><span class="hljs-operator">=</span> <span class="hljs-number">0</span>) {
                <span class="hljs-keyword">break</span>;
            }
        }
    }
    <span class="hljs-built_in">block</span>.nonce <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;
    <span class="hljs-built_in">block</span>.hash <span class="hljs-operator">=</span> SHA256(JSON.stringify(<span class="hljs-built_in">block</span>));
    let hash <span class="hljs-operator">=</span> <span class="hljs-built_in">block</span>.hash;
    <span class="hljs-keyword">while</span> (BigInt(`0x${hash}`) <span class="hljs-operator">></span><span class="hljs-operator">=</span> TARGET_DIFFICULTY) {
        <span class="hljs-built_in">block</span>.nonce <span class="hljs-operator">=</span> <span class="hljs-built_in">block</span>.nonce <span class="hljs-operator">+</span> <span class="hljs-number">1</span>;
        <span class="hljs-built_in">block</span>.hash <span class="hljs-operator">=</span> SHA256(JSON.stringify(<span class="hljs-built_in">block</span>));
        hash <span class="hljs-operator">=</span> <span class="hljs-built_in">block</span>.hash;
    }
    blocks.<span class="hljs-built_in">push</span>(<span class="hljs-built_in">block</span>);
}

module.exports <span class="hljs-operator">=</span> {
    TARGET_DIFFICULTY,
    MAX_TRANSACTIONS,
    addTransaction, 
    mine, 
    blocks,
    mempool
};
</code></pre><p>点击运行。</p><h2 id="h-blockchain-network" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Blockchain Network</h2><h3 id="h-blockchain-data-structure" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Blockchain Data Structure</h3><p>1: Blocks and Hashes</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/ac4605f1ba2a030988a8831d31b586dfd3934d7fa0b4a827a473d4df223458d9.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const SHA256 = require(&apos;crypto-js/sha256&apos;);

class Block {
    constructor() {
    }
    toHash() {
        return SHA256(&quot;a string&quot;);
    }
}

module.exports = Block;
"><code><span class="hljs-keyword">const</span> <span class="hljs-title class_">SHA256</span> = <span class="hljs-built_in">require</span>(<span class="hljs-string">'crypto-js/sha256'</span>);

<span class="hljs-keyword">class</span> <span class="hljs-title class_">Block</span> {
    <span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) {
    }
    <span class="hljs-title function_">toHash</span>(<span class="hljs-params"></span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-title class_">SHA256</span>(<span class="hljs-string">"a string"</span>);
    }
}

<span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span> = <span class="hljs-title class_">Block</span>;
</code></pre><p>点击运行。</p><p>2: What&apos;s in a Hash?</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/250887f2df7fa422b916a171a44c5c262d72587d4866513843a8aaaba0c40ab6.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const SHA256 = require(&apos;crypto-js/sha256&apos;);

class Block {
    constructor(data) {
        this.data = data; 
    }
    toHash() {
        return SHA256(this.data.toString());
    }
}

module.exports = Block;
"><code>const SHA256 <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'crypto-js/sha256'</span>);

class Block {
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params">data</span>) </span>{
        <span class="hljs-built_in">this</span>.data <span class="hljs-operator">=</span> data; 
    }
    toHash() {
        <span class="hljs-keyword">return</span> SHA256(<span class="hljs-built_in">this</span>.data.toString());
    }
}

module.exports <span class="hljs-operator">=</span> Block;
</code></pre><p>点击运行。</p><p>3: The Genesis Block</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/dd04ad81dcf6b7d9afccbcd613bd52c4eddc620a93754fbdb6814554d93117d2.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const Block = require(&apos;./Block&apos;);

class Blockchain {
    constructor() {
        this.chain = [new Block(&quot;Genesis&quot;)];
    }
}

module.exports = Blockchain;
"><code>const Block <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./Block'</span>);

class Blockchain {
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">this</span>.chain <span class="hljs-operator">=</span> [<span class="hljs-keyword">new</span> Block(<span class="hljs-string">"Genesis"</span>)];
    }
}

module.exports <span class="hljs-operator">=</span> Blockchain;
</code></pre><p>点击运行。</p><p>4: Adding Blocks</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/cd75451d8e9dfe34e2d84f52fa0d6a67f257e5f6041f7bd60d0ca864988499b6.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const Block = require(&apos;./Block&apos;);

class Blockchain {
    constructor() {
        this.chain = [new Block(&quot;Genesis&quot;)];
    }

    addBlock(block) {
        this.chain.push(block);
    }
}

module.exports = Blockchain;
"><code>const Block <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./Block'</span>);

class Blockchain {
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">this</span>.chain <span class="hljs-operator">=</span> [<span class="hljs-keyword">new</span> Block(<span class="hljs-string">"Genesis"</span>)];
    }

    addBlock(<span class="hljs-built_in">block</span>) {
        <span class="hljs-built_in">this</span>.chain.<span class="hljs-built_in">push</span>(<span class="hljs-built_in">block</span>);
    }
}

module.exports <span class="hljs-operator">=</span> Blockchain;
</code></pre><p>点击运行。</p><p>5: Linking The Blocks</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/80e3e4cad43bc17222e74f8033fa57aefaa95d1cda6bc252be1fb7739e9146f8.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>这里需要改两个文件，首先是</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/4cc2398a7a68498157ccc9651c045040a802dbe4fb671db980e2955ac5a66703.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const Block = require(&apos;./Block&apos;);

class Blockchain {
    constructor() {
        this.chain = [new Block(&quot;Genesis&quot;)];
    }

    addBlock(block) {
        block.previousHash = this.chain[this.chain.length - 1].toHash();
        this.chain.push(block);
    }
}

module.exports = Blockchain;
"><code>const Block <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./Block'</span>);

class Blockchain {
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">this</span>.chain <span class="hljs-operator">=</span> [<span class="hljs-keyword">new</span> Block(<span class="hljs-string">"Genesis"</span>)];
    }

    addBlock(<span class="hljs-built_in">block</span>) {
        <span class="hljs-built_in">block</span>.previousHash <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.chain[<span class="hljs-built_in">this</span>.chain.<span class="hljs-built_in">length</span> <span class="hljs-operator">-</span> <span class="hljs-number">1</span>].toHash();
        <span class="hljs-built_in">this</span>.chain.<span class="hljs-built_in">push</span>(<span class="hljs-built_in">block</span>);
    }
}

module.exports <span class="hljs-operator">=</span> Blockchain;
</code></pre><p>然后改这个：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/7d3a5cbaf75f782e6fb71c5e1139cdec2a8280eb4d623c5dec1d3b8759f64421.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><pre data-type="codeBlock" text="const SHA256 = require(&apos;crypto-js/sha256&apos;);

class Block {
    constructor(data) {
        this.data = data;
    }
    toHash() {
        if (this.previousHash) {
            return SHA256(this.data.toString() + this.previousHash.toString());
        } else {
            return SHA256(this.data.toString());
        }
    }
}

module.exports = Block;
"><code>const SHA256 <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'crypto-js/sha256'</span>);

class Block {
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params">data</span>) </span>{
        <span class="hljs-built_in">this</span>.data <span class="hljs-operator">=</span> data;
    }
    toHash() {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.previousHash) {
            <span class="hljs-keyword">return</span> SHA256(<span class="hljs-built_in">this</span>.data.toString() <span class="hljs-operator">+</span> <span class="hljs-built_in">this</span>.previousHash.toString());
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> SHA256(<span class="hljs-built_in">this</span>.data.toString());
        }
    }
}

module.exports <span class="hljs-operator">=</span> Block;
</code></pre><p>点击运行。</p><p>6: Validating the Chain</p><p>查看要求：</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/74d4f2a7af06db3a49fb8e70964d0fef2f66d52b7781593b769fb6c428a55ef4.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>输入：</p><pre data-type="codeBlock" text="const Block = require(&apos;./Block&apos;);

class Blockchain {
    constructor() {
        this.chain = [new Block(&quot;Genesis&quot;)];
    }

    addBlock(block) {
        block.previousHash = this.chain[this.chain.length - 1].toHash();
        this.chain.push(block);
    }

    isValid() {
        for (let i = 0; i &lt; this.chain.length; i++) {
            if ((i + 1) &gt;= this.chain.length) {
                break;
            }
            if (this.chain[i].toHash().toString() !== this.chain[i+1].previousHash.toString()) {
                return false;
            }
        }
        return true;
    }
}

module.exports = Blockchain;
"><code>const Block <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./Block'</span>);

class Blockchain {
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-built_in">this</span>.chain <span class="hljs-operator">=</span> [<span class="hljs-keyword">new</span> Block(<span class="hljs-string">"Genesis"</span>)];
    }

    addBlock(<span class="hljs-built_in">block</span>) {
        <span class="hljs-built_in">block</span>.previousHash <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.chain[<span class="hljs-built_in">this</span>.chain.<span class="hljs-built_in">length</span> <span class="hljs-operator">-</span> <span class="hljs-number">1</span>].toHash();
        <span class="hljs-built_in">this</span>.chain.<span class="hljs-built_in">push</span>(<span class="hljs-built_in">block</span>);
    }

    isValid() {
        <span class="hljs-keyword">for</span> (let i <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i <span class="hljs-operator">&#x3C;</span> <span class="hljs-built_in">this</span>.chain.<span class="hljs-built_in">length</span>; i<span class="hljs-operator">+</span><span class="hljs-operator">+</span>) {
            <span class="hljs-keyword">if</span> ((i <span class="hljs-operator">+</span> <span class="hljs-number">1</span>) <span class="hljs-operator">></span><span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.chain.<span class="hljs-built_in">length</span>) {
                <span class="hljs-keyword">break</span>;
            }
            <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.chain[i].toHash().toString() <span class="hljs-operator">!</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.chain[i<span class="hljs-operator">+</span><span class="hljs-number">1</span>].previousHash.toString()) {
                <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
            }
        }
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
    }
}

module.exports <span class="hljs-operator">=</span> Blockchain;
</code></pre><p>点击运行。</p><p>以上第四周的教程学习完成。</p><p>未完待续……</p><p>了解更多，请关注作者：<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/bitc2024">https://twitter.com/bitc2024</a></p>]]></content:encoded>
            <author>yao-9@newsletter.paragraph.com (Yao)</author>
        </item>
    </channel>
</rss>