NIP-13
Proof of Work
このNIPは、nostrのノート(テキスト投稿)に対して Proof of Work を生成・解釈する方法を定義する。 Proof of Work(PoW)は、ノートに対して計算作業の証明を付加する方法。これは少量のコードで任意のリレーとクライアントが普遍的に検証できる、無記名の証明である。この証明はスパム阻止の手段として用いることができる。
「難易度」(difficulty)を、NIP-01のイベントIDの「先頭から連続する0のビットの数」で定める。 例えば、ID000000000e9d97a1ab09fc381030b346cdd7a142ad57e6df0b46dc9bef6c7e2dは、先頭36ビットが0なので、難易度36となる。
マイニング
NIP-01 ノートのPoWを生成するために、nonceタグを用いる:
{"content": "It's just me mining my own business", "tags": [["nonce", "1", "21"]]}
マイニングにおいて、nonceタグの2番めの値(上の例でいう"1")が更新され、IDが再計算される(NIP-01を参照)。IDの先頭から連続する0のビット数が所望の数になったら、そのノートが採掘された(mined)ことになる。この処理ではcreated_atも更新することが望ましい。 nonceタグの3番めの値(上の例でいう"21")には目標難易度を設定すべきである(SHOULD)。
これにより、より低い難易度を目標とするスパマーが運良くもっと高い難易度の採掘を達成する、という状況からクライアントを守ることができる。
例えば、スレッドにリプライするのに40ビットの難易度を要求しているとして、(リプライのノートで)約束された目標難易度(committed target difficulty)が30であれば、もし(偶然)そのノートが40ビットの難易度を達成していたとしても安全に却下できる。目標難易度の約束がなければ、これを却下することはできない。
目標難易度へのコミットは、全ての誠実なマイナーが合意すべきことであり、クライアントは、目標難易度に適うノートであっても、難易度の約束が欠けているならば、却下してよい(MAY)。
採掘されたノートの例
code:json
{
"id": "000006d8c378af1779d2feebc7603a125d99eca0ccf1085959b307f64e5dd358",
"pubkey": "a48380f4cfcc1ad5378294fcac36439770f9c878dd880ffa94bb74ea54a6f243",
"created_at": 1651794653,
"kind": 1,
"tags": [
[
"nonce",
"776797",
"21"
]
],
"content": "It's just me mining my own business",
"sig": "284622fc0a3f4f1303455d5175f7ba962a3300d136085b9566801bc2e0699de0c7e31e44c81fb40ad9049173742e904713c3594a1da0fc5d2382a25c11aba977"
}
検証
C言語・JavaScriptによるnostrノートのIDから難易度を計算する処理の参照実装は原文を参照。 PoWつきノートをリレーにクエリする
リレーはIDの前方一致検索に対応しているので、これを特定の難易度をもつノートの検索に用いることができる。
code:sh
$ echo '["REQ", "subid", {"ids": "000000000"}]' | websocat wss://some-relay.com | jq -c '.2' {"id":"000000000121637feeb68a06c8fa7abd25774bdedfa9b6ef648386fb3b70c387", ...}
IDは16進表記なので、実際には4ビット範囲の検索になる? (上の例だと難易度36~39のノートが見つかるはず)jiftechnify.icon
Proof of Work の委譲
NIP-01ノートのIDは署名に関与しないので、PoWをPoWプロバイダ(手数料を取るものもありうる)に委託できる。
これにより、クライアントは自分で何も作業することなくPoW制限付きのリレーにメッセージを送ることができるようになる。これはモバイル端末のようなエネルギー制約をもつデバイスにおいて有用である。