<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://sify21.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sify21.github.io/" rel="alternate" type="text/html" /><updated>2026-01-22T16:45:26+00:00</updated><id>https://sify21.github.io/feed.xml</id><title type="html">sify21’s Blog</title><subtitle>personal blogs</subtitle><author><name>FangYuan Si</name></author><entry><title type="html">量子计算对区块链和加密货币交易所的影响</title><link href="https://sify21.github.io/cryptography/blockchain/PostQuantumCryptography/" rel="alternate" type="text/html" title="量子计算对区块链和加密货币交易所的影响" /><published>2026-01-22T00:00:00+00:00</published><updated>2026-01-22T00:00:00+00:00</updated><id>https://sify21.github.io/cryptography/blockchain/PostQuantumCryptography</id><content type="html" xml:base="https://sify21.github.io/cryptography/blockchain/PostQuantumCryptography/"><![CDATA[<h1 id="量子计算对区块链和加密货币交易所的影响">量子计算对区块链和加密货币交易所的影响</h1>

<h2 id="底层密码学安全风险">底层密码学安全风险</h2>

<ol>
  <li>公钥密码体系完全失效(ECC,RSA)</li>
</ol>

<p>主流区块链依赖椭圆曲线签名(ECDSA / EdDSA)</p>

<p>传统公钥加密依赖的数学难题：</p>

<ul>
  <li>RSA: 大整数因式分解</li>
  <li>DH密码交换/DSA签名: 整数域的离散对数问题 （已知a，b，a^x=b，求x)</li>
  <li>ECC: 椭圆曲线上的离散对数问题 (已知Q，P，<code class="language-plaintext highlighter-rouge">a*P=Q</code>，求a)</li>
</ul>

<p>经典计算机的解决办法是guess and check</p>

<p>量子计算中的 Shor 算法可在多项式时间内破解因式分解和离散对数问题。这两个问题都能转化为周期发现问题
<a href="https://pennylane.ai/qml/demos/tutorial_period_finding">period-finding problem</a></p>

<p>比如分解大数N，随机找一个与N没公因数的a, 定义周期函数f(x) = a^x mod N，计算函数周期r</p>

<p>经典计算机需要一个个试(a^1 % N, a^2 %N, …, 直到结果重复)</p>

<p>量子计算机可同时计算所有x，一个寄存器保存所有x的叠加态(superposition)，另一个寄存器保存对应f(x)的叠加态；然后应用量子傅里叶变换找到周期r</p>

<p>得到周期后计算a^(r/2)−1 和 a^(r/2)+1 与 N的最大公约数(gcd)，大概率就能得到N的一个非平凡因子(non-trivial factor，1和自身叫平凡因子)</p>

<p>已知a^r ≡ 1 (mod N) , 令x=a^(r/2), x^2 ≡ 1 (mod N), (x−1)(x+1) ≡ 0 (mod N), 已知N=pq, (x−1)(x+1) ≡ 0 (mod p) 并且 (x−1)(x+1) ≡ 0 (mod q)</p>

<p>有50%概率成功50%概率失败，每次选择a都是独立随机事件，所以如果失败连续选择a可以快速降低整体的失败率（<code class="language-plaintext highlighter-rouge">50%*50%*...</code>）</p>

<p>破解rsa需要的量子比特
| RSA key | Logical qubits | Physical qubits |
| — | — | — |
| RSA-1024 | ~2,500 | ~2–10 million |
| RSA-2048 | ~5,000 | ~10–50 million |
| RSA-3072 | ~8,000 | ~20–80 million |</p>

<p>逻辑量子比特是能用于量子算法的可靠的量子比特，需要多个物理量子比特加上量子纠错才能组成一个逻辑量子比特</p>

<p>shor算法破解ecc和rsa效率相同，ecc的密钥长度更小反而更容易破解。</p>

<p>当前量子计算机量子比特数</p>
<ul>
  <li>IBM Nighthawk(夜鹰) 120</li>
  <li>谷歌 Willow  105</li>
  <li>合肥量超融合计算中心 180</li>
</ul>

<p>Q-Day(或Y2Q、Quantum Apocalypse): 即量子计算机破解公钥体系(rsa/ecc)的预测日期</p>

<p>行业普遍预估在2030~2040中晚期可以攻破RSA-2048</p>
<ul>
  <li>https://postquantum.com/q-day/q-day-y2q-rsa-broken-2030/</li>
  <li>https://thequantuminsider.com/2025/05/24/google-researcher-lowers-quantum-bar-to-crack-rsa-encryption/</li>
  <li>https://www.ibm.com/think/insights/prepare-your-organization-for-q-day</li>
  <li>https://www.paloaltonetworks.com/cyberpedia/what-is-q-day</li>
  <li>https://www.nokia.com/quantum/5-misconceptions-about-q-day/</li>
  <li>https://www.bankinfosecurity.com/countdown-to-q-day-a-30048</li>
</ul>

<p>一旦公钥暴露（UTXO 花费后或账户首次交易后），私钥可被量子攻击者推导，资金可被伪造签名直接转移</p>

<ol>
  <li>对称加密、哈希算法的等效安全性减半</li>
</ol>

<p>区块链大量使用哈希函数：</p>

<ul>
  <li>
    <p>SHA-256（Bitcoin）</p>
  </li>
  <li>
    <p>Keccak-256（Ethereum）</p>
  </li>
</ul>

<p>量子 Grover 算法是一种无结构搜索算法，能将暴力搜索复杂度从 2^n 降到 2^n/2 (平发根级加速)</p>

<p>振幅放大（Amplitude Amplification): 反复放大正确答案的振幅，同时压低其他状态的振幅</p>

<p>如SHA-256 在量子环境下等效安全性约为 128 bit</p>

<p>aes/哈希不构成紧急风险, 但未来新链可能会使用更长输出或多轮结构</p>

<h2 id="区块链账户模型与交易模型">区块链账户模型与交易模型</h2>

<ol>
  <li>UTXO vs 账户
UTXO（Bitcoin）: 只在花费时暴露公钥，未花费 UTXO 相对安全 (联系HD钱包衍生路径字段区分receive/change的合理性)</li>
</ol>

<p>注意这里指p2pkh，而bitcoin最新的地址类型p2tr支持两种花钱方式:key-path spend和script-path spend，其中key-path spend会把公钥放在scriptPubkey里，从量子安全角度会更早暴露攻击面(风险类似eth)；script-path spend仍可延迟暴露脚本</p>

<p>虽然p2tr的internal pubkey/ internal private key不会上链；但是上链/验签用的是tweaked pubkey，签名用的tweaked private key；所以量子攻击者不需要知道internal key</p>

<p>账户模型（Ethereum）: 公钥长期暴露(可从交易签名恢复)，量子攻击面更大</p>

<p>账户模型链在量子威胁下更早失效，主要针对EOA账户(合约账户由代码控制，没有私钥不需要签名)</p>

<ol>
  <li>共识机制PoW vs PoS</li>
</ol>

<p>PoW基于哈希计算，可以通过提升难度来吸收grover算法的优势</p>

<p>PoS依赖长期质押身份+私钥安全，验证者私钥属于长期资产，直接面临shor算法威胁</p>

<p>PoS缓解路径:</p>
<ul>
  <li>强制快速密钥轮换,降低公钥暴露时间</li>
  <li>用合约账户来托管验证逻辑，允许多算法、紧急冻结、社会恢复(类似多签，设置多个守护者Guardians，控制权可被 guardians 接管，怀疑私钥可能已被量子破解被攻击前撤权或切换到其他量子安全的密钥)</li>
  <li>进行后量子签名算法迁移(不可避免)</li>
</ul>

<ol>
  <li>交易延迟攻击</li>
</ol>

<p>攻击者可能：</p>
<ul>
  <li>
    <p>现在收集链上公钥与签名数据</p>
  </li>
  <li>
    <p>未来一旦量子计算成熟，回溯破解私钥</p>
  </li>
</ul>

<p>这对长期冷存储资产构成潜在威胁，需要尽量避免“长期未花费但公钥已暴露”的模型</p>

<h2 id="交易所功能演进">交易所功能演进</h2>
<ol>
  <li>抽象签名算法</li>
</ol>

<p>不要在业务层绑定 ECDSA / EdDSA</p>

<ol>
  <li>支持多算法并行</li>
</ol>

<p>同一交易支持多种签名，为未来升级留接口</p>

<p>当前主流抗量子签名算法，参考CNSA 2.0 和 <a href="https://csrc.nist.gov/Projects/post-quantum-cryptography/selected-algorithms">nist规范</a>：</p>
<ul>
  <li>ML-DSA (fips-204)，基于模块晶格(module-lattice based), 也被称为CRYSTALS-Dilithium</li>
  <li>SLH-DSA (fips-205), 基于无状态哈希(stateless-hash based)，也叫SPHINCE+</li>
  <li>Falcon，暂无对应fips规范，目前已有两个链采用(Algorand, Crypnut)</li>
</ul>

<ol>
  <li>地址生命周期管理</li>
</ol>

<ul>
  <li>
    <p>关注密钥轮换和资产迁移机制，量子威胁下及时把旧地址资产迁移到新的量子安全地址</p>
  </li>
  <li>
    <p>热地址：短期、自动轮换</p>
  </li>
  <li>
    <p>冷地址：可迁移、可废弃</p>
  </li>
  <li>
    <p>禁止“永久地址”</p>
  </li>
</ul>

<h2 id="当前公链进展">当前公链进展</h2>
<ul>
  <li>BTQ Technologies已实现一个基于ML-DSA量子安全的<a href="https://thequantuminsider.com/2026/01/12/btq-technologies-launches-bitcoin-quantum-testnet/">bitcoin分支</a>，部署了一个testnet(https://explorer.bitcoinquantum.com/)</li>
  <li>以太坊有5个阶段的演进路线图，抗量子签名迁移在最后一个阶段
    <ol>
      <li>The Merge: PoW → PoS 转换 (Beacon Chain 与 Mainnet 合并，验证者系统。2022已完成)</li>
      <li>The Surge: 扩容，降低交易费用 (Rollups、分片Sharding、Danksharding。Rollups 已广泛使用，Danksharding 逐步测试，2023-2026)</li>
      <li>The Scourge: MEV / 去中心化风险控制 (MEV-Boost、共识层改进。2024–2026持续迭代)</li>
      <li>The Verge: 状态优化与客户端轻量化 (Stateless Client、Verkle 树。2025–2027逐步集成到主网)</li>
      <li>The Splurge: 兜底阶段，其他对协议长期安全性与可维护性至关重要的改进集合 (抗量子签名迁移、协议清理、边缘案例修复。2026–2030+)</li>
    </ol>
  </li>
</ul>]]></content><author><name>FangYuan Si</name></author><category term="cryptography" /><category term="blockchain" /><summary type="html"><![CDATA[量子计算对区块链和加密货币交易所的影响]]></summary></entry><entry><title type="html">aws ubuntu server安装vnc</title><link href="https://sify21.github.io/linux/aws-ubuntu-vnc/" rel="alternate" type="text/html" title="aws ubuntu server安装vnc" /><published>2025-02-22T00:00:00+00:00</published><updated>2025-02-22T00:00:00+00:00</updated><id>https://sify21.github.io/linux/aws-ubuntu-vnc</id><content type="html" xml:base="https://sify21.github.io/linux/aws-ubuntu-vnc/"><![CDATA[<h1 id="ec2上">ec2上</h1>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo su
apt install xfce4
apt install tightvncserver
shutdown -r now #(不确定需不需要重启)
重连后用ubuntu身份就行
vncserver :1 #(生成默认配置)
vncserver -kill :1
vim ~/.vnc/xstartup
</code></pre></div></div>
<p>写入下边的内容</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/bin/sh

# Uncomment the following two lines for normal desktop:
unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc
unset DBUS_SESSION_BUS_ADDRESS
[ -x /etc/vnc/xstartup ] &amp;&amp; exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] &amp;&amp; xrdb $HOME/.Xresources
export XAUTHORITY=$HOME/.Xauthority

autocutsel -fork
startxfce4 &amp;

xsetroot -solid grey
vncconfig -iconic &amp;
# x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &amp;
# x-window-manager &amp;
</code></pre></div></div>
<p>其中，<code class="language-plaintext highlighter-rouge">export XAUTHORITY=$HOME/.Xauthority</code>是为了能够在vnc session下运行snap版firefox。至少需要2g内存才不卡</p>

