一件确定性生成艺术作品。代码和种子决定图像,图像本身不在链上。 同一份代码加同一个种子,在任何机器上都必须得到同一张图——这个页面就是为了让人验证这一点。
作品和 manifest 各一笔铭文,已确认在区块 1,586,885。字节与本地构建一致;inscribe/audit.mjs 不读本地记录,直接从交易里重解信封、重算 taproot 承诺与 BIP341 签名,共 30 项检查全部通过。
| 铭文 | txid | 字节 | 确认 |
|---|---|---|---|
| generator | d46a8d4d…e314ef | 5,721 | 区块 1,586,885 |
| manifest | 106d4c2e…b404ad | 600 | 区块 1,586,885 |
测试网的 ord 索引停在 1,416,517(主链 1,586,885,落后 170,368 块),官方的 /content/<id> 返回 HTTP 500。确认没有改变这一点——内容在链上,不等于内容可访问。
所以本站自己实现了读的一侧:/content/<txid> 不查索引库,直接取交易、从 witness 里解出信封,返回铭刻时的字节。点开就是作品本身,也可以直接喂给查看器。
同一份输出,在两套完全不同的运行时里逐字节复现。conformance/port/ink_field.py
只用 Python 标准库,与 JS 版不共享一行代码——它把 Math.imul 的 32 位回绕、
>>> 的逻辑右移、Math.round 的 half-up、数字转字符串的最短往返,
逐条重写了一遍。
| 层 | 向量 | 钉住什么 |
|---|---|---|
| sha256 | 6 | 先证明哈希是对的,否则下面的种子全是噪声 |
| round2 | 17 | 舍入语义:half-up,不是 toFixed,也不是 Python 的 round |
| num2str | 11 | 数字 → 字符串:1000 不是 1000.0 |
| state | 23 | seed → PRNG 的四个 uint32 |
| seed | 27 | 18 组派生 + 9 组必须被拒(大小写、前导零、越界) |
| artwork | 23 | seed → sha256(SVG) 与 traits |
11 个典型移植错误全部被抓。第一轮有 1 个存活——23 个作品向量都放过了
half-up 换成 banker's rounding,因为没有种子恰好落在 .5 上。原语级向量就是这么来的。
用交易哈希做种子在比特币上是可以 grind 的:txid 由输入输出决定,买家换个找零地址就得到全新的 txid, 离线试几千次、挑一个自己喜欢的,成本接近零。所以种子取自开售后第 6 个区块的哈希—— 铸造时它还不存在,连艺术家也预筛不了。代价是铸造后有约三分钟的「未揭示」窗口,那是设计意图。
公式只有一行,所以它必须精确到字节,否则两套实现会各自「合理」地算出不同的图:
work.html 画——与链上那 5,721 字节完全相同的那份。| token | seed(前 24 位) |
|---|---|
| 0 | d414f951d8d2918851044d45… |
| 1 | 14d897fdd387954464118afd… |
| 2 | 981d60224cc82abb75d5177a… |
| 63 | ddcad67c9f2580a7a06ec47d… |
区块 1,586,891 的哈希是
0000000043d6291b002339fc979b6a89bb9dfcde52727ab83f0c66d4f19da697,可以在 测试网浏览器上核对;
跑 node scripts/seed.mjs demo 会连上链、重取一次这个哈希再算。
crypto.subtle 重算哈希做完整性校验。/content/<id>,其余逻辑不变。