<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>IPFS - Tag - 王小嗨的不老歌</title>
        <link>https://sogola.com/tags/ipfs/</link>
        <description>IPFS - Tag - 王小嗨的不老歌</description>
        <generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>high@sogola.com (王小嗨)</managingEditor>
            <webMaster>high@sogola.com (王小嗨)</webMaster><lastBuildDate>Sun, 23 Apr 2023 13:10:00 &#43;0800</lastBuildDate><atom:link href="https://sogola.com/tags/ipfs/" rel="self" type="application/rss+xml" /><item>
    <title>我的博客方案：靜態網站與 IPFS</title>
    <link>https://sogola.com/posts/deploy-a-blog/</link>
    <pubDate>Sun, 23 Apr 2023 13:10:00 &#43;0800</pubDate><author>
        <name>王小嗨</name>
    </author><guid>https://sogola.com/posts/deploy-a-blog/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/deploy-a-blog/1.png" referrerpolicy="no-referrer">
            </div><h2 id="緣起" class="headerLink">
    <a href="#%e7%b7%a3%e8%b5%b7" class="header-mark"></a>緣起</h2><p>隨著前幾年多個出名的博客服務商終止運營，或者不再提供更新與維護，國文博客開始文藝復興，重新歸復到獨立建站，個中滋味大概只有國朝網民知曉。縱然外國亦有不少博客服務商，但在互聯網開始被爭霸之中的主權國家裹挾之今日，又有哪個主權國家更高尚一些嗎？除了內容自託管，我們別無選擇。</p>
<p>內容的完全控制和方便遷移，這是我託管博客的兩大目標。考慮到國朝網路運營商對 web 端口的屏蔽，如不映射到海外服務器，那麼在自家主機上開放 HTTP/HTTPS 服務，在可預見的未來都是不可能的。為了達成這樣的目標，我選擇靜態網站託管服務與分布式儲存兩種方案。</p>
<p>選擇靜態網站的一個理由是不需要考慮數據庫的維護。相較於動態網站使用數據庫來存儲網站內容和用戶數據，靜態網站以靜態文件的形式存儲內容，進而減少了維護成本。個人使用 wordpress 的過程也有曾遭受過黑客攻擊的經歷，缺少安防經驗也促使我不再使用動態網站。除此之外，靜態網站也更易遷移，選擇靜態網站可方便地將數據從一個託管服務提供商遷移到另一個。</p>
<p>而選擇分布式儲存是由於國內網路環境的限制而不得已的選擇，同時也能有效增強自己對數據的控制權。分布式網站有很多方案，其中比較知名的有 <a href="https://zeronet.io/" target="_blank" rel="noopener noreferrer">ZeroNet</a> 和 <a href="https://ipfs.tech/" target="_blank" rel="noopener noreferrer">IPFS</a>，但 zeronet 目前已停止更新，我們的選擇可能只有 IPFS
了。</p>
<p>IPFS 全稱為 InterPlanetary File System （星際文件系統），是一個基於內容尋址的分布式存儲方案，目前有 <a href="https://brave.com/" target="_blank" rel="noopener noreferrer">Brave瀏覽器</a> 支援使用 <a href="https://ens.domains/" target="_blank" rel="noopener noreferrer">ENS域名</a> 或者傳統域名進行訪問 IPFS 網站。</p>
<p>我的網誌已經歷十幾年，雖然文章不多，但也歷經折騰，然而卻不曾介紹過我的部署方案。是時候將我的部署方案公之於眾了，以下供大家參考與批判。</p>
<h2 id="靜態網站的部署" class="headerLink">
    <a href="#%e9%9d%9c%e6%85%8b%e7%b6%b2%e7%ab%99%e7%9a%84%e9%83%a8%e7%bd%b2" class="header-mark"></a>靜態網站的部署</h2><h3 id="使用-hugo-生成靜態網站" class="headerLink">
    <a href="#%e4%bd%bf%e7%94%a8-hugo-%e7%94%9f%e6%88%90%e9%9d%9c%e6%85%8b%e7%b6%b2%e7%ab%99" class="header-mark"></a>使用 hugo 生成靜態網站</h3><p>我的博客選擇是靜態網站生成器 <a href="https://gohugo.io/" target="_blank" rel="noopener noreferrer">hugo</a>  ，主題為 <a href="https://github.com/HEIGE-PCloud/DoIt" target="_blank" rel="noopener noreferrer">DoIt</a>， DoIT 的基本配置可參考其<a href="https://hugodoit.pages.dev/zh-cn/theme-documentation-basics/" target="_blank" rel="noopener noreferrer">官方網站</a>。</p>