<p>再次启动 <code class="language-plaintext highlighter-rouge">vncserver :1</code></p>
<h1 id="在本地">在本地</h1>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install gvncviewer
ssh -L 5901:localhost:5901 远程ec2地址
在另一个cmd里：
gvncviewer :1
</code></pre></div></div>]]></content><author><name>FangYuan Si</name></author><category term="linux" /><summary type="html"><![CDATA[ec2上 sudo su apt install xfce4 apt install tightvncserver shutdown -r now #(不确定需不需要重启) 重连后用ubuntu身份就行 vncserver :1 #(生成默认配置) vncserver -kill :1 vim ~/.vnc/xstartup 写入下边的内容 ``` #!/bin/sh]]></summary></entry><entry><title type="html">AppImage</title><link href="https://sify21.github.io/linux/appimage/" rel="alternate" type="text/html" title="AppImage" /><published>2024-08-05T00:00:00+00:00</published><updated>2024-08-05T00:00:00+00:00</updated><id>https://sify21.github.io/linux/appimage</id><content type="html" xml:base="https://sify21.github.io/linux/appimage/"><![CDATA[<h1 id="如何解压appimage">如何解压AppImage</h1>

<p>参考https://superuser.com/questions/1301583/how-can-i-extract-files-from-an-appimage</p>

<ul>
  <li>
    <p>判断AppImage format (type 1 或 type 2)</p>

    <p><code class="language-plaintext highlighter-rouge">./xxx.AppImage --appimage-help</code>. 如果有<code class="language-plaintext highlighter-rouge">--appimage-extract</code>选项, 说明是type 2，没有是type 1.</p>
  </li>
  <li>
    <p>方法1: type 2格式可以直接用–appimage-extract或–appimage-mount</p>

    <p>缺点是需要运行xxx.AppImage(不是直接运行content)，如果不信任的话最好不运行</p>
  </li>
  <li>
    <p>方法2: 用官方tool https://github.com/AppImage/AppImageKit. (目前只支持解压type1的)</p>

    <p>用appimagetool-x86_64.AppImage –list xxx.AppImage查看, 用appimagetool-x86_64.AppImage xxx.AppImage somedir/解压</p>
  </li>
  <li>
    <p>方法3: 手动挂载(获取–appimage-offset也是需要运行)</p>

    <p>type1: mount -o loop my.AppImage mountpoint/; umount mountpoint/</p>

    <p>type2: xxx.AppImage –appimage-offset; mount xxx.AppImage mountpoint/ -o offset=???; umount mountpoint/</p>
  </li>
</ul>

<h1 id="与desktop-集成">与desktop 集成</h1>

<p>https://github.com/TheAssassin/AppImageLauncher</p>

<p>这个工具会后台运行daemon。</p>

<p>可以用<code class="language-plaintext highlighter-rouge">./xxx.AppImage --appimage-extract</code>获得图标和desktopentry，然后手动集成</p>

<ol>
  <li>cp squashfs-root/xx.desktop ~/.local/share/applications</li>
  <li>cp -r squashfs-root/usr/share/icons/hicolor/* ~/.local/share/icons/hicolor/</li>
  <li>(optional)svg文件可以安装inkscape后手动生成icon (https://gist.github.com/dw72/24dc5891b35b3a7ed53737272ed10b2d)
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt; for size in 16 22 24 32 48 64 128 256 512 1024
for&gt; do
for&gt; inkscape -o ~/.local/share/icons/hicolor/${size}x${size}/apps/{.desktop文件中设置的名字}.png -w $size -h $size  /path/to/icon.svg
for&gt; done
&gt; xdg-icon-resource forceupdate
</code></pre></div>    </div>
  </li>
  <li>(optional)<code class="language-plaintext highlighter-rouge">xdg-desktop-menu forceupdate</code> <code class="language-plaintext highlighter-rouge">xdg-icon-resource forceupdate</code></li>
</ol>

<p>参考：</p>

<ul>
  <li>https://specifications.freedesktop.org/basedir-spec/latest/</li>
  <li>https://specifications.freedesktop.org/menu-spec/latest</li>
  <li>https://specifications.freedesktop.org/desktop-entry-spec/latest/recognized-keys.html</li>
  <li>https://specifications.freedesktop.org/icon-theme-spec/latest/</li>
</ul>

<h2 id="desktop-entry">desktop entry</h2>
<p><code class="language-plaintext highlighter-rouge">Exec</code>的<code class="language-plaintext highlighter-rouge">field codes expansion</code>只会执行一次。所以jmeter要支持直接打开和双击.jmx文件打开，可以如下设置：</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Exec=zsh -ic "file=%f;if test -n $file;then /home/sify/Applications/apache-jmeter-5.6.3/bin/jmeter -t \"$file\"; else /home/sify/Applications/apache-jmeter-5.6.3/bin/jmeter; fi"
</code></pre></div></div>
<p>zsh -ic是为了加载asdf环境，其中~/.asdf/plugins/java/set-java-home.zsh里的<code class="language-plaintext highlighter-rouge">asdf_update_java_home</code>手动调用了一次，因为<code class="language-plaintext highlighter-rouge">add-zsh-hook precmd</code>在zsh -ic时不会执行？</p>]]></content><author><name>FangYuan Si</name></author><category term="linux" /><summary type="html"><![CDATA[如何解压AppImage]]></summary></entry><entry><title type="html">web界面</title><link href="https://sify21.github.io/wasm/leptos/web/leptos/" rel="alternate" type="text/html" title="web界面" /><published>2024-03-23T00:00:00+00:00</published><updated>2024-03-23T00:00:00+00:00</updated><id>https://sify21.github.io/wasm/leptos/web/leptos</id><content type="html" xml:base="https://sify21.github.io/wasm/leptos/web/leptos/"><![CDATA[<p>项目需要界面选择了leptos，对web ui整体认知不足，一直踩坑，理下思路。</p>

<h1 id="reactive">reactive</h1>
<p>leptos把自己定义为一个reactive框架，与responsive区别</p>
<blockquote>
  <p>How do these differ? Responsiveness implies thoughtful action that considers long and short term outcome in the context of the situation at hand. Reactive behavior is immediate and without conscious thought, like a knee jerk response. Reactive behavior is often driven by the emotions.</p>
</blockquote>

<p>react是本能、条件反射，response是经过思考的回应。</p>

<p>在前端开发领域，react涉及两方面：信号(signal)和效果(effect)，主要是对用户的事件进行响应(如点击、滑动)。responsive是指不同ui尺寸下显示合适的界面布局(这个当然需要事先思考规划)，一般通过css控制。</p>

<h1 id="html-streaming">html streaming</h1>
<p>html文件本身也是可以流式传输的，浏览器接收一部分显示一部分。这个过程对于后台而言就是一个请求，返回html流。leptos ssr模式中，所有non-sync mode都是返回的html流，调用server_fn是html返回流的一部分。所以后端middleware(比如鉴权)应该放在返回html的端点上，而不是单独应用到server_fn所对应的<code class="language-plaintext highlighter-rouge">/api</code> endpoint。</p>

<h1 id="浏览器的进程线程模型">浏览器的进程/线程模型</h1>
<p>leptos本质是webassembly框架，它把所有信号、效果保存在Runtime结构体上。csr模式下Runtime是<code class="language-plaintext highlighter-rouge">std::thread::LocalKey</code>。</p>

<p><a href="https://www.chromium.org/developers">Chromium</a>的相关文档：</p>
<ul>
  <li>https://www.chromium.org/developers/how-tos/getting-around-the-chrome-source-code/</li>
  <li>https://docs.google.com/presentation/d/1ujV8LjIUyPBmULzdT2aT9Izte8PDwbJi</li>
  <li>https://www.chromium.org/developers/design-documents/multi-process-architecture/</li>
  <li>https://www.chromium.org/developers/design-documents/multi-process-resource-loading/</li>
  <li>https://chromium.googlesource.com/chromium/src/+/HEAD/docs/threading_and_tasks.md</li>
  <li>https://www.chromium.org/developers/design-documents/displaying-a-web-page-in-chrome/</li>
  <li>https://chromium.googlesource.com/chromium/src/+/HEAD/content/README.md</li>
</ul>

<p>MDN 相关文档：</p>
<ul>
  <li>https://developer.mozilla.org/en-US/docs/Glossary/Browsing_context (每个origin都是一个browsing context)</li>
  <li>https://developer.mozilla.org/en-US/docs/Web/API/Document</li>
  <li>https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe (embeded browsing context)</li>
</ul>

<p>总结下，chrome浏览器包含进程：</p>
<ul>
  <li>一个browser process, 包含2个线程：
    <ul>
      <li>main browser (UI) thread，包含对象：
        <ul>
          <li>1个Browser</li>
          <li>RenderProcessHost(每个render process对应一个)</li>
          <li>RenderFrameHost(在RenderProcessHost内部唯一)</li>
          <li>RenderWidgetHost</li>
        </ul>
      </li>
      <li>I/O thread，包含对象
        <ul>
          <li>多个IPC channel（用于与render process通信）</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>多个render process, 每个redner process包含2个线程：
    <ul>
      <li>main thread, 包含对象：
        <ul>
          <li>1个RenderProcess(与browser process通信)
            <ul>
              <li>1个RenderThread(用于cross-thread communication with RenderView)</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>render thread, 包含对象
        <ul>
          <li>1个RenderView(继承widget，代表一个tab view，可以包含一个或多个RenderFrame);RenderWidget(下拉框是唯一widget独立于view的情况)</li>
          <li>RenderFrame(默认1个, 存在<code class="language-plaintext highlighter-rouge">&lt;iframe&gt;</code>时有多个)
            <ul>
              <li>https://www.chromium.org/developers/design-documents/oop-iframes/</li>
              <li>https://issues.chromium.org/issues/40319720</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<h2 id="web-app的lifecycle">web app的lifecycle</h2>
<ul>
  <li>https://developer.chrome.com/docs/web-platform/page-lifecycle-api
<img src="/assets/images/page-lifecycle-api-state.svg" alt="page lifecycle" /></li>
</ul>

<h1 id="关于leptos-runtime">关于leptos Runtime</h1>

<h2 id="保存的数据类型">保存的数据类型</h2>
<p>Runtime使用slotmap存储，key类型有:</p>
<ul>
  <li>NodeId (ReactiveNode)</li>
  <li>TypeId (用于context api)</li>
  <li>ResourceId</li>
  <li>StoredValueId</li>
</ul>

<p>ScopeProperty有:</p>
<ul>
  <li>Trigger(NodeId)</li>
  <li>Signal(NodeId)</li>
  <li>Effect(Nodeid)</li>
  <li>Resource(ResourceId)</li>
  <li>StoredValue(StoredValueId)</li>
</ul>

<h2 id="关于runtime对象自身的存储">关于Runtime对象自身的存储</h2>
<p>gbj的youtube视频里实现的简易版本，他直接leak了一个Runtime。</p>

<p>在leptos实际的代码实现中, 定义了几个全局static</p>

<p>csr端：</p>
<ul>
  <li>RUNTIME (thread_local!, Runtime)
ssr端：</li>
  <li>TASK_RUNTIME (task_local!, RuntimeId)</li>
  <li>CURRENT_RUNTIME (thread_local!, RuntimeId)</li>
  <li>RUNTIMES (thread_local!, RuntimeId-&gt;Runtime)</li>
</ul>

<p>注意csr端RuntimeId是<code class="language-plaintext highlighter-rouge">unit struct</code>；ssr端RuntimeId是<code class="language-plaintext highlighter-rouge">slotmap::new_key_type!</code></p>

<h2 id="关于runtime对象自身的生存周期">关于Runtime对象自身的生存周期：</h2>
<blockquote>
  <p>@me: Hi I have a question about the lifetime of Runtime. In the browser (csr mode), Runtime is created as  a static thread_local! variable. Take chromium for example, I read some docs about its thread/process model https://www.chromium.org/developers/design-documents/multi-process-architecture/, and came to the conclusion that one browser tab means one render process, which has one main thread and one render thread, and leptos runs in the render thread. So Runtime is a thread_local! variable in the render thread. If a user navigates away from my leptos website to another website, under the same browser tab, does it mean that my website’s Runtime still exist in that render thread?</p>

  <p>@cperry6060: pretty sure if you navigate away from the document anything that ran in that document’s environment is discarded. In the same way that a force-refresh would recreate the entire app. Otherwise you would just always be leaking memory for every previous page you visited
thats a hard-core “im guessing” though. so ymmv and im stupid</p>

  <p>@me: I would assume the same. But can you find references in chromium docs that clearly confirm that assumption? for example it would clear all thread-locals of the render thread when a renderer loads another website?
Though I think that if a cleanup thing exists, it should be triggered when origin is changed. Loading different documents from the same origin shouldn’t trigger it.</p>

  <p>@gbj: You are overthinking this one, I think. The “thread” here is a “thread” in the sandboxed virtual machine running the WASM module, it is absolutely not the system thread chromium is using to render the page.</p>

  <p>@me: oh, does every WASM module gets its own virtual machine?</p>

  <p>@Bloo: for now at least
iirc they will allow wasm modules, something like that</p>

  <p>@gbj: Yes they are executed independently of one another
If the browser allowed websites you to leak arbitrary code across pages like this it would be an insane security hole — like if you visited a website that started running a bitcoin miner, and then navigated away to another page and the browser kept running the miner because you’re allowed to arbitrarily access memory in the actual process chromium is using to render?</p>

  <p>@me: yeah that shouldn’t happen</p>

  <p>@cperry6060: i think wasm is just always single-threaded as well right? Since it is basically just all backed by a simple stack of memory</p>

  <p>@remrevo2048: I mean it doesn’t have to be.
IIRC there are extensions for atomics and thread creation.
So depending on the runtime, you might even do normal multi-threading.</p>

  <p>@me: So if I refresh the page and request the wasm file again, it would mean a brand new Runtime is created for me?</p>

  <p>@remrevo2048: Yes.</p>

  <p>@me: Got it!</p>

  <p>@cperry6060: i just meant like the current version that most browsers use. That is cool about the extensions though</p>

  <p>@remrevo2048: I think the furthest thing in that direction is wasix, which is basically full posix in webassemby.
The future is exciting!</p>
</blockquote>

<p>总结：就跟js是运行在sandbox里一样，wasm也不会直接在render thread中运行，也会有它自己的sandbox</p>
<ul>
  <li>https://www.quora.com/What-is-meant-by-JavaScript-running-in-a-secure-sandbox</li>
  <li>https://www.oreilly.com/library/view/learning-javascript/0596527462/ch01s05.html (Learning JavaScript by Shelley Powers)</li>
</ul>

<p>在MDN的文档中也有提及： https://developer.mozilla.org/en-US/docs/WebAssembly/Concepts</p>
<blockquote>
  <ul>
    <li>Keep secure — WebAssembly is specified to be run in a safe, sandboxed execution environment. Like other web code, it will enforce the browser’s same-origin and permissions policies.</li>
  </ul>
</blockquote>

<h2 id="关于runtime中存储的数据的生存周期">关于Runtime中存储的数据的生存周期：</h2>

<ul>
  <li>https://discord.com/channels/1031524867910148188/1163432463817785375 (resource的lifetime)
    <blockquote>
      <p>@gbj: 
Like a signal, StoredValue, or any other type in the reactive system it (Resource) will be cleaned up either
1) When the scope it’s created in is cleaned up (i.e., when the portion of the tree it’s in “rerenders”), or
2) when you call .dispose() to dispose it early</p>

      <p>If you are creating a large number of resource in a high/global scope, then yes they are leaking unless you dispose them</p>

      <p>Take a look at leptos_query if you haven’t already. Otherwise, you can either create the resources at the right scope for them to be disposed automatically, or dispose of them manually</p>

      <p>@me:
Hi @gbj , are there online docs about how scopeworks in leptos? like how scopes get created, and how Signals\StoredValue get bounded to them. If not, where should I look into the source code?</p>

      <p>@gbj:
Sure. It’s not super complicated. Every effect or memo is an Owner. It owns everything created while it is running. When it reruns, it disposes of everything from the last time (and runs again, creating them all again)</p>

      <p>Most of it lives around here: https://github.com/leptos-rs/leptos/blob/3e93a686f45657c6d2e86790c2b7e8fcc574df4b/leptos_reactive/src/runtime.rs#L193</p>

      <p>Generally speaking this will only come up if you’re doing things like creating signals and trying to store them somewhere higher up in the component tree, or in a global, but then the effect under which they were created reruns</p>
    </blockquote>
  </li>
  <li>https://discord.com/channels/1031524867910148188/1121455457853251725 (#[component]的lifecycle)
    <blockquote>
      <p>@gbj: 
See also https://docs.rs/leptos/0.3.1/leptos/struct.HtmlElement.html#method.on_mount</p>

      <p>There is no component lifecycle per se, because components run once. However, as you’ve noticed they run before the DOM elements they return are actually mounted (which makes sense, as they return them and the parent mounts them where it wants them). Create effect + request animation frame (to delay a tick until it’s actually been mounted) or on\mount both work. In the other direction, on_cleanup</p>
    </blockquote>
  </li>
</ul>]]></content><author><name>FangYuan Si</name></author><category term="wasm" /><category term="leptos" /><category term="web" /><summary type="html"><![CDATA[项目需要界面选择了leptos，对web ui整体认知不足，一直踩坑，理下思路。]]></summary></entry><entry><title type="html">rust-gdb</title><link href="https://sify21.github.io/rust,%20gdb/rust-gdb/" rel="alternate" type="text/html" title="rust-gdb" /><published>2024-01-10T00:00:00+00:00</published><updated>2024-01-10T00:00:00+00:00</updated><id>https://sify21.github.io/rust,%20gdb/rust-gdb</id><content type="html" xml:base="https://sify21.github.io/rust,%20gdb/rust-gdb/"><![CDATA[<h2 id="gdb中可以调用python脚本">gdb中可以调用python脚本：</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python 
help(gdb.parse_and_eval)
help(gdb.execute)
end
</code></pre></div></div>

<h2 id="gdb中可以自定义command跟上边python结合可以很灵活">gdb中可以自定义command，跟上边python结合可以很灵活</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>define display_string_pointer_vec
&gt;python
 &gt;i = gdb.parse_and_eval("string_pointer_vec.len")
 &gt;for j in range(0, i):
 &gt;  gdb.execute(f"p *string_pointer_vec.buf.ptr.pointer.pointer[{j}]")
 &gt;end
&gt;end
</code></pre></div></div>]]></content><author><name>FangYuan Si</name></author><category term="rust, gdb" /><summary type="html"><![CDATA[gdb中可以调用python脚本：]]></summary></entry><entry><title type="html">rust程序内存泄漏问题定位</title><link href="https://sify21.github.io/rust/rust-memory-leak/" rel="alternate" type="text/html" title="rust程序内存泄漏问题定位" /><published>2023-12-23T00:00:00+00:00</published><updated>2023-12-23T00:00:00+00:00</updated><id>https://sify21.github.io/rust/rust-memory-leak</id><content type="html" xml:base="https://sify21.github.io/rust/rust-memory-leak/"><![CDATA[<p>一个rust项目出现内存占用不断增大的问题，怀疑代码中有内存泄漏。</p>

<p>memory leak只会发生在heap allocation过程中。stack上的local variable是会随着stack销毁的，如果stack上留存只会是stack overflow。</p>

<p>jvm有heapdump。c/c++最好使用一个allocator以获得stacktrace。</p>

<p>目前主流的memory allocator有jemalloc(facebook维护，firefox大量使用), tcmalloc(google维护)，mimalloc(微软新出的，据说提升很大)。</p>

<p>这里使用了tikv维护的一个crate: jemallocator，rustc之前默认用的就是这个，后来剔除了，让用户可以自己设global allocator。</p>

<p>用heap profile的功能需要开启feature profiling(jemalloc的opt.prof需要–enable-prof)。我配成了只为linux target使用（cross编译windows和apple报错，可能要调整构建容器）。</p>

<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">[target.'cfg(target_os</span> <span class="p">=</span> <span class="s">"linux"</span><span class="err">)</span><span class="s">'.dependencies]</span><span class="err">
</span><span class="py">tikv-jemallocator</span> <span class="p">=</span> <span class="s">"0.5"</span>

<span class="nn">[features]</span>
<span class="py">profiling</span> <span class="p">=</span> <span class="nn">["tikv-jemallocator/profiling"]</span> <span class="c"># 或者可以不加这个，在构建的时候直接指定 --features tikv-jemallocator/profiling</span>
</code></pre></div></div>

<p>rust目前还没有target specific feature，但既然dependency已经是target specific的了，所以如果没有这个dependency开这个feature也没啥影响。</p>

<p>注意在rust项目构建完成后，会在对应target目录的build/tikv-jemalloc-sys-??/out/build/bin目录下包含对应jeprof脚本程序。最好用这个脚本。自己从jemalloc源码构建的可能跟rust构建用的版本不一样。</p>

<h3 id="jemalloc配置">jemalloc配置</h3>
<p>jemalloc配置文档：http://jemalloc.net/jemalloc.3.html</p>
<blockquote>
  <h3 id="tuning">TUNING</h3>

  <p>Once, when the first call is made to one of the memory allocation routines, the allocator initializes its internals based in part on various options that can be specified at compile- or run-time.</p>

  <p>The string specified via –with-malloc-conf, the string pointed to by the global variable malloc_conf, the “name” of the file referenced by the symbolic link named /etc/malloc.conf, and the value of the environment variable MALLOC_CONF, will be interpreted, in that order, from left to right as options. Note that malloc_conf may be read before main() is entered, so the declaration of malloc_conf should specify an initializer that contains the final value to be read by jemalloc. –with-malloc-conf and malloc_conf are compile-time mechanisms, whereas /etc/malloc.conf and MALLOC_CONF can be safely set any time prior to program invocation.</p>

  <p>An options string is a comma-separated list of option:value pairs. There is one key corresponding to each opt.* mallctl (see the MALLCTL NAMESPACE section for options documentation). For example, abort:true,narenas:1 sets the opt.abort and opt.narenas options. Some options have boolean values (true/false), others have integer values (base 8, 10, or 16, depending on prefix), and yet others have raw string values.</p>
</blockquote>

<p>注意在<code class="language-plaintext highlighter-rouge">MALLCTL NAMESPACE</code>中的rw, 指的是运行时调用mallctl<em>()是否可读写。<code class="language-plaintext highlighter-rouge">TUNING</code>中的opt.</em>是启动时的配置，这些基本都是r-, 这些参数在程序启动时可以用来设置初始值，在运行阶段就不能通过mallctl*()修改了。</p>

<h3 id="tikv-jemallocator配置">tikv-jemallocator配置</h3>
<ul>
  <li>
    <p>feature: profiling 和 stats 分别对应构建文档:https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md 中的–enable-prof和–disable-stats</p>
  </li>
  <li>
    <p>unprefixed_malloc_on_supported_platforms默认不开启，相当于–with-jemalloc-prefix=<em>rjem</em></p>
  </li>
</ul>

<h3 id="jemalloc的heap-dump文件格式">jemalloc的heap dump文件格式</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>heap_v2/524288
  t*: 28106: 56637512 [0: 0]
  [...]
  t3: 352: 16777344 [0: 0]
  [...]
  t99: 17754: 29341640 [0: 0]
  [...]
@ 0x5f86da8 0x5f5a1dc [...] 0x29e4d4e 0xa200316 0xabb2988 [...]
  t*: 13: 6688 [0: 0]
  t3: 12: 6496 [0: 0]
  t99: 1: 192 [0: 0]
[...]

MAPPED_LIBRARIES:
[...]

The following matches the above heap profile, but most tokens are replaced with &lt;description&gt; to indicate descriptions of the corresponding fields.

&lt;heap_profile_format_version&gt;/&lt;mean_sample_interval&gt;
  &lt;aggregate&gt;: &lt;curobjs&gt;: &lt;curbytes&gt; [&lt;cumobjs&gt;: &lt;cumbytes&gt;]
  [...]
  &lt;thread_3_aggregate&gt;: &lt;curobjs&gt;: &lt;curbytes&gt; [&lt;cumobjs&gt;: &lt;cumbytes&gt;]
  [...]
  &lt;thread_99_aggregate&gt;: &lt;curobjs&gt;: &lt;curbytes&gt; [&lt;cumobjs&gt;: &lt;cumbytes&gt;]
  [...]
@ &lt;top_frame&gt; &lt;frame&gt; [...] &lt;frame&gt; &lt;frame&gt; &lt;frame&gt; [...]
  &lt;backtrace_aggregate&gt;: &lt;curobjs&gt;: &lt;curbytes&gt; [&lt;cumobjs&gt;: &lt;cumbytes&gt;]
  &lt;backtrace_thread_3&gt;: &lt;curobjs&gt;: &lt;curbytes&gt; [&lt;cumobjs&gt;: &lt;cumbytes&gt;]
  &lt;backtrace_thread_99&gt;: &lt;curobjs&gt;: &lt;curbytes&gt; [&lt;cumobjs&gt;: &lt;cumbytes&gt;]
[...]

MAPPED_LIBRARIES:
&lt;/proc/&lt;pid&gt;/maps&gt;
</code></pre></div></div>
<p>objects可能是指calloc: Allocates memory for an array of <strong>num</strong> objects of <strong>size</strong> and initializes all bytes in the allocated storage to zero. 最终分配的bytes= <strong>num</strong> * <strong>size</strong></p>

<p>对应的malloc可能就看成了object count为1。</p>

<p>文件最后的MAPPED_LIBRARIES包含可执行文件的绝对路径。所以jeprof工具应当在生成dump文件的机器上本地跑。如果把dump文件拿到本地来分析，需要手动需改下文件路径到本地的可执行文件路径。</p>

<p>Jason Evans本人对数据的解释（http://jemalloc.net/mailman/jemalloc-discuss/2015-November/001205.html）</p>
<blockquote>
  <p>The two types of stats are:</p>
  <ul>
    <li>Current bytes/objects, aka “inuse” in pprof/jeprof terminology.  These are counts of how many sampled objects currently exist.  Use these stats to understand current memory usage.</li>
    <li>Cumulative bytes/objects, aka “alloc” in pprof/jeprof terminology.  These are counts of how many sampled bytes/objects have existed since the most recent stats reset (process start or “prof.reset” mallctl call).  Use these stats to understand total allocation volume.</li>
  </ul>

  <p>dumps are always based on the most recent stats reset (process start or “prof.reset” mallctl call).  You can view incremental differences between two dumps by using the –base option to jeprof</p>

  <p>opt.lg_prof_interval is merely a dump triggering mechanism.  opt.prof_accum controls whether cumulative stats are collected at all.</p>

  <p>Take the following function as an example, run with MALLOC_CONF=prof:true,prof_accum:true :</p>
  <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>void g(void *p);

void f(void) {
    unsigned i;

    for (i = 0; i &lt; (1U &lt;&lt; 20); i++) {
        void *p = malloc(1U &lt;&lt; 30);
        if (i == (1U &lt;&lt; 19)) {
            mallctl("prof.dump", NULL, NULL, NULL, 0); /* A */
            mallctl("prof.reset", NULL, NULL, NULL, 0);
            mallctl("prof.dump", NULL, NULL, NULL, 0); /* B */
        }
        if (p != NULL) {
            g(p);
            free(p);
        }
    }
    mallctl("prof.dump", NULL, NULL, NULL, 0); /* C */
}
</code></pre></div>  </div>
  <p>What will the heap profiling stats (as interpreted by jeprof) dumped at A, B, and C say regarding the malloc() site in f()?</p>

  <p>A:</p>
  <ul>
    <li>Current: ~1 object, ~2^30 bytes</li>
    <li>Cumulative: ~2^19 objects, ~2^49 bytes</li>
  </ul>

  <p>B:</p>
  <ul>
    <li>Current: 0 objects, 0 bytes</li>
    <li>Cumulative: 0 objects, 0 bytes</li>
  </ul>

  <p>C:</p>
  <ul>
    <li>Current: 0 objects, 0 bytes</li>
    <li>Cumulative: ~2^19 objects, ~2^49 bytes</li>
  </ul>

  <p>opt.prof_accum controls whether jemalloc maintains the cumulative stats.  With MALLOC_CONF=prof:true,prof_accum:false, you will get no cumulative stats at all, no matter when/whether any resets occurred.</p>
