バーンアドレスとはイーサリアムではそう呼ばれている、秘密鍵のない(わからない)アドレスとして定義されているものです。
そのアカウントからは如何なるトランザクション操作ができないため、そこに送られたトークンは実質的に抹消という扱いになります。
イーサリアムにおいては0x000000000000000000000000000000000000000000000
というアドレスがバーンアドレスとして用いられるようです。
Symbolには少なくともドキュメントを見る限りはそのような仕様が見当たらなかったので、いろいろと試してみました。
長々と書いてますが、結論としてバーンアドレスとしてのアドレスは用意されていない(調べた限り名付けられていない)、が、ネメシスアカウントへ送るのが代替策としてベストと結論づけました。
ただし、必要十分な方法として選択肢は複数あると考えられますので、ニーズに合わせた方法を取るといいと思います。
バーンアドレスを作ってみる
任意のアドレスを作ってみる
Symbolにおいて、アドレスは(APIの生の値)か
(一般的なフォーマット)で表現され、後者の表現が主に用いられます。
先頭一文字はネットワークを表し、次の一文字はA,B,C,Dのいずれかという決まりがあります。
また、3byteのチェックサムが入っているようです。
そのため、適当にTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
のようなアドレスを作っても、エラーになってしまいました。
{
"hash": "BE34DCF3857E6B66C0D38E29224D5579F63A3F07B9B6F9A69AD9EB22D41E7511",
"code": "Failure_Core_Invalid_Address",
"deadline": "85792955974"
}
チェックサムが成立するように調整したら、通るかもしれませんが、仮にそうやって作り出したアドレスの秘密鍵を絶対に持っていないという証明ができません。
しかし、後述の通り十分に秘密鍵を見つけることが困難であれば選択肢としてはありだと思います。
任意のアドレスを作り出す方法は別途検証しようと思います。
公開鍵を"0"埋めにしてみる
なんとなくイーサリアムのアドレスを真似して、公開鍵を0000000000000000000000000000000000000000000000000000000000000000
(0が64個)で埋めてみてはどうでしょうか。
const seed = "0".repeat(64);
const publicAccount = facade.createPublicAccount(new PublicKey(seed));
console.debug(publicAccount.address.toString())
// => "TAXQUTQQNS6JEJG7PLC6FRVJ2USS44GLMVULPGQ"
このアドレスpublicAccount.address
を宛先にしてトランザクションを発信してみるとエラーになりました。
{
"hash": "9288F3E975935EC04E2C08FA6A9B4F8E537D96D660DD8C8187D3A5D7D1093E5C",
"code": "Failure_Core_Zero_Address",
"deadline": "85792827198"
}
これはエラーコード定義にもありますが、ゼロアドレスは許可されていないようです。
(大したことは書かれていないので、それくらいにしか読めません)
どうも"0"*64
の公開鍵の秘密鍵は暗号学的にあり得ないとのこと。
(あまり詳しくないのでAIの解答を参考程度に貼ります)
結論: この全て0の公開鍵は暗号学的に無効であり、対応する実用的な秘密鍵は存在しません。
理由:
・楕円曲線暗号において、全て0の値は「無限遠点」を表す特別な値です
・無限遠点は暗号学的に意味のある公開鍵として使用できません
・正当な秘密鍵の範囲は通常 [1, n-1] であり、0は除外されています
・この値を公開鍵として使用することは、暗号システムの脆弱性となります
したがって、この値に対応する公開された秘密鍵は存在せず、仮に存在したとしても暗号学的に安全ではありません。
それに、仮に上記の前提が無い場合でも、やはり本当に対応する鍵を知らないのかどうかを証明できません。
公開鍵を"f"埋めにしてみる
"0"がダメならその逆で"f"を公開鍵としてみた。
const seed = "f".repeat(64);
// 導出されるアドレス
// => "TDXRM5WOD5JASSCVFUNYX5JHGWDX22ZE6E655UI"
このアドレスは有効で、トランザクションが承認されました。
しかし、これも対応する秘密鍵を知らないとは言い切れませんね…。
言い切れませんが、対応する秘密鍵を見つけること自体は困難です。
その意味においてはとてもわかり易い公開鍵なので、ネットワークを問わずに固定値として使うことが出来そうです。
公開鍵の導出方法を晒す
既知の文字列から作ったハッシュを公開鍵としてみるのはどうでしょうか。
function generateHash(input: string) {
return crypto.createHash('sha256').update(input).digest('hex');
}
const seed = generateHash("BURN_PUBLIC_KEY");
// 導出されるアドレス
// => TBGVFWZXMVKPVT7B5DHFDI67XNP35YI7CSUNFOA
このアドレスも有効でした。
別途、"BURN_PUBLIC_KEY"
という文字列のsha256
ハッシュ値という共通認識を広める必要があります。
この文字列からこの公開鍵が導出されるとして、それに対応する秘密鍵を見つけるということは一応不可能と言えそうです。
a) Generate the public key for an account without knowing its private key. Then, send mosaics to this generated address.
ここでも言及されていました。
これも"f"埋めの場合と同様に、対応する秘密鍵を絶対に知らないとは言い切れなく、誰かに握られていることを証明はできないが、理屈の上では十分に安全であるという判断はできます。
自分用のゴミ箱を作る
そもそもいらないモザイクというのは利用価値がないものだと思うから、捨てたくなるはずです。
仮にいらないモザイクが入っていたとして、ただそこにいる、というだけなのですが、スパムまがいの気分の悪いモザイクや、そのモザイク名を見ると嫌なことを思い出す、単にリストに並ぶのが気に入らない、などの理由から、捨てたいということはあると思います。
だったら、とりあえず一つ適当なアドレスを自分で作り、そこに投げ込むというのが一番良さそうです。
その際、秘密鍵は覚えて無くてもいいでしょうが、万が一にでも間違った場合に備えて、一応取っておくのもいいでしょう。
(そしてどうせ捨てアドレスなのだから、厳重に管理しなくてもよい)
バーンアドレスを用意することの結論
いずれの方法も、誰かが対応する秘密鍵を絶対に知らないとは言い切る証明は出来なさそうです。
公開鍵から秘密鍵は現実的に導出できないので、必要十分ではありそうですが、やはり仕組みや仕様として定義されているものでないと安心してつかうことはできません。
(逆に、それを許容できるなら、使ってもいいと思います)
Symbolの場合、ユーザー定義のモザイクは期限が存在するため、期限付きであれば、更新しない場合に消失します。
無期限に設定した場合は消失しないので、作成者がモザイクを回収する呼びかけを行い、供給量変更で消失させるトランザクションを出してもいいかもしれません。
モザイクについては/mosaics/{mosaicId}
でそのモザイクの情報が取れます。
{
"mosaic": {
"version": 1,
"id": "72C0212E67A08BCE",
"supply": "8244399083458654",
"startHeight": "1",
"ownerAddress": "9889432DE263BB8FE88444A4DA28D3609BD8BB8FAE18AE95",
"revision": 1,
"flags": 2,
"divisibility": 6,
"duration": "0"
},
"id": "67CA9E5B41FDD7AB72A1E47D"
}
72c0212e67a08bce
はテストネット上のsymbol.xym
ですが、ownerAddress
に発行者が入っているので、もしいらないモザイクを捨てたいなら、送り返してあげるのがいいかもしれません。
ただし、相手先アドレスがアドレス制限で受信をブロックする設定にしているかもしれないので、必ずできるとは限らないかもしれません。
また、サービス提供側も意図しないモザイクの返却トランザクションを送られることを考慮した対応(システム的なことなのか、制限をかけるのか等)を考慮したほうがいいかもしれません。
バーンアドレスとして使えそうなアドレス
ネームスペース・モザイクSINKに投げ込む
***SinkAddres
と書かれたプロパティに指定されているアドレスが各種シンクアドレスです。
ここはネットワーク手数料などが回収されるアドレスです。
おそらく一般のユーザからでは操作できないような仕組みになっているはずです。
(操作権限をコアが握っているのか、システム的に調整される実装になっているのか等は不明です。Catapultサーバの実装を追いかけたら分かるかもしれません)
なので、ここへ送りつければ基本的にはそこから取り出すことは事実上不可能だと思っても良さそうです。
もちろん、そういった使い方をするアドレスではないと思いますが、そういった使われ方をされること自体は想定内のはずであり、十分大丈夫だと思います。
(この程度で壊れるネットワークなら使い物になりません)
ネメシスアカウントに投げ込む
アドバイスいただきました。
ネメシスアカウントとはチェーンの原初ブロック(1)に署名したアカウントで、仕様上、Failure_Core_Nemesis_Account_Signed_After_Nemesis_Block
のエラーとなるそうです。
(メッセージから、ネメシスアカウントはネメシスブロック以降での署名は無効ということ。検証はできませんが)
b) Send mosaics to the account that signed the first network block (nemesis). This account is not allowed to send transactions in the future, as the protocol raises Failure_Core_Nemesis_Account_Signed_After_Nemesis_Block validation error.
ここでも言及されていました。
network.nemesisSignerPublicKey
が名前通りネメシスアカウントの公開鍵です。
const seed = "76E94661562762111FF7E592B00398554973396D8A4B922F3E3D139892F7C35C";
// 導出されるアドレス(テストネット)
// => TCEUGLPCMO5Y72EEISSNUKGTMCN5RO4PVYMK5FI
このアドレスへ転送できることを確認しました。メインネットでもできるでしょう。
前述の通り、仮にこの公開鍵に対する秘密鍵を知っている人がいても、チェーンの仕様上、操作することはできないため、バーンアドレスとしては最も安全な場所として使えそうです。
結論
いわゆる抹消の目的などでバーンアドレスとして使うなら、ネメシスアカウントへ転送するのがよいでしょう。
目障り程度の理由で、ゴミ箱的にしたいなら、個人でゴミ箱アドレスを用意するのがよさそうです。
秘密鍵をメモしてあれば、もし後に必要なことがあっても取り出せます。
また、サービスを運営している場合は、発行してばらまいたモザイクは、誰かから不要と判断されて、送り返されることがあることを考慮した仕組みを考えたほうが良さそうです。
(バーンアドレスの話というよりは、所有者から見た不要モザイクの処分の話ですが)
「既知の文字列から作ったハッシュを公開鍵としてみる」のも必要十分には秘密鍵がわからないといえるので、
ネメシスアカウントだと不特定多数でごちゃごちゃになっているのを避けたいというなら、自前で用意するというのも選択肢となりうると思います。
また、そのアドレスからトランザクションを発信させる必要がなく、単に記録を残したい場合は
単純に「メッセージを記録する場所」として使えるかもしれません。
"f"埋め公開鍵以外は、ネットワークごと、作成者ごとに公開鍵が異なるため、イーサリアムのような「コレ!」という値は無いということになりそうです。
見落としている仕様や他のアイディアがあればコメント頂けるとありがたいです。