<ul>
<li>網誌文章的 markdown 文件放入 <code>$PWD/yoursite/content/posts</code></li>
<li>簡單頁面的 markdown 文件放入 <code>$PWD/yoursite/content/</code></li>
</ul>
<p>md 文件的名稱就是改頁面的連結，示例如下：</p>
<ul>
<li><a href="https://sogola.com/posts/godsofsanhe1111/" target="_blank" rel="noopener noreferrer">三和大神的双十一怎么过？</a>: <code>$PWD/yoursite/content/posts/godsofsanhe1111.md</code></li>
<li><a href="https://sogola.com/about/" target="_blank" rel="noopener noreferrer">關於頁面</a>: <code>$PWD/yoursite/content/about.md</code></li>
</ul>
<p>對於使用 Hugo 創建博客文章，需要注意和普通 Markdown 文件的區別。在 Hugo 中，無法使用如同普通 markdown 文件般使用 # 來標記文章標題。相反，你需要在文件內使用前置參數進行標記。以下是一個示例前置參數：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">title: &#34;三和大神的双十一怎么过？&#34;
</span></span><span class="line"><span class="cl">date: 2019-11-11T11:52:18+08:00
</span></span><span class="line"><span class="cl">lastmod: 2020-06-16T15:58:26+08:00
</span></span><span class="line"><span class="cl">draft: false
</span></span><span class="line"><span class="cl">author: &#34;王小嗨&#34;
</span></span><span class="line"><span class="cl">summary: &#34;双十一，我去三和做了一晚快递日结。&#34;
</span></span><span class="line"><span class="cl">featuredImage: &#34;/images/godsofsanhe1111/20191111.1.jpg&#34;
</span></span><span class="line"><span class="cl">images: [&#34;/images/godsofsanhe1111/20191111.1.jpg&#34;]
</span></span><span class="line"><span class="cl">toc: false
</span></span><span class="line"><span class="cl">keepStatic: false
</span></span><span class="line"><span class="cl">auto: true
</span></span><span class="line"><span class="cl">categories: [&#34;Capitalism&#34;,&#34;Life&#34;]
</span></span><span class="line"><span class="cl">tags: [&#34;三和大神&#34;,&#34;日结&#34;,&#34;零工&#34;,&#34;快递&#34;]
</span></span><span class="line"><span class="cl">license: &#39;&lt;a rel=&#34;license external nofollow noopener noreffer&#34; href=&#34;https://creativecommons.org/licenses/by-nc/3.0/&#34; target=&#34;_blank&#34;&gt;CC BY-NC 3.0&lt;/a&gt;&#39;
</span></span></code></pre></td></tr></table>
</div>
</div><p>在這個示例中，<code>title</code> 屬性標示了文章的標題，<code>date</code> 標示了文章的發布日期和時間，<code>lastmod</code> 標示文章最後修改的時間，<code>draft</code> 屬性表示文章是否是草稿狀態。另外，還有一些其他的屬性，比如前面列舉的 <code>author</code>、<code>summary</code>、<code>featuredImage</code> 等等。在這個標題之後，可以使用正常的 Markdown 語法來編寫文章的內容。其中圖片文件在 <code>$PWD/yoursite/static/images</code> 目錄。</p>
<p>在安装 hugo 程式，下載好 DoIt 主題， 完善 <code>config.toml</code> 配置文件，寫好妳的文章之後，cd 至 <code>$PWD/yoursite</code> ，運行 <code>hugo server -D</code> 可對博客網站預覽，若滿意，則運行 <code>hugo</code> 命令。在 <code>$PWD/yoursite/public</code> 目錄中，妳將會得到博客的所有靜態文件。</p>
<h3 id="將靜態網站上載至託管服務商" class="headerLink">
    <a href="#%e5%b0%87%e9%9d%9c%e6%85%8b%e7%b6%b2%e7%ab%99%e4%b8%8a%e8%bc%89%e8%87%b3%e8%a8%97%e7%ae%a1%e6%9c%8d%e5%8b%99%e5%95%86" class="header-mark"></a>將靜態網站上載至託管服務商</h3><p>有了整個網站的靜態文件，我們需將其上傳至託管服務商。目前，可供選擇服務商有好幾家，大部分服務商的免費方案都足夠個人博客使用。</p>
<ul>
<li><a href="https://vercel.com/" target="_blank" rel="noopener noreferrer">Vercel</a></li>
<li><a href="https://www.netlify.com/" target="_blank" rel="noopener noreferrer">Netlify</a></li>
<li><a href="https://pages.cloudflare.com/" target="_blank" rel="noopener noreferrer">Cloudflare Pages</a></li>
<li><a href="https://pages.github.com/" target="_blank" rel="noopener noreferrer">GitHub Pages</a></li>
<li><a href="https://fleek.co/" target="_blank" rel="noopener noreferrer">Fleek</a></li>
</ul>
<p>以上服務商，都支持綁定 GitHub 倉庫，它會自動拉取最新倉庫更新並保持同步。其中 Fleek ，不僅支持生成 http 頁面，還會將文件上傳至 IPFS 網路，給出 CID。</p>
<p>先在 GitHub 新建一個 repository， 與本地的 <code>$PWD/yoursite/public</code> 目錄進行關聯，並將博客文件上載至倉庫。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">cd $PWD/your_site/public
</span></span><span class="line"><span class="cl">git init
</span></span><span class="line"><span class="cl">git add .
</span></span><span class="line"><span class="cl">git commit -m &#34;deploy blog&#34;
</span></span><span class="line"><span class="cl">git branch -M main
</span></span><span class="line"><span class="cl">git remote add origin git@github.com:your_github_name/your_blog_repository.git
</span></span><span class="line"><span class="cl">git push -u origin main
</span></span></code></pre></td></tr></table>
</div>
</div><p>之後，有新博文之後，再重新運行 <code>hugo server -D</code> 預覽博客，若滿意，則運行 <code>hugo</code> 命令更新博客的靜態文件，再將其更新至 GitHub 倉庫。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">cd $PWD/yoursite/public
</span></span><span class="line"><span class="cl">git add .
</span></span><span class="line"><span class="cl">git commit -m &#34;blog update&#34;
</span></span><span class="line"><span class="cl">git push -u origin main
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>git push</code> 完成後，託管服務商會自動讀取倉庫更新，將其部署至服務器。</p>
<h3 id="綁定傳統域名" class="headerLink">
    <a href="#%e7%b6%81%e5%ae%9a%e5%82%b3%e7%b5%b1%e5%9f%9f%e5%90%8d" class="header-mark"></a>綁定傳統域名</h3><p>在託管服務商創建我們的博客項目並綁定 GitHub 倉庫後，通常服務商會提示我們綁定域名。如若沒有相關提示，也可以在其管理界面中方便地找到綁定域名的選項，按照其要求添加相關 DNS 記錄，比如 A 記錄 或者 CNAME 記錄。</p>
<p>為了更方便、更安全地管理域名的 DNS，建議使用 <a href="https://www.cloudflare.com/" target="_blank" rel="noopener noreferrer">Cloudflare</a> 服務。首先，在 Cloudflare 上添加域名，然後在域名服務商的管理界面中將 DNS 服務器變更為 Cloudflare 提供的 DNS 服務器，最後等待生效即可。</p>
<p>當然，如果不想購買域名的話，也可使用服務商提供的二級域名。但是，若使用自有域名，我們將更方便地將網站從一個服務商遷移至另一個，僅需更改 DNS 記錄即可。</p>
<h2 id="博客的ipfs部署方案" class="headerLink">
    <a href="#%e5%8d%9a%e5%ae%a2%e7%9a%84ipfs%e9%83%a8%e7%bd%b2%e6%96%b9%e6%a1%88" class="header-mark"></a>博客的IPFS部署方案</h2><h3 id="docker-安裝-ipfs" class="headerLink">
    <a href="#docker-%e5%ae%89%e8%a3%9d-ipfs" class="header-mark"></a>docker 安裝 IPFS</h3><p>將網誌託管給服務商固然很方便，這也增加了被審查與阻斷的風險。作為國朝臣民，我們天然地對任何服務商沒有信任。如果選擇 IPFS 方案託管網誌，這無疑將大大地治癒我們的書報檢查PTSD。但要特別注意：IPNS 並不匿蹤，書寫與言說就要承受利維坦之重，請審慎考量再使用鍵鼠。</p>
<p>IPFS 擁有一個域名系統 IPNS (InterPlanetary File System)，可讓我們更方便地配合域名使用 IPFS ， IPFS 託管網站的要義是用戶自己控制 IPNS 的 private key (私鑰)。儘管已有提供 IPNS 託管服務的選項，但這要付出信任成本。如若選擇自行生成與託管 IPNS Key ，這是一個 trustless 的抉擇，只要自己做好安全風險的管控。</p>
<p>要進行 IPFS 網站的自託管，首先要 安裝 IPFS 程式。因為需要 7*24 的不間斷服務，將 IPFS 安裝在功耗較低的小主機是一個好的選擇，所有選擇 docker 安裝 IPFS 是一個好的選項。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">docker</span> <span class="n">run</span> <span class="o">-</span><span class="n">d</span> <span class="o">--</span><span class="n">name</span> <span class="n">ipfs</span> \
</span></span><span class="line"><span class="cl">  <span class="o">-</span><span class="n">v</span> <span class="o">$</span><span class="n">PWD</span><span class="o">/</span><span class="n">docker</span><span class="o">/</span><span class="n">ipfs</span><span class="o">/</span><span class="n">ipfs</span><span class="p">:</span><span class="o">/</span><span class="n">data</span><span class="o">/</span><span class="n">ipfs</span> \
</span></span><span class="line"><span class="cl">  <span class="o">-</span><span class="n">v</span> <span class="o">$</span><span class="n">PWD</span><span class="o">/</span><span class="n">docker</span><span class="o">/</span><span class="n">ipfs</span><span class="o">/</span><span class="k">export</span><span class="p">:</span><span class="o">/</span><span class="k">export</span> \
</span></span><span class="line"><span class="cl">  <span class="o">-</span><span class="n">u</span> <span class="mi">1000</span><span class="p">:</span><span class="mi">1000</span> \
</span></span><span class="line"><span class="cl">  <span class="o">-</span><span class="n">p</span> <span class="mi">4001</span><span class="p">:</span><span class="mi">4001</span> \
</span></span><span class="line"><span class="cl">  <span class="o">-</span><span class="n">p</span> <span class="mi">8080</span><span class="p">:</span><span class="mi">8080</span> \
</span></span><span class="line"><span class="cl">  <span class="n">ipfs</span><span class="o">/</span><span class="n">go</span><span class="o">-</span><span class="n">ipfs</span><span class="p">:</span><span class="n">latest</span>  
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="生成-ipns-key-並綁定域名" class="headerLink">
    <a href="#%e7%94%9f%e6%88%90-ipns-key-%e4%b8%a6%e7%b6%81%e5%ae%9a%e5%9f%9f%e5%90%8d" class="header-mark"></a>生成 IPNS Key ，並綁定域名</h3><p>安裝完成後，進入 IPFS 容器的 Shell ，運行以下命令，將服務应用 lowpower 配置，這會優化 IPFS 資源的佔用情況。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">ipfs config profile apply lowpower
</span></span></code></pre></td></tr></table>
</div>
</div><p>接著在 Shell 中， cd 至 <code>export</code> 目錄，運行以下命令，生成一個 IPNS key pair。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">ipfs key gen your_key_name
</span></span></code></pre></td></tr></table>
</div>
</div><p>記錄給出的 IPNS 的 public key (公鑰)，並使用以下命令將其導出。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">ipfs</span> <span class="n">key</span> <span class="k">export</span> <span class="n">your_key_name</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在文件管理中，進入至 <code>$PWD/docker/ipfs/export</code> ，將目錄中的 Key 文件妥善保管，以下是 IPFS KEY 管理的命令。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="n">ipfs</span> <span class="n">key</span> <span class="k">export</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span>           <span class="o">-</span> <span class="n">Export</span> <span class="n">a</span> <span class="n">keypair</span>
</span></span><span class="line"><span class="cl"><span class="n">ipfs</span> <span class="n">key</span> <span class="n">gen</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span>              <span class="o">-</span> <span class="n">Create</span> <span class="n">a</span> <span class="n">new</span> <span class="n">keypair</span>
</span></span><span class="line"><span class="cl"><span class="n">ipfs</span> <span class="n">key</span> <span class="n">import</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="n">key</span><span class="o">&gt;</span>     <span class="o">-</span> <span class="n">Import</span> <span class="n">a</span> <span class="n">key</span> <span class="ow">and</span> <span class="nb">prints</span> <span class="n">imported</span> <span class="n">key</span> <span class="n">id</span>
</span></span><span class="line"><span class="cl"><span class="n">ipfs</span> <span class="n">key</span> <span class="n">list</span>                    <span class="o">-</span> <span class="n">List</span> <span class="n">all</span> <span class="n">local</span> <span class="n">keypairs</span><span class="o">.</span>
</span></span><span class="line"><span class="cl"><span class="n">ipfs</span> <span class="n">key</span> <span class="n">rename</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="n">newName</span><span class="o">&gt;</span> <span class="o">-</span> <span class="n">Rename</span> <span class="n">a</span> <span class="n">keypair</span><span class="o">.</span>
</span></span><span class="line"><span class="cl"><span class="n">ipfs</span> <span class="n">key</span> <span class="n">rm</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;...</span>            <span class="o">-</span> <span class="n">Remove</span> <span class="n">a</span> <span class="n">keypair</span><span class="o">.</span>
</span></span><span class="line"><span class="cl"><span class="n">ipfs</span> <span class="n">key</span> <span class="n">rotate</span>                  <span class="o">-</span> <span class="n">Rotates</span> <span class="n">the</span> <span class="n">IPFS</span> <span class="n">identity</span><span class="o">.</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>有了 IPNS Key 之後，就可將內容的 CID 發布到 IPNS 。如果直接訪問 IPFS 公鑰，當然也可以，但也這讓訪問者望而卻步，一大串字符讓人望而卻步。為了方便記憶，我們需要將 IPNS 與域名綁定，綁定方法可參考我的文章<a href="https://sogola.com/posts/planet/" target="_blank" rel="noopener noreferrer">Planet：一款IPFS静态站点生成器</a>中的域名绑定綁定部分。</p>
<h3 id="自動更新-ipns" class="headerLink">
    <a href="#%e8%87%aa%e5%8b%95%e6%9b%b4%e6%96%b0-ipns" class="header-mark"></a>自動更新 IPNS</h3><p>使用 IPFS 自託管靜態網站，主要是因為其分布式特性，它讓我們重拾萬維網之互聯真義。然而，由於個人博客的讀者不多，使用 IPFS 的用戶更是寥寥無幾，因此在 IPFS 自託管的同時，使用 remote pinning services 來提高網站的可用性是個不錯的選擇。</p>
<p>在介紹靜態網站託管服務商的時候，有提到 <a href="https://fleek.co/" target="_blank" rel="noopener noreferrer">Fleek</a> ，它就有提供 remote pinning services ，在生成動態網站的同時，可生成一個網站的 CID。</p>
<p>如果我們在每次更新網站後，從 Fleek 生成的域名讀取出它綁定的 CID，並在本地 pin 這個 CID，然後再將其發布至我們自己的 IPNS ，那麼我們就可以實現同時更新靜態網站服務商和 IPNS 託管。所以，我請 ChatGPT 寫了可自動這一系列操作的腳本，如下所示。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Script: update-ipns.sh</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Description: Check if IPNS record needs to be updated and update it if necessary.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Function: get IPNS CID</span>
</span></span><span class="line"><span class="cl">get_ipns_cid<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> <span class="nv">ipns_name</span><span class="o">=</span><span class="nv">$1</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> <span class="nv">ipfs_container</span><span class="o">=</span><span class="nv">$2</span>
</span></span><span class="line"><span class="cl">  docker <span class="nb">exec</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">ipfs_container</span><span class="si">}</span><span class="s2">&#34;</span> ipfs resolve -r <span class="s2">&#34;/ipns/</span><span class="si">${</span><span class="nv">ipns_name</span><span class="si">}</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    <span class="p">|</span> tail -n1 <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    <span class="p">|</span> awk <span class="s1">&#39;{ print $NF }&#39;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Variables: define container name, IPNS names and options</span>
</span></span><span class="line"><span class="cl"><span class="nv">IPFS_CONTAINER</span><span class="o">=</span><span class="s2">&#34;ipfs&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">SOGOLA_IPNS</span><span class="o">=</span><span class="s2">&#34;your_domain_name&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">FLEEK_IPNS</span><span class="o">=</span><span class="s2">&#34;your_fleek_site_name.on.fleek.co&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">PIN_OPTS</span><span class="o">=</span><span class="s2">&#34;--progress&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">PUBLISH_OPTS</span><span class="o">=</span><span class="s2">&#34;--key=your_ipns_public_key&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Check if the IPFS container is running</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> ! <span class="s2">&#34;</span><span class="k">$(</span>docker ps -q -f <span class="nv">name</span><span class="o">=</span><span class="si">${</span><span class="nv">IPFS_CONTAINER</span><span class="si">}</span><span class="k">)</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">IPFS_CONTAINER</span><span class="si">}</span><span class="s2"> container is not running. Please start the container and try again.&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get IPNS CID</span>
</span></span><span class="line"><span class="cl"><span class="nv">SOGOLA_CID</span><span class="o">=</span><span class="k">$(</span>get_ipns_cid <span class="s2">&#34;</span><span class="si">${</span><span class="nv">SOGOLA_IPNS</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">IPFS_CONTAINER</span><span class="si">}</span><span class="s2">&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">FLEEK_CID</span><span class="o">=</span><span class="k">$(</span>get_ipns_cid <span class="s2">&#34;</span><span class="si">${</span><span class="nv">FLEEK_IPNS</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">IPFS_CONTAINER</span><span class="si">}</span><span class="s2">&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Check if IPNS record needs update</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">SOGOLA_CID</span><span class="si">}</span><span class="s2">&#34;</span> !<span class="o">=</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">FLEEK_CID</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># Publish new IPNS record</span>
</span></span><span class="line"><span class="cl">  docker <span class="nb">exec</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">IPFS_CONTAINER</span><span class="si">}</span><span class="s2">&#34;</span> ipfs name publish <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PUBLISH_OPTS</span><span class="si">}</span><span class="s2">&#34;</span> --lifetime<span class="o">=</span>8766h -- <span class="s2">&#34;</span><span class="si">${</span><span class="nv">FLEEK_CID</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># Unpin the previous IPNS record</span>
</span></span><span class="line"><span class="cl">  docker <span class="nb">exec</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">IPFS_CONTAINER</span><span class="si">}</span><span class="s2">&#34;</span> ipfs pin rm <span class="s2">&#34;</span><span class="si">${</span><span class="nv">SOGOLA_CID</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># Pin the updated IPNS record</span>
</span></span><span class="line"><span class="cl">  docker <span class="nb">exec</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">IPFS_CONTAINER</span><span class="si">}</span><span class="s2">&#34;</span> ipfs pin add <span class="s2">&#34;</span><span class="si">${</span><span class="nv">PIN_OPTS</span><span class="si">}</span><span class="s2">&#34;</span> -- <span class="s2">&#34;</span><span class="si">${</span><span class="nv">FLEEK_CID</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;IPNS record updated successfully.&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;IPNS record is already up-to-date, no need to update.&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add error handling</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> -eq <span class="m">0</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;Update completed.&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;Error occurred while updating IPNS record. Please check.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">exit</span> <span class="m">1</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>將上述腳本中的 SOGOLA_IPNS,FLEEK_IPNS,PUBLISH_OPTS 分別替換並保存為 <code>update-ipns.sh</code> ，使用自動化工具定時執行，即可使用 Git 更新博客後，實現靜態網站的 HTTP 與 IPFS 同時更新的功能。</p>
<p>如果覺得只有一個 remote pinning service 不保險的話，還可以使用 <a href="https://dashboard.4everland.org?invite=BB0BLBGV" target="_blank" rel="noopener noreferrer">4EVERLAND</a> ，這個服務商支持使用 IPNS 進行 PIN。</p>
<h2 id="總結" class="headerLink">
    <a href="#%e7%b8%bd%e7%b5%90" class="header-mark"></a>總結</h2><p>透過個間網站託管服務商，我們可以通過控制域名來遊走之間，輕鬆實現切換服務商。而通過自託管 IPFS ，拜分布式託管之幸，我們終可回歸到萬維網之本心，重新掌握我們自己的數據。</p>
<p>就撰寫這篇博文期間，我留意到<a href="https://www.solidot.org/story?sid=74728" target="_blank" rel="noopener noreferrer">一則新聞</a>，ICANN 和 Verisign 提议允许任何政府扣押域名。是時候，我們該嘗試無許可與去信任的 crypto 了。</p>
<blockquote>
<p>整治書報檢查制度的真正而根本的辦法，就是廢除書報檢查制度，因為這種制度本身是惡劣的，可是各種制度卻比人更有力量。我們的意見可能是正確的，也可能是不正確的，不過無論如何，新的檢查令終究會使普魯士的作者要么獲得更多的現實的自由，要么獲得更多的觀念的自由，也就是獲得更多的意識。</p>
<p>Rara temporum felicitas, ubi quae velis sentire et quae sentias dicere licet［當你能夠想你願意想的東西，並且能夠把你所想的東西說出來的時候，這是非常幸福的時候］。</p>
<p>————馬克思《評普魯士最近的書報檢查令》</p>
</blockquote>
<p>「清風不識字」，主權國家宰制一切。當言說成為禁忌，開設一個部落格已然成為罪證，我只祝福妳們成為幸福的人。那些獨立博客的作者有福了，因為妳們必然承受大地之重。</p>
]]></description>
</item><item>
    <title>matters.news：一个故弄玄虚的伪去中心化站点</title>
    <link>https://sogola.com/posts/mattersnews/</link>
    <pubDate>Tue, 11 Oct 2022 17:30:00 &#43;0800</pubDate><author>
        <name>王小嗨</name>
    </author><guid>https://sogola.com/posts/mattersnews/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/mattersnews/1.png" referrerpolicy="no-referrer">
            </div><p>在展开之前，我们先要明确一点，web3的要义是个人主权，意即用户可以自主地控制自己的数据。</p>
<p>这里，我列举两点matters的做法。</p>
<ul>
<li>不许用户修改用户名和绑定的likerid和eth地址</li>
<li>诱导用户将IPFS认知为永久储存</li>
</ul>
<p>就连臭名昭著的微信都允许用户定期进行用户名的修改，可matters并未有任何修改用户名（Matters ID）或注销账户的选项。这与其宣称的「生態：自主、自由」完全背离。</p>
<p>事实上，所谓的 Matters ID，抑或账户与 likerid 与eth 地址的绑定，只是 matters.news 的数据库上的一串数字而已，并未存储在 blockchain 之上，完全不存在不能修改的技术问题。</p>
<p>早先，我有给 matters.news 发过电子邮件，要求解除likerid绑定，得到回复如下：</p>
<blockquote>
<p>Liker ID 目前無法解綁或更換。</p>
</blockquote>
<p>坦率地讲，使用过区块链钱包的人都知晓，目前的crypto世界是一片黑暗森林，没人可完全保证自己永久地掌控一个钱包地址，不能解除绑定，这不仅增加被盗钱包用户的风险，也给其它用户带来风险。</p>
<p>如此来看，用户在 matters.news 上毫无自主的权利。</p>
<p>倘若用户在 matters.news 上发布文章，再想删除的话，那么抱歉了，因为 matters.news 仅提供隐藏文章的选项，只能隐藏。对此，matters.news的解释是一旦储存在IPFS上就无法删除。如此敷衍的解释，只会诱导用户将IPFS认知为永久储存。</p>
<p>虽然一个文件一旦储存在IPFS之上，真的没法删除，但不代表这个文件不会消失，也不代表这个文件一定与这个用户在 matters.news 的数据之间存在绑定关系。</p>
<p>要知道，一个IPFS文件，如果长久的没有节点对其进行存储，自然就会消失。嗯，互联网是没有记忆的。但 matters.news 将储存在IPFS之上的文件用户进行永恒绑定，这是打算自行付费将全站文章存储到天荒地老？</p>
<figure>
</figure>

<p>亦有<a href="https://matters.news/@mthree/130425-%E5%85%AC%E5%91%8A-%E7%AE%A1%E7%90%86%E5%91%98%E6%81%B6%E6%84%8F%E5%88%A0%E9%99%A4%E6%9C%AC%E4%BA%BA%E6%96%87%E7%AB%A0-bafyreibia52hidunyzn5s2hsgtxozz5ugf4qhqhxv2k2an5vieefk4ijni" target="_blank" rel="noopener noreferrer">用户反应</a> matters.news 「管理员」将其文章恶意隐藏，它们丝毫不掩饰其中心化平台的狰狞面目。「去中心化的創作社群與內容生態」，看起来像个地狱笑话。</p>
<p>最近一段时间，matters.news 在其首页疯狂推送NFT等诈骗信息，也许是时候该NFT祛魅了。</p>
<p>这样的平台，我反正不会去使用。</p>
]]></description>
</item><item>
    <title>Planet：一款IPFS静态站点生成器</title>
    <link>https://sogola.com/posts/planet/</link>
    <pubDate>Sat, 03 Sep 2022 11:52:18 &#43;0800</pubDate><author>
        <name>王小嗨</name>
    </author><guid>https://sogola.com/posts/planet/</guid>
    <description><![CDATA[<div class="featured-image">
                <img src="/images/planet/1.png" referrerpolicy="no-referrer">
            </div><p>对于不少人来说，搭建一个自己的网站是件不好入手的事情。抛开一系列眼花缭乱的技术术语，还需搞定服务器、域名、建站工具等等，这些都要气力去认知与实践。况且随着互联网寡头横行霸道，似乎发布或拥有一个网志站点已变为画蛇添足的笨蛋行为。</p>
<p>万幸，分布式网路虽英雄末路，但还未乘鹤西去，已有开发者将发布分布式网站做成了一件用户操作友好的事情。妳只需在macOS上安装Planet，就可将IPFS作为托管服务器，几下点击就可发布一个网志站点。</p>
<h2 id="planet的缘起" class="headerLink">
    <a href="#planet%e7%9a%84%e7%bc%98%e8%b5%b7" class="header-mark"></a>Planet的缘起</h2><p>Planet的创始人Livid也是大型程序员交友网站<a href="https://www.v2ex.com/" target="_blank" rel="noopener noreferrer">v2ex</a>的创始人，在Planet发布前的<a href="https://www.xiaoyuzhoufm.com/episode/626ba660bf39836fd02b78e9" target="_blank" rel="noopener noreferrer">一档播客访谈</a>
中，Livid称维护v2ex的服务器与数据库是一件漫长且痛苦的事情，并表示如果再开发一款程序，自己不会选择再托管用户的数据。</p>
<blockquote>
<p>星际文件系统（Interplanetary File System，缩写为IPFS）是一个旨在实现文件的分布式存储、共享和持久化的网络传输协议。[2]它是一种内容可寻址（英语：Content-addressable storage）的对等超媒体分发协议。在IPFS网络中的节点构成一个分布式文件系统。</p>
<p>——<a href="https://zh.m.wikipedia.org/zh-hans/%E6%98%9F%E9%99%85%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F" target="_blank" rel="noopener noreferrer">维基百科「星际文件系统」词条</a></p>
</blockquote>
<p>IPFS作为分布式网路技术，并且可实现用户自己托管自己的数据，这让Livid看到了光亮，遂有了开发Planet的想法。西元2022年07月11日，Livid在v2ex<a href="https://www.v2ex.com/t/857404" target="_blank" rel="noopener noreferrer">发帖</a>，「如果你之前用过 IPFS 或者 ENS，你可能会想要试试我们在做的这个App」，Planet正式上线。</p>
<p>Livid在访谈中表示，底层协议的迭代已经成熟，分布式站点完全可能，Planet会做一个用户友好的进入分布式的入口。</p>
<h2 id="站点的访问" class="headerLink">
    <a href="#%e7%ab%99%e7%82%b9%e7%9a%84%e8%ae%bf%e9%97%ae" class="header-mark"></a>站点的访问</h2><p>在开始使用Planet部署自己的分布式站点之前，我们有必要有了解一下访问一个万维网站点的过程。</p>
<figure><figcaption>
            <h4>浏览器访问万维网过程的简易示意图</h4>
        </figcaption>
</figure>

<p>在访问传统万维网站点的过程中，首先浏览器要跟DNS服务器请求服务器地址，我们可以把这个过程想象成在手机地图中输入商家名称，获得商家地址；然后，有服务器地址，浏览器就可以与服务器建立连接，我们可以把这个过程想象成有商家地址，我们就可以乘坐共同交通前往与返回；最后，当建立了连接，客户浏览器就可以发送需要的文件，服务器收到了这个请求，就会将相应的文件返回给浏览器，浏览器得到文件就可以将内容显示给用户，我们可以将这个过程想象成我们在外送app上点了一个红烧肉，商家收到了订单，做好后就发送给用户。</p>
<figure><figcaption>
            <h4>世界上第一台服务器</h4>
        </figcaption>
</figure>

<p>也许有人会问，什么是服务器呢？事实上，服务器就是一台电脑，任何联网的设备都可以成为一台服务器，妳的手机或电脑都可以作为服务器供她人访问。被提姆·柏内兹-李在CERN所使用的这台NeXT计算机成为了世界上第一台网页服务器，上面写着「这台机器是服务器，不要关闭电源」。</p>
<p>然而，时至今日，互联网寡头大行其道，加之国内糟糕的联网环境，已经很少人在家中自行搭建站点服务器了。我们平时所访问站点更多是托管在云服务器商（阿里云、亚马逊云等等）之上，这与万维网的理念完全背离，回滚到电台广播的时代。「偷听敌台」，「私建电台」，已然成为抗命行为。</p>
<p>那么，Planet生成的IPFS站点有什么不同？</p>
<figure><figcaption>
            <h4>浏览器通过ENS域名访问IPFS站点的简易示意图</h4>
        </figcaption>
</figure>

<p>我们可以简单地认为IPNS代替了传统域名和DNS服务器，IPFS代替了服务器。</p>
<p>一个网站主要使用由域名与服务器构成，与传统站点不同，IPFS的域名与服务器可完全实现分布式。IPNS是IPFS生态中的一个重要组件，全称是 Interplanetary Name System，一个去中心化的类似域名的系统。IPNS可绑定在一些去中心域名，也可绑定在传统域名域名中。而由于IPFS是一个分布式文件存储系统，所以使用IPFS作为站点服务器，也就实现了服务器的分布式。</p>
<h2 id="开始使用" class="headerLink">
    <a href="#%e5%bc%80%e5%a7%8b%e4%bd%bf%e7%94%a8" class="header-mark"></a>开始使用</h2><figure><figcaption>
            <h4>点击「Download for Mac」下载</h4>
        </figcaption>
</figure>

<p>Planet是一个开源的macOS原生App，我们通过它的<a href="https://www.planetable.xyz/" target="_blank" rel="noopener noreferrer">官網</a>与<a href="https://github.com/Planetable/Planet" target="_blank" rel="noopener noreferrer">GitHub</a>进行下载。</p>
<p>下载安装完成后，打开Planet，它会自动follow这两个站点：</p>
<ul>
<li>vitalik.eth - Ethereum 的创始人之一</li>
<li>Planetable.eth - Planet 项目的博客</li>
</ul>
<figure><figcaption>
            <h4>点击主界面下方的加号</h4>
        </figcaption>
</figure>

<figure><figcaption>
            <h4>写入名字与简介，选择模版，创建自己的Planet</h4>
        </figcaption>
</figure>

<figure><figcaption>
            <h4>点击撰写按钮</h4>
        </figcaption>
</figure>

<figure><figcaption>
            <h4>写入网志内容，并点击发布</h4>
        </figcaption>
</figure>

<p>发布完第一个篇文章之后，妳的 Planet 就会被发布为一个 IPNS。右键点击侧栏里你的站点，选择 Copy IPNS。然后你就会在剪贴板中获得像这样的一串东西：</p>
<figure><figcaption>
            <h4>Copy IPNS</h4>
        </figcaption>
</figure>

<p>k51qzi5uqu5dhxd50115dn1hfvuwiqwej3dki72uyopetqua71i6lp96pem0a6</p>
<p>然后妳把这串IPNS发给其它Planet用户，她们就可以收到来自妳的更新了。</p>
<p>妳用Planet发布的网站，也可能可以通过各种 Public Gateway 访问，比如这是你当前正在阅读的这篇文章在各个 Gateway 上的地址（URL 拼接规则是 Public Gateway 域名 + /ipns/ + Planet.ipns + / + Article.UUID）：</p>
<ul>
<li>ipfs.io</li>
<li>dweb.link</li>
<li>cf-ipfs.com</li>
</ul>
<h2 id="域名绑定" class="headerLink">
    <a href="#%e5%9f%9f%e5%90%8d%e7%bb%91%e5%ae%9a" class="header-mark"></a>域名绑定</h2><h3 id="传统域名绑定" class="headerLink">
    <a href="#%e4%bc%a0%e7%bb%9f%e5%9f%9f%e5%90%8d%e7%bb%91%e5%ae%9a" class="header-mark"></a>传统域名绑定</h3><p>绑定传统域名，需要使用的是<a href="https://docs.ipfs.tech/concepts/dnslink/" target="_blank" rel="noopener noreferrer">DNSlink</a>服务，大概的意思就是在DNS上写入txt记录，以供读取。因为使用到传统的DNS服务，所以IPNS关联到传统域名，并非是一个去中心的解决方案。</p>
<figure>
</figure>

<p>例如，绑定Planet到sogola.com主域名，</p>
<p>IPNS的地址：</p>
<p>k51qzi5uqu5dhxd50115dn1hfvuwiqwej3dki72uyopetqua71i6lp96pem0a6</p>
<p>则到域名DNS管理页上创建一个txt记录</p>
<p>设置name值为：</p>
<ul>
<li>_dnslink</li>
</ul>
<p>设置Content值为：</p>
<ul>
<li>dnslink=/ipns/k51qzi5uqu5dhxd50115dn1hfvuwiqwej3dki72uyopetqua71i6lp96pem0a6</li>
</ul>
<figure>
</figure>

<p>例如，绑定Planet到www.sogola.com二级域名，</p>
<p>设置name值为：</p>
<ul>
<li>_dnslink.www</li>
</ul>
<p>设置Content值为：</p>
<ul>
<li>dnslink=/ipns/k51qzi5uqu5dhxd50115dn1hfvuwiqwej3dki72uyopetqua71i6lp96pem0a6</li>
</ul>
<figure>
</figure>

<p>等待DNS生效，使用原生支持IPFS的Brave浏览器就可以直接访问 ipns://sogola.com/ 。</p>
<figure>
</figure>

<p>如果在DNS中添加cloudflare的IPFS gateway，也可以使用普通浏览器的访问。</p>
<h3 id="ens绑定" class="headerLink">
    <a href="#ens%e7%bb%91%e5%ae%9a" class="header-mark"></a>ENS绑定</h3><p>使用ENS绑定IPNS，就是利用Ethereum账本作为DNS账本。在ENS合约之中，将IPNS地址记录到Content Hash，这样任何人都可以访问Ethereum账本，查询相应的ENS绑定的IPNS。</p>
<p>因为设定Content Hash会是一个 ENS 合约上的操作，所以这一步会有gas fee。但是之后妳在 Planet里发布新的内容，妳的IPNS不会发生改变，也不会再有gas fee的问题。</p>
<figure>
</figure>

<p>首先，打开ENS管理页面 <a href="https://app.ens.domains/" target="_blank" rel="noopener noreferrer">https://app.ens.domains/</a></p>
<p>ipns://k51qzi5uqu5dhxd50115dn1hfvuwiqwej3dki72uyopetqua71i6lp96pem0a6</p>
<p>然后，将IPNS写入Content Hash，并确定上链。</p>
<figure>
</figure>

<p>这里有一个小tip，如果妳并不着急解析立刻失效，可自定义Max base fee和Priority fee。在metamask中打开gas fee的高级管理选项，在确认操作的时候，编辑gas fee选项即可。</p>
<p>在完成了ENS绑定之后，也可以直接用类似下面这样的地址通过Public Gateway打开妳的 ENS：</p>
<ul>
<li><a href="https://ipfs.io/ipns/sogola.eth" target="_blank" rel="noopener noreferrer">https://ipfs.io/ipns/sogola.eth</a></li>
<li><a href="https://sogola.eth.limo" target="_blank" rel="noopener noreferrer">https://sogola.eth.limo</a></li>
</ul>
<figure>
</figure>

<p>在原生支持IPFS的Brave浏览器里，你甚至可以用 ipns://sogola.eth 这样的地址直接打开妳的IPFS站点。</p>
<h2 id="关于planet的疑问" class="headerLink">
    <a href="#%e5%85%b3%e4%ba%8eplanet%e7%9a%84%e7%96%91%e9%97%ae" class="header-mark"></a>关于Planet的疑问</h2><blockquote>
<p>阅读器用自己的格式渲染原文，可以让体验更一致，及对离线阅读更友好。但对于网站的原作者，会丢失原始网站的设计及影响源网站的利益。</p>
<p>—— Livid在Planet中的发言</p>
</blockquote>
<p>使用Planet订阅Planet、IPFS站点或RSS，会自动加载站点的原生样式，这样的做法无疑是在开发一款浏览器，而非阅读器。对于读者用户来讲，这不是一个好的体验，比较kindle这样的电纸书也不会不允许读者自定义图书的样式。至于创作者的收益与读者的便利，我想肯定应该会有一个平衡点，但将阅读器重新发明为浏览器，无疑不是一种好的选择。</p>
<p>因为IPFS的特性，Planet站点使用普通域名往往访问过慢，这时候每个用户要尽可能地获得更多follower。</p>
<p>对于这一点，Livid在用户聊天群中表示：将来可以成立一个数据DAO来提供托管服务，但目前的主要工作还是完善软件、扩大用户数量。</p>
<p>Planet目前只支援macOS，至于使用更为普遍的Windows，开发者好像并没有支援计划。桌面操作系统的份额，Windows是最大，分布式网路依靠用户数量壮大才能取胜，只支援macOS与扩大节点数量是存在矛盾的，我们只能寄希望于有其它开发者会开发一款兼容Windows的客户端。</p>
<p>如果使用过程中遇到什么问题，可进入Planet的中文用户群，Livid是一位热心的开发者，他很乐意与用户交流。</p>
<p><a href="https://t.me/&#43;5bl7FIsxeChlOWIz" target="_blank" rel="noopener noreferrer">https://t.me/+5bl7FIsxeChlOWIz</a></p>
<p>最后，衷心地祝福Planet做强做大，分布式永垂不朽。</p>
<h2 id="参考资料" class="headerLink">
    <a href="#%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99" class="header-mark"></a>参考资料</h2><ul>
<li>Livid的Planet <a href="https://olivida.eth.limo" target="_blank" rel="noopener noreferrer">https://olivida.eth.limo</a></li>
</ul>
]]></description>
</item></channel>
</rss>