</blockquote>

<p>也就是说free会将current数据减少，cumulative数据会一直增加。reset是所有数据的计数起点。</p>

<p>注意这里的cumulative stats，和jeprof的top表头中的flat/cum是两个概念。flat/cum意思是: 纯自己的 vs 包含内部调用的其他函数的。</p>

<h3 id="jeprof工具使用flamegraph">jeprof工具使用（flamegraph）</h3>
<blockquote>
  <p>Note that each of the .heap files are full snapshots instead of increments. Hence, simply pick the latest file (or any historical snapshot).</p>

  <p>jeprof is a utility provided by jemalloc to analyze heap dump files. It reads both the executable binary and the heap dump to get a full heap profiling.</p>

  <p>Note that the heap profiler dump file must be analyzed along with exactly the same binary that it generated from.</p>
</blockquote>

<p>jeprof –collapsed –show_bytes binary_file heap_file &gt; heap_file.collapsed</p>

<p>https://github.com/brendangregg/FlameGraph</p>

<p>可以直接丢到这个网页上看https://www.speedscope.app/, 或者</p>

<p>./flamegraph.pl –colors=mem –countname=bytes heap_file.collapsed &gt; flamegraph.svg</p>

<h3 id="tokio-console">tokio-console</h3>
<p>这个工具是基于tokio/tracing做的，需要async runtime支持tracing（目前只有tokio支持）。开启这个还挺麻烦的。需要tokio开启tracing feature; 设置RUSTFLAGS=”–cfg tokio_unstable”; 代码中调用console_subscriber::init()。</p>

<p>tracing是需要在代码中手动设置的(#[instrument])，跟我期待的debugger有差距。</p>

<h3 id="memory-profile原理">memory profile原理</h3>
<p>A heap profiler associates memory allocations with the callstacks on which they happen.It is prohibitively expensive to handle every allocation done by a program, so the Android Heap Profiler employs a sampling approach that handles a statistically meaningful subset of allocations.</p>
<h4 id="cpu-profile-sample">cpu profile sample</h4>
<h4 id="程序运行时如何获取stacktrace">程序运行时如何获取stacktrace</h4>
<p>在大多数编程语言中，可执行程序获取调用堆栈（call stacktrace）通常通过特定的语言特性或库函数来实现。不同的编程语言可能有不同的方法来获取调用堆栈，但通常都可以通过以下方式之一：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>语言特性或内置函数： 很多编程语言提供了直接获取调用堆栈的内置函数或语言特性。例如，在Java中，可以使用Thread.currentThread().getStackTrace()方法来获取堆栈跟踪信息。

调试器和异常处理器： 调试器通常能够提供堆栈跟踪信息。当程序抛出异常时，异常处理器通常会记录堆栈跟踪以便于调试。通过捕获异常或利用调试器的功能，程序可以获取堆栈信息。

第三方库或工具： 有些编程语言可能需要使用第三方库或工具来获取堆栈跟踪。例如，Python中的traceback模块可以用于获取堆栈信息。
</code></pre></div></div>

<p>调用堆栈信息通常包括当前执行的函数、调用该函数的函数，以及整个调用链的信息。这些信息对于调试和定位程序中的问题非常有用，能够帮助开发人员追踪程序的执行流程。</p>

<p>不同编程语言中获取调用堆栈的实现方式可能会有所不同，但通常的实现原理大致相似。以下是一般情况下的实现方式：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>保存调用信息： 当函数被调用时，程序会在内存中创建一个称为堆栈帧（stack frame）的数据结构，用于保存该函数的信息，如函数参数、局部变量以及函数执行完后应该返回的位置等。这些堆栈帧按照调用顺序依次堆叠在一起，形成调用堆栈。

语言运行时或编译器支持： 许多编程语言的运行时环境或编译器会提供一些特殊的数据结构或机制，用于跟踪和管理调用堆栈。这些机制可能包括在堆栈帧中添加额外信息、记录函数调用和返回、管理异常处理等。

内置函数或API： 语言提供了特定的函数或API，允许程序访问当前调用堆栈的信息。这些函数可以访问堆栈中的堆栈帧，并从中提取有关函数调用的信息，例如函数名、文件名、行号等。

符号表和元数据： 有些语言会使用符号表或元数据来存储函数和变量的信息，包括函数名、文件名、行号等。调用堆栈信息的获取可能涉及到解析这些符号表或元数据，以获取更多有关函数调用的信息。
</code></pre></div></div>

<p>总的来说，调用堆栈信息的获取通常依赖于语言的运行时环境、编译器支持以及提供的特殊函数或API。这些机制的具体实现可能因编程语言而异，但都旨在提供对程序执行过程中函数调用链的跟踪和管理。</p>

<p>大多数通用的 CPU 指令集并没有直接提供获取当前调用堆栈的指令。调用堆栈的概念是高级编程语言和运行时环境层面的概念，而并非在 CPU 指令集级别的概念。</p>

<p>CPU 指令集主要负责执行基本的操作，例如算术运算、数据移动、逻辑操作等，它们与更高层次的抽象概念（比如函数调用、堆栈跟踪）通常是分离的。</p>

<p>然而，在特定的架构中，有些指令集可能提供了某种形式的支持，使得在硬件级别上可以获取部分堆栈信息。例如，有些 CPU 架构可能提供指令，可以读取当前栈指针（stack pointer）或帧指针（frame pointer），这些指针是用于管理堆栈的重要指示器。但是，这些信息通常并不足以直接获取完整的调用堆栈信息，例如函数名、文件名、行号等高级调试信息。</p>

<p>获取完整的调用堆栈信息通常需要在更高级别的抽象层（比如编程语言的运行时环境或调试器）中实现。这些抽象层会利用 CPU 提供的基本指令以及其他运行时环境的信息，来构建和管理完整的调用堆栈信息。</p>

<p>backtrace 模块在 Rust 中是一个提供调用堆栈信息的标准库。其内部的实现主要依赖于底层的系统功能，比如使用操作系统提供的原生功能或者平台相关的工具来获取调用堆栈信息。</p>

<p>在底层，backtrace 模块通常使用了平台相关的调试信息，比如在 Linux 上可能使用了 libunwind 库，而在 Windows 上可能使用了 DbgHelp。这些库提供了对程序运行时调用堆栈信息的访问。</p>

<p>一般来说，这些库可以让 Rust 或其他编程语言的程序获取当前线程的调用堆栈信息。具体的实现会依赖于操作系统和硬件平台，因为不同的系统和架构可能有不同的方式来处理调用堆栈的信息。</p>

<p>backtrace 模块提供了一个统一的接口来获取调用堆栈信息，而底层的实现则依赖于系统和平台相关的功能来实际获取这些信息。这种抽象允许 Rust 在不同的平台上获取调用堆栈信息而无需更改程序的代码。</p>

<p>libunwind 是一个用于访问程序运行时调用堆栈信息的库，它提供了对堆栈展开（stack unwinding）的支持，允许程序在运行时获取调用堆栈的信息。</p>

<p>主要功能包括：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>堆栈展开： 能够在程序运行时追踪当前线程的函数调用链，找出函数调用的顺序和位置。
异常处理： 在 C++ 等语言中，它也用于异常处理，允许程序在异常发生时回溯到异常点，获取相关的调用堆栈信息。
跨平台性： 尽管它的实现可能依赖于底层操作系统和硬件架构，但它为不同的操作系统（如 Linux、BSD、macOS）提供了一致的接口。
</code></pre></div></div>

<p>libunwind 提供了一组 C 接口，允许程序访问和操作调用堆栈信息。这对于调试器、性能分析器以及需要获取运行时调用堆栈信息的工具和库非常有用。</p>

<p>在 Rust 中，libunwind 也被用于实现一些与调用堆栈相关的功能，比如 backtrace 模块就可能在一些平台上依赖于 libunwind 来获取调用堆栈信息。</p>

<p>在 Linux 上，libunwind 通过操作系统提供的机制来获取调用堆栈信息。它使用了一系列系统调用和底层的机制来实现堆栈展开并获取函数调用链信息。</p>

<p>基本上，libunwind 在 Linux 上的工作原理包括以下几个方面：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>使用系统调用获取寄存器和堆栈信息： libunwind 通过访问线程的寄存器和堆栈来获取调用堆栈信息。这包括读取栈指针（Stack Pointer）、基址指针（Base Pointer）等寄存器的值，以及从堆栈中读取调用帧信息。

解析函数调用帧： libunwind 遍历堆栈中的帧信息，解析出函数调用链的信息。它会识别帧中的返回地址，从而确定调用链中各个函数的位置和顺序。

使用特定的异常处理机制： 在有些情况下，libunwind 还可以利用操作系统提供的异常处理机制来获取调用堆栈信息。当程序发生异常时，操作系统可能会保存相关的调用堆栈信息，libunwind 可以利用这些信息进行堆栈展开。
</code></pre></div></div>

<p>需要注意的是，libunwind 的实现依赖于操作系统提供的接口和机制，并且在不同的系统和架构上可能有不同的实现方式。因此，在 Linux 上，它的工作原理可能会与其他操作系统上的实现略有不同，但基本思路是相似的：通过访问寄存器和堆栈来追踪和解析函数调用链。</p>

<p>libunwind 识别帧中的返回地址是通过解析调用堆栈中的帧信息来实现的。在大多数架构上，函数调用时，程序会在堆栈中创建帧（stack frame）来存储有关函数调用的信息，其中包括返回地址。</p>

<p>返回地址是指函数执行完毕后程序应该继续执行的地址，通常是调用该函数的指令地址加上指令长度。这个返回地址通常是存储在帧中的一个特定位置，不同的架构可能有不同的存储方式。</p>

<p>具体来说，在一些常见的架构中：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>x86 架构： 返回地址通常存储在栈顶，即当前函数的栈帧中的一个位置。在函数调用时，返回地址被压入栈中。libunwind 可以读取当前栈帧的栈顶，获取存储的返回地址。

x86-64（64位）架构： 与x86类似，返回地址也通常存储在栈帧中的特定位置。同样，libunwind 在64位系统上也可以读取栈顶位置，获取返回地址。

其他架构： 不同的架构可能有不同的堆栈结构和帧信息存储方式。libunwind 针对特定架构会使用相应的机制来读取帧信息，包括返回地址。
</code></pre></div></div>

<p>通过解析帧信息，libunwind 能够识别帧中存储的返回地址，从而追踪函数调用链的顺序和位置。这些返回地址告诉程序在函数执行完毕后应该回到哪里继续执行。</p>
<h4 id="memory-profile-sample">memory profile sample</h4>
<p>exponential distribution</p>

<blockquote>
  <p>// nextSample returns the next sampling point for heap profiling. The goal is
// to sample allocations on average every MemProfileRate bytes, but with a
// completely random distribution over the allocation timeline; this
// corresponds to a Poisson process with parameter MemProfileRate. In Poisson
// processes, the distance between two samples follows the exponential
// distribution (exp(MemProfileRate)), so the best return value is a random
// number taken from an exponential distribution whose mean is MemProfileRate.
func nextSample() uintptr</p>
</blockquote>

<p>In many cases, memory allocation is regular. If sampling is performed at a fixed granularity, the final result may have a big error. It may happen that a particular type of memory allocation exists at each sampling. This is why randomization is chosen here.</p>

<h3 id="gdb">gdb</h3>

<p>有个rust-gdbgui的可视化工具。时间长会断开连接，不如命令行稳定，而且也不能看string_pointer数组的内容。</p>

<h3 id="neo4j">neo4j</h3>

<p>调试后没发现代码问题，归结为生出树本身的问题。把数组数据导入到了neo4j中直观看到了节点间的关系</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>from neo4j import GraphDatabase
import json

driver = GraphDatabase.driver(
    "bolt://localhost:7687", auth=("neo4j", "neo4j"))

d = json.load(open('bom.json'))

# 社区版只支持一个standard database

for i in d['dependencies']:
    params = {"a": i['ref']}
    clauses = ["merge (a:Component {name:$a})"]
    for idx, x in enumerate(i['dependsOn']):
        node = f"b{idx}"
        params[node] = x
        clauses.append(
            f"MERGE ({node}:Component }) merge (a) -[:dependsOn]-&gt; ({node})")
    driver.execute_query(
        ' '.join(clauses), parameters_=params, database_="neo4j")

driver.close()
</code></pre></div></div>
<p>本地用了 <code class="language-plaintext highlighter-rouge">neo4j</code>镜像;可以用<code class="language-plaintext highlighter-rouge">neo4j/neo4j-admin</code>镜像dump database再导入到aura在线观看（社区版需要先关闭neo4j服务）。</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>match (n where not ()--&gt;(n)) return n; // 所有顶层节点
match (a {name:"顶层节点name"}) match (b {name:"任意记诶但"}) match p=(a) (()--&gt;())* (b) return p; // 查询全部可能路径
</code></pre></div></div>
<blockquote>
  <p>When the quantified path pattern has one relationship pattern, it can be abbreviated to a quantified relationship.</p>
</blockquote>

<p>即 <code class="language-plaintext highlighter-rouge">(() &lt;relationship pattern&gt; ()) &lt;quantifier&gt;</code> 可以重写为 <code class="language-plaintext highlighter-rouge">&lt;relationship pattern&gt; &lt;quantifier&gt;</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>match (a {name:"顶层节点name"}) match (b {name:"任意记诶但"}) match p=(a)--&gt;*(b) return p; // 查询全部可能路径
</code></pre></div></div>]]></content><author><name>FangYuan Si</name></author><category term="Rust" /><category term="memory leak" /><category term="memory profile" /><category term="heap profile" /><category term="malloc" /><summary type="html"><![CDATA[一个rust项目出现内存占用不断增大的问题，怀疑代码中有内存泄漏。]]></summary></entry><entry><title type="html">mastering ehtereum - 笔记</title><link href="https://sify21.github.io/ethereum/mastering-ehtereum/" rel="alternate" type="text/html" title="mastering ehtereum - 笔记" /><published>2023-11-10T00:00:00+00:00</published><updated>2023-11-10T00:00:00+00:00</updated><id>https://sify21.github.io/ethereum/mastering-ehtereum</id><content type="html" xml:base="https://sify21.github.io/ethereum/mastering-ehtereum/"><![CDATA[<h2 id="ch02-basics">ch02 basics</h2>

<table>
  <thead>
    <tr>
      <th>Value (in wei)</th>
      <th>Exponent</th>
      <th>Common name</th>
      <th>SI name</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>1</td>
      <td>wei</td>
      <td>Wei</td>
    </tr>
    <tr>
      <td>1,000</td>
      <td>$10^3$</td>
      <td>Babbage</td>
      <td>Kilowei or femtoether</td>
    </tr>
    <tr>
      <td>1,000,000</td>
      <td>$10^6$</td>
      <td>Lovelace</td>
      <td>Megawei or picoether</td>
    </tr>
    <tr>
      <td>1,000,000,000</td>
      <td>$10^9$</td>
      <td>Shannon</td>
      <td>Gigawei or nanoether</td>
    </tr>
    <tr>
      <td>1,000,000,000,000</td>
      <td>$10^{12}$</td>
      <td>Szabo</td>
      <td>Microether or micro</td>
    </tr>
    <tr>
      <td>1,000,000,000,000,000</td>
      <td>$10^{15}$</td>
      <td>Finney</td>
      <td>Milliether or milli</td>
    </tr>
    <tr>
      <td>1,000,000,000,000,000,000</td>
      <td>$10^{18}$</td>
      <td>Ether</td>
      <td>Ether</td>
    </tr>
    <tr>
      <td>1,000,000,000,000,000,000,000</td>
      <td>$10^{21}$</td>
      <td>Grand</td>
      <td>Kiloether</td>
    </tr>
    <tr>
      <td>1,000,000,000,000,000,000,000,000</td>
      <td>$10^{24}$</td>
      <td> </td>
      <td>Megaether</td>
    </tr>
  </tbody>
</table>

<ul>
  <li>
    <p><code class="language-plaintext highlighter-rouge">zero address</code></p>

    <p>Registering a contract on the blockchain involves creating a special transaction whose destination is the address 0x0000000000000000000000000000000000000000, also known as the zero address</p>
  </li>
</ul>

<h2 id="ch03-clients">ch03 clients</h2>
<ul>
  <li>
    <p>DoS attack</p>

    <p>block 2,283,397 (2016-09-18) to block 2,700,031 (2016-11-26). validation time: 1min/block. hard fork cleaned up 20 million empty accounts created by spam transactions. fast synchronization skips the full validation of transactions until it has synced to the tip of the blockchain.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Remote Client</code> $\ne$ <code class="language-plaintext highlighter-rouge">Light Client</code></p>

    <p><code class="language-plaintext highlighter-rouge">Light Client</code> is analogous to a Simplified Payment Verification client in Bitcoin. Light clients are in development and not in general use for Ethereum</p>
  </li>
  <li>
    <p>JSON-RPC</p>

    <p>https://www.jsonrpc.org/specification</p>
  </li>
</ul>

<h2 id="ch04-cryptography">ch04 cryptography</h2>

<ul>
  <li>EOA: <em>externally owned accounts</em>
    <h3 id="private-key">private key</h3>
  </li>
  <li>nonzero number less than $2^{256}$ (a 78-digit number, roughly $1.158 * 10^{77}$, python <code class="language-plaintext highlighter-rouge">2 ** 256</code> to see)</li>
  <li>shares the first 38 digits with $2^{256}$ and is defined as the order of elliptic curve</li>
  <li>the visible universe is estimated to contain $10^{77}$ to $10^{80}$ atoms
    <h3 id="public-key">public key</h3>
  </li>
  <li>elliptic curve multiplication $K = k * G$. $k$: private key. $G$: constant point called the generator point</li>
  <li>the multiplication is called a “one-way” function by cryptographers
    <h3 id="elliptic-curve-cryptography">elliptic curve cryptography</h3>
  </li>
</ul>

<p>secp256k1, to reuse elliptic curve libraries and tools from Bitcoin</p>
<pre><code class="language-math">y^2 = \big(x^3+7\big) over \big(\mathbb{F}_p\big)
</code></pre>
<p>\(y^2 \mod p = \big(x^3+7\big) \mod p\)</p>

<p>the curve is over a finite field of prime order $p$ (also written as $\mathbb{F}_p$), where $p = 2^{256} - 2^{32} - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 -1$, which is a very large prime number.</p>

<p>The variable p is the prime order of the elliptic curve (the prime that is used for all the modulo operations). you can write the equation in python code as <code class="language-plaintext highlighter-rouge">(x**3 +7 - y**2) % p == 0</code></p>

<h3 id="elliptic-curve-arithmetic-operation">elliptic curve arithmetic operation</h3>
<pre><code class="language-math">P_1 + P_2 + P'_3 = 0, P'_3=(x,y), P_3=(x,-y)
</code></pre>
<p>https://bitcoin.stackexchange.com/questions/21907/what-does-the-curve-used-in-bitcoin-secp256k1-look-like
\(P_3 = P_1 + P_2\)</p>

<ul>
  <li>
    <p>point at infinity: ($P_1$ and $P_2$ have same x value but different y value, then $P_3$ is point at infinity)</p>
  </li>
  <li>
    <p>SECG (Standards for Efficient Cryptography Group) <a href="http://www.secg.org/sec1-v2.pdf">SEC1</a>
prefix | meaning | length(bytes counting prefix)
— | — | —
0x00 | point at infinity | 1
0x04 | uncompressed point | 65
0x02 | compressed point with even y | 33
0x03 | compressed point with odd y | 33</p>
  </li>
</ul>

<h3 id="cryptographic-hash-function-keccak-256">cryptographic hash function: Keccak-256</h3>
<ul>
  <li>originally a SHA-3 candidate, NIST adjusted some parameters for efficiency, at the same time Edward Snowden revealed Dual_EC_DRBG backdoor. thus backlash against those changes and deplayed standardization of SHA-3, so Ethereum Foundation implement the original Keccak algorithm, rather than using the finalized FIPS-202 SHA-3 standard.</li>
</ul>

<h3 id="ethereum-address">Ethereum Address</h3>
<ul>
  <li>last 20 bytes of the Keccak-256 hash of the public key (without the prefix 0x04)</li>
  <li>higher layers should add checksums to those bytes</li>
  <li>ICAP (Inter exchange Client Address Protocol): similar to International Bank Account Number (IBAN) encoding, less support</li>
  <li>later, EIP-55 mixed-capitalization checksum</li>
</ul>

<h2 id="ch05-wallets">ch05 wallets</h2>
<p>HD wallet advantages</p>
<ul>
  <li>organizational meaning</li>
  <li>create a sequence of public keys without private keys: watch-only or receive-only capacity</li>
</ul>

<p>standards</p>
<ul>
  <li>mnemonic code words, BIP-39</li>
  <li>HD wallets, BIP-32
    <ul>
      <li>extended keys (append a 256-bit chain code)</li>
      <li>hardended child key derivation
        <ul>
          <li>normal derivation: index number from $0$ to $2^{31}-1$</li>
          <li>hardened derivation: index number from $2^{31}$ to $2^{32}-1$ (displayed as $i^\prime$, meaning $2^{31}+i$</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>
    <p>Paths, BIP-43/44
<code class="language-plaintext highlighter-rouge">m / purpose' / coin_type' / account' / change / address_index</code></p>

    <p>forth level only “receive” path is used in ethereum</p>
  </li>
</ul>

<h2 id="ch06-transactions">ch06 transactions</h2>
<p>Contracts don’t run on their own. Ethereum doesn’t run autonomously. Everything starts with a transaction.</p>
<ul>
  <li>
    <p>Nonce</p>

    <p>not stored, calculated dynamically(<code class="language-plaintext highlighter-rouge">getTransactionCount</code>), by counting the number of confirmed transactions that have originated from an address. vital for account-based protocol, in contrast to UTXO mechanism of Bitcoin protocol</p>
    <ul>
      <li>tx being included by the order of creation(similar to JSON-RPC id of Request object)</li>
      <li>replay (without nonce the two tx would be the same)</li>
    </ul>
  </li>
  <li>Gas price</li>
  <li>Gas limit</li>
  <li>Recipient</li>
  <li>Value</li>
  <li>Data
    <ul>
      <li>
        <p>when sent to EOA</p>

        <p>interpreted by wallet(ignored by most), not subject to Ethereum’s consensus rules</p>
      </li>
      <li>
        <p>when sent to ABI-compatible contract</p>

        <p>interpreted by EVM as contract invocation</p>
        <ul>
          <li>A function selector: first 4 bytes of Keccak-256 hash of function’s prototype, e.g. withdraw(uint256), and padded to 32 bytes</li>
          <li>function arguments: encoded by rules for types in ABI specification</li>
        </ul>
      </li>
      <li>
        <p>when sent to zero address (there is specially designated burn-address: 0x0..0dEaD)</p>

        <p>means contract creation, bytecode representation of the contract(optionally with value as starting balance)</p>
      </li>
    </ul>
  </li>
  <li>
    <p>$v,r,s$</p>

    <p>The three components of an ECDSA digital signature of the originating EOA.
\(Sig = F_{sig}\big(F_{keccak256}(m),k\big)\)</p>
    <ul>
      <li>k signing private key</li>
      <li>m RLP-encoded transaction(nonce, gasPrice, gasLimit, to, value, data, chainID, 0, 0)</li>
      <li>$Sig = (r,s)$</li>
    </ul>

    <p>$r$ is $x$ coordinate of ephemeral public key $Q$ from ephemeral private key $q$, $s \equiv q^{-1}(Keccak256(m)+r*k) (\mod p)$</p>

    <p>$v$ indicates the chain ID and the recovery identifier (Public Key Recovery involves $r$, $s$ and message hash)</p>
  </li>
</ul>

<p>transaction serialized using RLP (Recursive Length Prefix), big-endian integers, no field delimiters or labels. EOA’s public key is derived from $v,r,s$</p>

<h2 id="ch07-smart-contract-and-solidity">ch07 smart contract and solidity</h2>
<ul>
  <li>by Nick Szabo</li>
  <li>misnomer in Ethereum, neither smart nor legal contracts</li>
  <li>computer programs</li>
  <li>immutable (the code cannot change)</li>
  <li>deterministic</li>
  <li>EVM context</li>
  <li>world computer</li>
  <li>selfdestruct/suicide negative gas (the refund is removed since EIP-3529)
    <h3 id="contract-abiapplication-binary-interface">contract ABI(application binary interface)</h3>
  </li>
  <li>ABI defines how data structures and functions are accessed in machine code, thus primary way of encoding and decoding data into and out of machine code</li>
  <li>API(application programming interface) define this access in high level, often human-readable formats as source code</li>
  <li>in Ethereum, define functions in contract that can be invoked and describe function arguments and result</li>
  <li>specified as JSON array of function descriptions and events (solc –abi)</li>
</ul>

<h2 id="ch08-vyper">ch08 vyper</h2>
<ul>
  <li>no function modifiers</li>
  <li>no inheritance</li>
  <li>no inline assembly</li>
  <li>no function overloading</li>
  <li>no implicit typecasting: use <code class="language-plaintext highlighter-rouge">convert</code> to perform explicit casts (raise exception when information lost;)</li>
  <li>deterministic number of iterations with <code class="language-plaintext highlighter-rouge">for</code>; no recursive calling</li>
  <li>preconditionsn and postconditions
    <ul>
      <li>condition</li>
      <li>effects</li>
      <li>interactions</li>
    </ul>
  </li>
  <li>decorators</li>
  <li>one vyper file for one contract; function and variable declarations physically written in particular order</li>
  <li>overflow issue
    <ul>
      <li>solidity
        <ul>
          <li>SafeMath library</li>
          <li>Mythril OSS security analysis tool</li>
        </ul>
      </li>
      <li>vyper
        <ul>
          <li>SafeMath equivalent</li>
          <li>clamps</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<h2 id="ch09-smart-contract-security">ch09 smart contract security</h2>
<ul>
  <li>defensive programming
    <ul>
      <li>minimalism/simplicity</li>
      <li>code reuse</li>
      <li>code quality: unforgiving discipline</li>
      <li>readability/auditability</li>
      <li>test coverage</li>
    </ul>
  </li>
  <li>security risks / antipatterns
    <ul>
      <li>reentrancy
        <ul>
          <li>use <code class="language-plaintext highlighter-rouge">transfer</code></li>
          <li><code class="language-plaintext highlighter-rouge">checks-effects-interacctions</code> pattern</li>
          <li>mutex</li>
        </ul>
      </li>
      <li>arithmetic over/underflows
        <ul>
          <li>SafeMath library by OpenZeppelin</li>
        </ul>
      </li>
      <li>
        <p>unexpected ether</p>

        <p>ether added to contract without executing any code; or <code class="language-plaintext highlighter-rouge">this.balance</code> artificially manipulated</p>
        <ul>
          <li>sendall/selfdestruct/suicide</li>
          <li>
            <p>pre-sent ether</p>

            <p><code class="language-plaintext highlighter-rouge">contract_address = keccak256(rlp.encode([account_address,transaction_nonce]))</code></p>
          </li>
        </ul>
      </li>
      <li>delegatecall
        <ul>
          <li>context-reserving: state variables are referenced by slot index</li>
          <li>library should be stateless</li>
        </ul>
      </li>
      <li>default visibilities
        <ul>
          <li>solidity: default is public</li>
          <li>always specify visibility</li>
        </ul>
      </li>
      <li>entropy illusion
        <ul>
          <li>source of entropy must be external to the blockchain
            <ul>
              <li>commit-reveal(done among peers)</li>
              <li>RandDAO</li>
              <li>randomness oracle</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>
        <p>external contract referencing</p>

        <p>author/owner/deployer of the contract(the attacker) wants to hide malicious code (from auditor)</p>
        <ul>
          <li><code class="language-plaintext highlighter-rouge">new</code> to create contracts</li>
          <li>hardcode external contract addresses</li>
          <li>external contral addresses should be public to allow users examnie referenced code</li>
          <li>if external contract address can be changed, it should implement a time-lock/voting mechanism for auditing</li>
        </ul>
      </li>
      <li>
        <p>short address/parameter attack</p>

        <p>performed on third-party applications that interact with contracts</p>
        <ul>
          <li>EVM will add zeros to the end of the encoded parameters if they are shorter than the expected parameter length</li>
          <li>input parameters in external applications should be validated</li>
          <li>careful ordering of contract parameters can mitigate: padding(added zeros) only occurs at the end</li>
        </ul>
      </li>
      <li>unchecked call return values
        <ul>
          <li><code class="language-plaintext highlighter-rouge">call</code>/<code class="language-plaintext highlighter-rouge">send</code> return <code class="language-plaintext highlighter-rouge">Boolean</code>, rather than revert</li>
          <li>should use <code class="language-plaintext highlighter-rouge">transfer</code>(which reverts) to send ether</li>
          <li><a href="https://docs.soliditylang.org/en/latest/common-patterns.html#withdrawal-from-contracts"><em>withdrawal</em> pattern</a>: isolated withdraw function</li>
        </ul>
      </li>
      <li>race conditions/front-running
        <ul>
          <li>attacker watch transaction pool, raise gasPrice</li>
          <li>miners reorder transactions at their will</li>
          <li>solution1: upper bound on gasPrice</li>
          <li>solution2: commit-reveal scheme</li>
          <li>solution3: submarine sends</li>
        </ul>
      </li>
      <li>dos
        <ul>
          <li>loop through externally manipulated mappings/arrays (exceeds block gas limit)
            <ul>
              <li>should use withdrawal pattern</li>
            </ul>
          </li>
          <li>owner privileged operations needed for the contract to proceed to the next state
            <ul>
              <li>can use multisig</li>
              <li>can use time-lock</li>
            </ul>
          </li>
          <li>progressing state based on external calls
            <ul>
              <li>should add a time-based state progression</li>
            </ul>
          </li>
          <li>can add a <code class="language-plaintext highlighter-rouge">maintenanceUser</code> (centralized, trust-issue)</li>
        </ul>
      </li>
      <li>block timestamp manipulation
        <ul>
          <li>use block number instead</li>
        </ul>
      </li>
      <li>constructor name (before solidity v0.4.22)</li>
      <li>uninitialized storage pointers
        <ul>
          <li>solidity by default puts local variables of  complex data types(e.g. structs) in storage</li>
        </ul>
      </li>
      <li>floating point and precision</li>
      <li>tx.origin authentication
        <ul>
          <li>can only be used when: deny external contracts from calling current contract <code class="language-plaintext highlighter-rouge">require(tx.origin == msg.sender)</code></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<h2 id="ch10-token">ch10 token</h2>
<ul>
  <li>fungibility</li>
  <li>counterparty risk
    <ul>
      <li>custodian of the asset</li>
    </ul>
  </li>
  <li>intrinsicality
    <ul>
      <li>equity in a extinsic corporatio vs DAO(intrinsic)</li>
    </ul>
  </li>
  <li>utility &amp; equity</li>
  <li>The ether balance of Ethereum accounts is handled at the protocol level, whereas the token balance of Ethereum accounts is handled at the smart contract level</li>
  <li>ERC20
    <ul>
      <li>fungible</li>
      <li>cant pay for gas (need ether to send tokens)</li>
      <li>locked into contracts problem: tokens transfered to contract that dont support tokens are lost forever</li>
    </ul>
  </li>
  <li>ERC223
    <ul>
      <li>solve the problem of inadvertent transfer of tokens to a contract</li>
      <li><code class="language-plaintext highlighter-rouge">isContract</code>: extcodesize</li>
      <li><code class="language-plaintext highlighter-rouge">tokenFallback</code> to accept tokens</li>
      <li>not widely implemented</li>
    </ul>
  </li>
  <li>ERC777
    <ul>
      <li>depends on ERC820: registry contract</li>
    </ul>
  </li>
  <li>ERC721
    <ul>
      <li>non-fungible tokens (deeds)</li>
      <li>256-bit identifier (deedId)
        <h2 id="ch11-oracles">ch11 oracles</h2>
      </li>
    </ul>
  </li>
  <li>system that can answer questions that are external to Ethereum</li>
  <li>to maintain consensus, EVM execution must be totally deterministic
    <ul>
      <li>no intrinsic source of randomness</li>
      <li>extrinsic data can only be introduced as transaction data payload</li>
    </ul>
  </li>
  <li>ability
    <ul>
      <li>Collect data from an off-chain source</li>
      <li>Transfer the data on-chain with a signed message</li>
      <li>Make the data available by putting it in a smart contract’s storage</li>
    </ul>
  </li>
  <li>patterns
    <ul>
      <li>request-response</li>
      <li>publish-subscribe</li>
      <li>immediate-read
        <h2 id="ch12-dapps">ch12 dapps</h2>
      </li>
    </ul>
  </li>
  <li>aspects of an application that may be decentralized
    <ul>
      <li>Backend software (application logic)</li>
      <li>Frontend software</li>
      <li>Data storage</li>
      <li>Message communications</li>
      <li>Name resolution</li>
    </ul>
  </li>
  <li>dapp advantages
    <ul>
      <li>resiliency</li>
      <li>transparency</li>
      <li>censorship resistance
        <h2 id="ch13-evm">ch13 EVM</h2>
      </li>
    </ul>
  </li>
  <li>stack-based: all in-memory values stored on a stack</li>
  <li>256-bit word size: to facilitate native hashing and elliptic curve operations</li>
  <li>addressable data components
    <ul>
      <li>immutable program code ROM (contract code)</li>
      <li>volatile memory</li>
      <li>permanent storage
        <h2 id="ch14-consensus">ch14 consensus</h2>
      </li>
    </ul>
  </li>
  <li>synchronizing state in distributed system</li>
  <li>no trusted arbitrator</li>
  <li>consensus algorithm: the mechanism to reconcile security and decentralization</li>
  <li>consensus is intended to produce a system of strict rules without rulers</li>
  <li>consensus models
    <ul>
      <li>PoW
        <ul>
          <li>mining
            <ul>
              <li>reward is the means</li>
              <li>decentralized security is the end</li>
            </ul>
          </li>
          <li>Ethhash
            <ul>
              <li>dependent on the generation and analysis of DAG (directed acyclic graph)</li>
              <li>ASIC resistant: more difficult to make ASIC, to avoid centralization in PoW mining (use GPU)</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>PoS
        <ul>
          <li>blockchain keeps track of validators</li>
          <li>anyone who holds the blockchain’s base cryptocurrency can become a validator by sending a special type of transaction that locks up their ether into a deposit</li>
          <li>validators take turns proposing and voting on the next valid block, and the weight of each validator’s vote depends on the size of its deposit (i.e. stake)</li>
          <li>a validator risks losing their deposit, i.e., “being slashed”, if the block they staked it on is rejected by the majority of validators</li>
          <li>validators earn a small reward, proportional to their deposited stake, for every block that is accepted by the majority</li>
          <li>The major difference between PoS and PoW is that the punishment in PoS is intrinsic to the blockchain (e.g., loss of staked ether), whereas in PoW the punishment is extrinsic (e.g., loss of funds spent on electricity)</li>
          <li>Casper</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>]]></content><author><name>FangYuan Si</name></author><category term="ethereum" /><summary type="html"><![CDATA[ch02 basics]]></summary></entry><entry><title type="html">ethereum yellowpaper - 笔记</title><link href="https://sify21.github.io/ethereum/ehtereum-yellowpaper/" rel="alternate" type="text/html" title="ethereum yellowpaper - 笔记" /><published>2023-11-03T00:00:00+00:00</published><updated>2023-11-03T00:00:00+00:00</updated><id>https://sify21.github.io/ethereum/ehtereum-yellowpaper</id><content type="html" xml:base="https://sify21.github.io/ethereum/ehtereum-yellowpaper/"><![CDATA[<h2 id="world-state">World State</h2>

<table>
  <thead>
    <tr>
      <th>symbol</th>
      <th>meaning</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$\sigma$</td>
      <td>world state</td>
    </tr>
    <tr>
      <td>$\sigma [a]$</td>
      <td>account state</td>
    </tr>
    <tr>
      <td>$\sigma [a]_n$</td>
      <td>nounce</td>
    </tr>
    <tr>
      <td>$\sigma [a]_b$</td>
      <td>balance(Wei)</td>
    </tr>
    <tr>
      <td>$\sigma [a]_s$</td>
      <td>storageRoot</td>
    </tr>
    <tr>
      <td>$\sigma [a]_c$</td>
      <td>codeHash</td>
    </tr>
  </tbody>
</table>

\[\forall a : \sigma [a] = \varnothing \vee (a \in \mathbb{B}_{20} \wedge v(\sigma[a]))\]

\[v(x) \equiv x_n \in \mathbb{N}_{256} \wedge x_b \in \mathbb{N}_{256} \wedge x_s \in \mathbb{B}_{32} \wedge x_c \in \mathbb{B}_{32}\]

\[EMPTY(\sigma, a) \equiv \sigma[a]_c=KEC\big(()\big) \wedge \sigma[a]_n=0 \wedge \sigma[a]_b=0\]

\[DEAD(\sigma, a) \equiv \sigma[a]=\varnothing \vee EMPTY(\sigma, a)\]

<h2 id="transaction">Transaction</h2>

<table>
  <thead>
    <tr>
      <th>symbol</th>
      <th>meaning</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$T_x$</td>
      <td>type</td>
    </tr>
    <tr>
      <td>$T_p$</td>
      <td>gasPrice</td>
    </tr>
    <tr>
      <td>$T_g$</td>
      <td>gasLimit</td>
    </tr>
    <tr>
      <td>$T_t$</td>
      <td>to</td>
    </tr>
    <tr>
      <td>$T_v$</td>
      <td>value(Wei)</td>
    </tr>
    <tr>
      <td>$T_r$, $T_s$</td>
      <td>signature (r, s)</td>
    </tr>
    <tr>
      <td>$T_A$ (type 1)</td>
      <td>accessList</td>
    </tr>
    <tr>
      <td>$T_c$ (type 1)</td>
      <td>chainId $\beta$</td>
    </tr>
    <tr>
      <td>$T_y$ (type 1)</td>
      <td>yParity</td>
    </tr>
    <tr>
      <td>$T_w$ (type 0 legacy)</td>
      <td>$T_w=27+T_y$ or $T_w=2\beta+35+T_y$</td>
    </tr>
    <tr>
      <td>$T_i$ ($T_t=\varnothing$)</td>
      <td>init (contract creation)</td>
    </tr>
    <tr>
      <td>$T_d$ ($T_t\ne\varnothing$)</td>
      <td>data (message call)</td>
    </tr>
  </tbody>
</table>

<h2 id="block">Block</h2>

<table>
  <thead>
    <tr>
      <th>symbol</th>
      <th>meaning</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>B</td>
      <td>block</td>
    </tr>
    <tr>
      <td>$B_H$</td>
      <td>block header</td>
    </tr>
    <tr>
      <td>$B_T$</td>
      <td>transaction list</td>
    </tr>
    <tr>
      <td>$B_U$</td>
      <td>ommer block headers</td>
    </tr>
  </tbody>
</table>

\[B \equiv (B_H, B_T, B_U)\]

<table>
  <thead>
    <tr>
      <th>block header field</th>
      <th>meaning</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$H_p$</td>
      <td>parentHash</td>
    </tr>
    <tr>
      <td>$H_o$</td>
      <td>ommersHash</td>
    </tr>
    <tr>
      <td>$H_c$</td>
      <td>beneficiary</td>
    </tr>
    <tr>
      <td>$H_r$</td>
      <td>stateRoot</td>
    </tr>
    <tr>
      <td>$H_t$</td>
      <td>transactionsRoot</td>
    </tr>
    <tr>
      <td>$H_e$</td>
      <td>receiptsRoot</td>
    </tr>
    <tr>
      <td>$H_b$</td>
      <td>logsBloom</td>
    </tr>
    <tr>
      <td>$H_d$</td>
      <td>difficulty</td>
    </tr>
    <tr>
      <td>$H_i$</td>
      <td>number</td>
    </tr>
    <tr>
      <td>$H_l$</td>
      <td>gasLimit</td>
    </tr>
    <tr>
      <td>$H_g$</td>
      <td>gasUsed</td>
    </tr>
    <tr>
      <td>$H_s$</td>
      <td>timestamp</td>
    </tr>
    <tr>
      <td>$H_x$</td>
      <td>extraData</td>
    </tr>
    <tr>
      <td>$H_m$</td>
      <td>mixHash</td>
    </tr>
    <tr>
      <td>$H_n$</td>
      <td>nonce</td>
    </tr>
  </tbody>
</table>

<h3 id="transaction-receipt">Transaction Receipt</h3>

<table>
  <thead>
    <tr>
      <th>symbol</th>
      <th>meaning</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$B_R$</td>
      <td>transaction receipt trie of the block, $B_R[i]$ for the $i$ th transaction</td>
    </tr>
    <tr>
      <td>R</td>
      <td>transaction receipt</td>
    </tr>
    <tr>
      <td>$R_x$</td>
      <td>type of the transaction</td>
    </tr>
    <tr>
      <td>$R_z$</td>
      <td>status code of the transaction</td>
    </tr>
    <tr>
      <td>$R_u$</td>
      <td>the cumulative gas used in the block containing the transaction receipt as of immediately after the transaction has happened</td>
    </tr>
    <tr>
      <td>$R_l$</td>
      <td>the set of logs created through execution of the transaction</td>
    </tr>
    <tr>
      <td>$R_b$</td>
      <td>the Bloom filter composed from information in those logs</td>
    </tr>
  </tbody>
</table>

\[R \equiv (R_x, R_z, R_u, R_b, R_l)\]

<table>
  <thead>
    <tr>
      <th>log entry field</th>
      <th>meaning</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>O</td>
      <td>log entry</td>
    </tr>
    <tr>
      <td>$O_a$</td>
      <td>logger’s address</td>
    </tr>
    <tr>
      <td>$O_t$</td>
      <td>a possibly empty series of 32-byte log topics</td>
    </tr>
    <tr>
      <td>$O_d$</td>
      <td>log data</td>
    </tr>
  </tbody>
</table>

\[O \equiv (O_a, (O_{t0}, O_{t1}, ...), O_d)\]]]></content><author><name>FangYuan Si</name></author><category term="ethereum" /><summary type="html"><![CDATA[World State]]></summary></entry><entry><title type="html">ethereum whitepaper - 笔记</title><link href="https://sify21.github.io/ethereum/ethereum-whitepaper/" rel="alternate" type="text/html" title="ethereum whitepaper - 笔记" /><published>2023-11-02T00:00:00+00:00</published><updated>2023-11-02T00:00:00+00:00</updated><id>https://sify21.github.io/ethereum/ethereum-whitepaper</id><content type="html" xml:base="https://sify21.github.io/ethereum/ethereum-whitepaper/"><![CDATA[<h1 id="name-origin">Name Origin</h1>
<ul>
  <li>Aetherium/Volucite (<a href="https://ghibli.fandom.com/wiki/Crystal_necklace">Crystal necklace</a> from <code class="language-plaintext highlighter-rouge">Laputa: Castle in the Sky</code>)</li>
  <li><a href="https://markets.businessinsider.com/currencies/news/ethereum-name-origin-ether-vitalik-buterin-camilla-russo-infinite-machine-2021-5-1030477375">ether</a>
    <blockquote>
      <p>Vitalik Buterin was inspired by a medieval scientific theory when he came up with the name for the ethereum network, according to Camilla Russo, former Bloomberg journalist and founder of DeFi news platform, The Defiant.</p>

      <p>In her 2020 book The Infinite Machine, Russo said that Buterin looked to science fiction terms for inspiration when he wrote the ethereum white paper in 2013.</p>

      <p>Buterin was scrolling through Wikipedia when he came across the word “ether,” and remembered this term from a science book he had read as a child.</p>

      <p>Ether is the now disproved concept that there’s a subtle material that fills space and carries all light waves. In the 19th century, scientists assumed ether was weightless, transparent, frictionless, undetectable chemically or physically, and permeated all matter and space, according to Britannica.</p>

      <p>“Vitalik wanted his platform to be the underlying and imperceptible medium for every application, just what medieval scientists thought ether was,” Russo said. “Plus, it sounded nice.”</p>

      <p>He landed on the word “ethereum,” to describe the decentralized protocol.</p>

      <p>“Ether” refers to the cryptocurrency of the ethereum blockchain, a fuel that can be used for payments or to power decentralized apps built on the platform.</p>

      <p>The theory of ether was abandoned by scientists after Albert Einstein formed the special theory of relativity in 1905, per Britannica. But the use cases for the ethereum protocol are just getting started, crypto experts say.</p>
    </blockquote>
  </li>
</ul>

<h1 id="basic-concepts">Basic Concepts</h1>
<ul>
  <li>Accounts
    <blockquote>
      <p>Ethereum account contains four fields:</p>

      <ul>
        <li>The nonce, a counter used to make sure each transaction can only be processed once</li>
        <li>The account’s current ether balance</li>
        <li>The account’s contract code, if present</li>
        <li>The account’s storage (empty by default)</li>
      </ul>

      <p>In general, there are two types of accounts: externally owned accounts, controlled by private keys, and contract accounts, controlled by their contract code. An externally owned account has no code, and one can send messages from an externally owned account by creating and signing a transaction; in a contract account, every time the contract account receives a message its code activates, allowing it to read and write to internal storage and send other messages or create contracts in turn.</p>
    </blockquote>
  </li>
  <li>Messages and Transactions
    <blockquote>
      <p>The term “transaction” is used in Ethereum to refer to the signed data package that stores a message to be sent from an externally owned account. Transactions contain:</p>

      <ul>
        <li>The recipient of the message</li>
        <li>A signature identifying the sender</li>
        <li>The amount of ether to transfer from the sender to the recipient</li>
        <li>An optional data field</li>
        <li>A STARTGAS value, representing the maximum number of computational steps the transaction execution is allowed to take</li>
        <li>A GASPRICE value, representing the fee the sender pays per computational step</li>
      </ul>

      <p>The fundamental unit of computation is “gas”; usually, a computational step costs 1 gas, but some operations cost higher amounts of gas because they are more computationally expensive, or increase the amount of data that must be stored as part of the state. There is also a fee of 5 gas for every byte in the transaction data.</p>
    </blockquote>

    <blockquote>
      <p>Contracts have the ability to send “messages” to other contracts. Messages are virtual objects that are never serialized and exist only in the Ethereum execution environment. A message contains:</p>

      <ul>
        <li>The sender of the message (implicit)</li>
        <li>The recipient of the message</li>
        <li>The amount of ether to transfer alongside the message</li>
        <li>An optional data field</li>
        <li>A STARTGAS value</li>
      </ul>
    </blockquote>
  </li>
  <li>Code Execution
    <blockquote>
      <p>EVM’s full computational state while running can be defined by the tuple (block_state, transaction, message, code, memory, stack, pc, gas)</p>
    </blockquote>
  </li>
</ul>

<h1 id="blockchain-and-mining">Blockchain and Mining</h1>
<blockquote>
  <p>Ethereum blocks contain a copy of both the transaction list and the most recent state (In Ethereum, the state is made up of objects called “accounts”)</p>
  <ul>
    <li><a href="https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/">Merkle Patricia Trie</a></li>
  </ul>
</blockquote>

<h1 id="concerns没读懂">Concerns（没读懂）</h1>
<ul>
  <li>
    <p>Modified GHOST</p>

    <p><a href="https://eprint.iacr.org/2013/881.pdf">Secure High-Rate Transaction Processing in Bitcoin</a></p>
  </li>
  <li>
    <p>Fees</p>

    <p>Bitcoin: “market-based”, in reality it’s not, because every transaction that a miner includes will need to be processed by every node, thus <code class="language-plaintext highlighter-rouge">tragedy-of-the-commons</code></p>
  </li>
</ul>]]></content><author><name>FangYuan Si</name></author><category term="ethereum" /><summary type="html"><![CDATA[Name Origin Aetherium/Volucite (Crystal necklace from Laputa: Castle in the Sky) ether Vitalik Buterin was inspired by a medieval scientific theory when he came up with the name for the ethereum network, according to Camilla Russo, former Bloomberg journalist and founder of DeFi news platform, The Defiant. In her 2020 book The Infinite Machine, Russo said that Buterin looked to science fiction terms for inspiration when he wrote the ethereum white paper in 2013. Buterin was scrolling through Wikipedia when he came across the word “ether,” and remembered this term from a science book he had read as a child. Ether is the now disproved concept that there’s a subtle material that fills space and carries all light waves. In the 19th century, scientists assumed ether was weightless, transparent, frictionless, undetectable chemically or physically, and permeated all matter and space, according to Britannica. “Vitalik wanted his platform to be the underlying and imperceptible medium for every application, just what medieval scientists thought ether was,” Russo said. “Plus, it sounded nice.” He landed on the word “ethereum,” to describe the decentralized protocol. “Ether” refers to the cryptocurrency of the ethereum blockchain, a fuel that can be used for payments or to power decentralized apps built on the platform. The theory of ether was abandoned by scientists after Albert Einstein formed the special theory of relativity in 1905, per Britannica. But the use cases for the ethereum protocol are just getting started, crypto experts say.]]></summary></entry><entry><title type="html">mastering bitcoin - 笔记</title><link href="https://sify21.github.io/bitcoin/mastering-bitcoin/" rel="alternate" type="text/html" title="mastering bitcoin - 笔记" /><published>2023-10-17T00:00:00+00:00</published><updated>2023-10-17T00:00:00+00:00</updated><id>https://sify21.github.io/bitcoin/mastering-bitcoin</id><content type="html" xml:base="https://sify21.github.io/bitcoin/mastering-bitcoin/"><![CDATA[<h1 id="ch02-how-bitcoin-works">ch02 How Bitcoin Works</h1>
<p>Alice to Bob’s rawtx(P2PKH)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0100000001186f9f998a5aa6f048e51dd8419a14d8a0f1a8a2836dd734d2804fe65fa35779000000008b483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adfffffffff0260e31600000000001976a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788acd0ef8000000000001976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac00000000
</code></pre></div></div>
<p>its parent rawtx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0100000001524d288f25cada331c298e21995ad070e1d1a0793e818f2f7cfb5f6122ef3e71000000008c493046022100a59e516883459706ac2e6ed6a97ef9788942d3c96a0108f2699fa48d9a5725d1022100f9bb4434943e87901c0c96b5f3af4e7ba7b83e12c69b1edbfe6965f933fcd17d014104e5a0b4de6c09bd9d3f730ce56ff42657da3a7ec4798c0ace2459fb007236bc3249f70170509ed663da0300023a5de700998bfec49d4da4c66288a58374626c8dffffffff0180969800000000001976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac00000000
</code></pre></div></div>
<h1 id="ch04-keys-addresses">ch04 Keys, Addresses</h1>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>K=kG, 0&lt;k&lt;=n-1
n(1.1578 * 1077) is slightly less than 2^256(order of elliptic curve)
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>A=RIPEMD160(SHA256(K)), or A=HASH160(K)
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>checksum = first 4 bytes of: SHA256(SHA256(prefix + data))
Base58Check-encoded Payload = Base58(prefix + data + checksum)
</code></pre></div></div>
<p>Base58Check version prefix and encoded result examples</p>

<table>
  <thead>
    <tr>
      <th>Type</th>
      <th>Version prefix (hex)</th>
      <th>Base58 result prefix</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Bitcoin Address</td>
      <td>0x00</td>
      <td>1</td>
    </tr>
    <tr>
      <td>Pay-to-Script-Hash Address</td>
      <td>0x05</td>
      <td>3</td>
    </tr>
    <tr>
      <td>Bitcoin Testnet Address</td>
      <td>0x6F</td>
      <td>m or n</td>
    </tr>
    <tr>
      <td>Private Key WIF</td>
      <td>0x80</td>
      <td>5, K, or L</td>
    </tr>
    <tr>
      <td>BIP-38 Encrypted Private Key</td>
      <td>0x0142</td>
      <td>6P</td>
    </tr>
    <tr>
      <td>BIP-32 Extended Public Key</td>
      <td>0x0488B21E</td>
      <td>xpub</td>
    </tr>
  </tbody>
</table>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uncompressed public key = 04 x y
compressed public key = 02 x(y is even) or 03 x(y is odd)
compressed private key (for wallet import format) = uncompressed private key 01
</code></pre></div></div>
<h1 id="ch05-wallets">ch05 Wallets</h1>
<p><code class="language-plaintext highlighter-rouge">mnemonic(128-256 bits)</code> -&gt; (optinaly with salt) key-stretching function PBKDF2(2048 rounds of HMAC-SHA512) -&gt; <code class="language-plaintext highlighter-rouge">seed(512-bit)</code> -&gt; HMAC-SHA512 -&gt; <code class="language-plaintext highlighter-rouge">master pri key(left 256 bits) + master chain code(right 256 bits)</code></p>

<p>CKD function visualized. from <a href="https://medium.com/@blainemalone01/hd-wallets-why-hardened-derivation-matters-89efcdc71671">a nice blog</a> of @blainemalone01 on medium.</p>

<p><img src="/assets/images/bip32.webp" alt="child key derivation function" /></p>

<ul>
  <li>Mnemonic code words, based on <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">BIP-39</a></li>
  <li>HD(hierarchical deterministic) wallets, based on <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">BIP-32</a></li>
  <li>Multipurpose HD wallet structure, based on <a href="https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki">BIP-43</a></li>
  <li>Multicurrency and multiaccount wallets, based on <a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP-44</a>: <code class="language-plaintext highlighter-rouge">m / purpose'(always 44’) / coin_type' / account' / change(0 for receiving address or signing prikey, 1 for change address) / address_index (usable addresses)</code></li>
</ul>

<h1 id="ch07-advanced-transactions-and-scripting">ch07 Advanced Transactions and Scripting</h1>
<h2 id="p2shbip-16">p2sh(<a href="https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki">BIP-16</a>)</h2>
<ul>
  <li>execute scriptSig</li>
  <li>the stack gets copied (contains &lt;redeem script&gt;, which is the original scripPub of p2pbk or p2ms)</li>
  <li>execute scriptPub</li>
  <li>pop and deserialize &lt;redeem script&gt; from the copied stack, which becomes the new locking script</li>
</ul>

<p>2-of-3 multisig script using p2sh adds an extra 25 bytes to the overall script, compared to 2-of-3 multisig script using the simple P2MS pattern.</p>
<h2 id="segwit">segwit</h2>
<ul>
  <li><a href="https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki">BIP-141</a> The main definition of Segregated Witness.</li>
  <li><a href="https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki">BIP-143</a> Transaction Signature Verification for Version 0 Witness Program</li>
  <li><a href="https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki">BIP-144</a> Peer Services—New network messages and serialization formats</li>
  <li><a href="https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki">BIP-145</a> getblocktemplate Updates for Segregated Witness (for mining)</li>
  <li><a href="https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki">BIP-173</a> Base32 address format for native v0-16 witness outputs</li>
</ul>

<p>A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (for 0 to 16) followed by a data push between 2 and 40 bytes gets a new special meaning, which is interpreted as  “version byte” + “witness program”.</p>

<p>two cases in which witness validation logic are triggered:</p>
<ul>
  <li>native witness program: above pattern is in scriptPubKey (scriptSig must be empty or validaition fails)</li>
  <li>P2SH witness program: above pattern is in redeemScript (scriptSig must be exactly a push of the BIP16 redeemScript or validation fails)</li>
</ul>

<p><code class="language-plaintext highlighter-rouge">version byte</code> = <code class="language-plaintext highlighter-rouge">0</code> &amp;&amp; <code class="language-plaintext highlighter-rouge">witness program</code> = <code class="language-plaintext highlighter-rouge">20 bytes</code>: interpreted as P2WPKH program, the witness must consist of exactly 2 items (≤ 520 bytes each). The first one a signature, and the second one a public key.</p>

<p><code class="language-plaintext highlighter-rouge">version byte</code> = <code class="language-plaintext highlighter-rouge">0</code> &amp;&amp; <code class="language-plaintext highlighter-rouge">witness program</code> = <code class="language-plaintext highlighter-rouge">32 bytes</code>: interpreted as P2WSH program, The witness must consist of an input stack to feed to the script, followed by a serialized script(witness script, ≤ 10,000 bytes).</p>

<h1 id="ch08-the-bitcoin-network">ch08 The Bitcoin Network</h1>
<ul>
  <li>P2P network</li>
  <li>FIBRE(fast internet bitcoin relay engine) 挖矿用
    <h2 id="full-node">full node</h2>
  </li>
</ul>

<h2 id="spv-node">SPV node</h2>
<p>只存储Block头。SPV verifies transactions by reference to their depth in the blockchain instead of their height。节点等待6个新block堆叠在包含tx的block上，以此证明tx被认证了。</p>

<p>消息(会过滤peer连接中的block和tx消息)：</p>
<ul>
  <li>getheaders(headers,包含2000个)</li>
  <li>getdata(merkleblock,tx)</li>
  <li>filterload, filteradd, filterclear(<a href="https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki">BIP-37</a> 请求特定tx会暴露钱包管理的地址，所以引入Bloom Filters提高私密性)</li>
</ul>

<p>通过消息加密来提升SPV节点的隐私性</p>
<ul>
  <li>Tor</li>
  <li>P2P层面 : Peer Authentication(BIP-150), Peer-to-Peer Communication Encryption(BIP-151）</li>
</ul>

<h1 id="ch09-the-blockchain">ch09 The Blockchain</h1>
<h2 id="block">Block</h2>
<p>|Size| Field | Description |
| – | – | – |
| 4 bytes | Block Size | The size of the block, in bytes, following this field |
| 80 bytes | Block Header | Several fields form the block header |
| 1–9 bytes (VarInt) | Transaction Counter | How many transactions follow |
| Variable | Transactions | The transactions recorded in this block |</p>
<h2 id="block-header40-bytes">Block Header(40 bytes)</h2>
<p>|Size| Field | Description |
| – | – | – |
| 4 bytes | Version | A version number to track software/protocol upgrades |
| 32 bytes | Previous Block Hash | A reference to the hash of the previous (parent) block in the chain |
| 32 bytes | Merkle Root | A hash of the root of the merkle tree of this block’s transactions |
| 4 bytes | Timestamp | The approximate creation time of this block (in seconds elapsed since Unix Epoch) |
| 4 bytes | Difficulty Target | The Proof-of-Work algorithm difficulty target for this block |
| 4 bytes | Nonce | A counter used for the Proof-of-Work algorithm |</p>

<p><code class="language-plaintext highlighter-rouge">authentication path</code>, or <code class="language-plaintext highlighter-rouge">merkle path</code>: nodes in the merkle tree to make hash with, bottom-up.</p>

<p>The merkleblock message contains the block header as well as a merkle path that links the transaction of interest to the merkle root in the block</p>

<h1 id="ch12-blockchain-applications">ch12 Blockchain Applications</h1>
<h2 id="payment-channel--state-channel">payment channel / state channel</h2>
<p>funding transaction / anchor transaction (on-chain) —-&gt; commitment transactions (off-chain, each state invalidates previous state) —-&gt; settlement transaction (on-chain)</p>

<p>various mechanisms that can be used to invalidate prior state :</p>
<ul>
  <li>
    <p>transaction-level timelocks (nLocktime)</p>

    <p>The refund transaction acts as the first commitment transaction and its timelock establishes the upper bound for the channel’s life.</p>

    <p>Each commitment sets a shorter timelock, allowing it to be spent before the previous commitments become valid</p>
  </li>
  <li>
    <p>Asymmetric revocable commitments with relative time locks (CSV CheckSequenceVerify)</p>

    <p><code class="language-plaintext highlighter-rouge">time delay</code> + <code class="language-plaintext highlighter-rouge">revocation key</code> as a punishment/disadvantage/penalty</p>

    <p>我构造的（让对方签的）tx包含如下输出</p>
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  Output 0 &lt;5 bitcoin&gt;:
      &lt;对方的 Public Key&gt; CHECKSIG

  Output 1 &lt;5 bitcoin&gt;:
      IF
          # Revocation penalty output
          &lt;Revocation Public Key&gt;
      ELSE
          &lt;1000 blocks&gt;
          CHECKSEQUENCEVERIFY
          DROP
          &lt;我的 Public Key&gt;
      ENDIF
      CHECKSIG
</code></pre></div>    </div>
    <p>进入下一个state，我要revoke我自己的tx，做法是：把我的half of the revoke secret发送给对方。</p>

    <p>在每个阶段，对方也持有类似的一个tx。</p>
  </li>
</ul>

<h2 id="routed-payment-channels-lightning-network">routed payment channels (lightning network)</h2>
<p>HTLC (hash time lock contract)</p>
<ul>
  <li>hash: redeem immediately</li>
  <li>time lock: refund after timeout(if the secret is not revealed)</li>
</ul>

<p><em>疑问1</em> 在channel末端，返回private key后，为什么channel中的每个节点必须把key传给上家？当前节点有了key就可以直接得到钱了啊</p>]]></content><author><name>FangYuan Si</name></author><category term="bitcoin" /><summary type="html"><![CDATA[ch02 How Bitcoin Works Alice to Bob’s rawtx(P2PKH) 0100000001186f9f998a5aa6f048e51dd8419a14d8a0f1a8a2836dd734d2804fe65fa35779000000008b483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adfffffffff0260e31600000000001976a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788acd0ef8000000000001976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac00000000 its parent rawtx 0100000001524d288f25cada331c298e21995ad070e1d1a0793e818f2f7cfb5f6122ef3e71000000008c493046022100a59e516883459706ac2e6ed6a97ef9788942d3c96a0108f2699fa48d9a5725d1022100f9bb4434943e87901c0c96b5f3af4e7ba7b83e12c69b1edbfe6965f933fcd17d014104e5a0b4de6c09bd9d3f730ce56ff42657da3a7ec4798c0ace2459fb007236bc3249f70170509ed663da0300023a5de700998bfec49d4da4c66288a58374626c8dffffffff0180969800000000001976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac00000000 ch04 Keys, Addresses K=kG, 0&lt;k&lt;=n-1 n(1.1578 * 1077) is slightly less than 2^256(order of elliptic curve) A=RIPEMD160(SHA256(K)), or A=HASH160(K) checksum = first 4 bytes of: SHA256(SHA256(prefix + data)) Base58Check-encoded Payload = Base58(prefix + data + checksum) Base58Check version prefix and encoded result examples]]></summary></entry></feed>