OP_PUSH_TX

ロックスクリプトコントラクトをデータとコードの2つの部分に分割する

OP_PUSH_TXを使用すると...
コードはメソッドであり、データはオブジェクトのメンバー変数...

要はロック解除すればデータは更新できる。
サンプルとしてカウンターが紹介されています(testnetです)。

medium.com

github.com

ロック解除する権限があれば、数字を更新したtxを生み出せる。
が、今のところここだけなのでまだピンと来ない。これから画像をセピアにしたり、辞書を引くみたいに構築できるのか?という話です。bitcoin scriptを用いないなら出来るんですが、bitcoin scriptで出来たらヤバい。

いまのところ例えばjqueryブロックチェーンにアップしてそれを参照するとかはできる。でもプログラムの実行自体は閲覧ブラウザのパソコンや運営サーバで処理しないといけない。もしbitcoin scriptで出来るのであればブロックチェーン上でプログラム処理済みのものが返ってくる。

...聞いてみようかな。将来的にできるものなのか...限界があるのか...大事よね...

bitbus2.0を使う

_unwriter氏が直近推している。というか他が手に回らないので、最新のツールを使ってくれという感じでいつも言っている。
性能もいいみたいだから使おう。なによりクエリーで$gtとか仕様上は使えるはずなのにgenecisで今は使えないので、bitbusでいけるか試す必要がある。まぁ使えなくても何とかなる気がするからいいんだけども。

docs.bitbus.network

これまで通りトークンを取得して、APIなのでどんなプラットフォームでもいけますよという超便利なビットコインクローラーです。
ドキュメントでいきなり"blk.i": { "$gt": 609000 }とあって動いてるgifがあるのでまぁーいけるでしょう!!

というかいままで

https://genesis.bitdb.network/q/1FnauZ9aUH2Bex6JzdcV4eNX7oLSSEbxtN/...

だったのを

https://txo.bitbus.network/block

にすればいいくさい?

GET形式からPOSTになったので地味に取得コーディングを変えんといけん。でも以前やった。curlを使えばいい。
何でやったかと思えばmoneybuttonのoauthだ。サンプルを公開したいがライブラリを使用しているので、ライブラリ毎公開する気はないので、今回もやりましたよー記事です。

しかしできねぇ!{"error":"invalid query"}になる!

・・・
・・・
・・・

おかしいぞ!って思って、nodejsのサンプル実行したら動いたので、何かしらcurlの送り方がおかしいっぽい。クッソ!!!!
でもnodejsのサンプルで「$gt」は動いた。小さな目的達成。そもそもドキュメントにaggregate以外使えるとある。まぁバグとかこれまでのはあったんすよ。
とりまPHPでもいけるように頑張る。世界はPHP眼中にない(笑)

・・・
・・・
・・・

ぎゃー、わかった。javascriptのサンプルqとかfindがなぜか囲いがねぇ。「"」で囲ったら余裕だった。ざけんな!

それ以外にもPOSTデータって大抵複数あるので、大方キーバリューの配列構成なんだけど、jsonのクエリー一つで完結しているのでPOSTデータを配列でいれてはいけない。
PHPのhttp_build_queryでだいたいエンコードするもんだけど、それもやるとおかしくなるのでやらない。無駄を極限まで省くためかは謎。まぁ動けばいい。

取れたと思ったら、大きなデータはBitFSに託されたみたいで一遍にとれない。うーむ、仕方ない。
bitfsやってなかったのでよくわからんけど、バイナリデータを持ってこなくても取得したアドレスを指定すれば描画されるっぽい。
これはこれで画像とかなら自前のサーバに負荷が掛からなくていいかも?暗号化とかしたら取得して復号化しないといけないけどね。

bitfs.network


そんな感じで、bitbus2.0 + bitfsでございました。最近外部jsとかチェーンにあげてそれを読むとかしてる人とかいてサーバレス近づいてきてます。しかし進展早いからキツイ。かといって遅れて入れば入るほど過程が飛びまくって分からんかもしれんね。

1度の決済で別々のtxでOP_RETURNが送れるかテスト

表題の件、よーく考えたら分かる事なんですが、1取引が1トランザクションなので、表向き偽装しない限りできません。ただこれを何故できないか言い出した理由は、データを別々に登録したかったから。Dプロトコルなどで上書きにしても全項目入れ直しは非常にしんどい。このため1回の決済で個別のtxハッシュが欲しかったの。


で、テストした意味はありました。

<div class='money-button'
	data-outputs = '[
		{
			"script": "OP_0 OP_RETURN hex_text1",
			"amount": "0",
			"currency": "BSV"
		},
		{
			"script": "OP_0 OP_RETURN hex_text2",
			"amount": "0",
			"currency": "BSV"
		}
	]'
	data-on-payment = 'myCustomCallback'
></div>

outputsはもともと以前手数料をいただきつつ~の記事で紹介した変則バージョンになりますね。そもそも送り先は複数が可能です。実際ブロックチェーンは仕組み上そういうものです。
online106.hatenablog.jp

で、このパターンで実行するとどうなるかというとout.iで分けられて記録されます。

{
  "v": 3,
  "q": {
    "find": {"tx.h": "tx hash"}
  },
  "r": {
    "f": "[.[] | { text1: .out[0].s2, text2: .out[1].s2} ]"
  }
}

こういうことですわ。これどうやるのかいままでわかってなかったのでテストしてよかった。軽く見た感じではDプロトコルでこのレコード?までは指定できないっぽい。これ識別子かインデックスかスコープと言われるのか分からないけど...何の役に立つのだろうか。データ分割してもビックブロックだし1tx1GB制限の範囲だしなぁ。

MAPでDELETEしてみる。SETで上書きできる?

はい、ということでDELETEとUPDATEを試してみます。filenameはいらない気がしてきました。URLの見た目は良くなりますが、txにすれば一意だしチェーンに刻む分ちょっとお金かかるし...前回同じアドレスで同じfilenameにしたら動き変になった気がするし。課題としています。

DELETEはキーをピンポイントで削れるようです。

1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5 (MAP)
'DELETE'
'profile.name'

github.com


つまり前回の記事で、投稿したうちの経度緯度4番目を削るとすると

OP_RETURN 
19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
"<html><body><h1>なんでもいい?</h1></body></html>"
text/html
utf8
map_test001.html
| 
1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5
DELETE
4

で、いいのかな...ここでこそfilenameが重要になってくるのではないだろうか。


できない!なんかゴミレコードができてしまった。誰も使ってないし使わなくてもいいけどDプロトコルの方が最適解になるやも?勘違いだろうけど。
※とりあえず問い合わせてみている最中。回答来るか分からないけど。
※あがいてapp指定してDELETEテスト。READMEにはないけど、普通app指定するはずだから...。だめだわからん。

ではUPDATEできるのか?あるレコードにSETで上書きしてみる奴。

"19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut", 
'<html><body><h1 style="font-size:72px;">もす!</h1></body></html>', 
"text/html", 
"UTF-8", 
"map_test001.html", 
"|", 
"1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5", 
"SET", 
"app",
"test.app",
"5",
"34.6731630^135.5193140^e17.8",
"6",
"34.6731630^135.5193140^e17.8"

5は更新で、6は追加という感じ。

・・・だめだな。

MAPのテスト結果。

SETする分にはいいかも?twetchのように1回きりで流れていく短文にはいいけど、更新するならB->Dでシーケンス管理の方がいまのところちゃんと動く。私がまったく使い方違ってるだけかもしれんが。

そう思てB|Dのテストを見に行ったらDのエクスプローラーオフラインになってた。安定稼働には徐々に普及が必要そうだなぁ


確認しました。v2策定中なので現在初版を導入する必要はなさそうです。
github.com

とりあえずMAPを試す。

B |(パイプ) D と違ってMAPプロトコルはREST感!CRUD感だしてます!横文字カッコイイ!
MAGIC ATTRIBUTE PROTOCOLいうらしいです。
プレフィックスは1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5です。

<OP_RETURN | <input>>
MAP
<SET | DELETE>
<key>
<value>

以下サンプル

OP_RETURN
19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
text/html
UTF-8
<html><body><h1>とりあえず何かいれておく</h1></body></html>
|
1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5
SET
app
test_app
type
gps
1
34.6731630^135.5193140^e17.8
2
34.6912530^135.5348380^e0.4
3
34.7415840^135.5266780^e-1.4
4
34.7651220^135.5210800^e13.8
5
34.8244010^135.5088550^e41.4

とりあえずです。何度か上手くいかず書き直しました。エクスプローラー側のバグかもしれんし、仕様かもしれん。とりあえずデータはAPIで取得したい身としてはバグだろうと仕様だろうと従うしかない。

MAPにパイプしてからはキーバリューの形になります。ルールとしてappでアプリ名を書く。そしてtypeで自前のコンテンツの用途を書く。今回は5つだけのGPS風にしてみました。この登録の仕方がベストかは不明です。twetchだとAIPにパイプしています。これによって誤データを弾いているのかもしれない。

BMAPのエクスプローラーで登録内容を確認できます。
https://b.map.sv/

{
  "v": 3,
  "q": {
    "find": {
      "MAP.app": "tonicpow"
    },
    "limit": 10
  }
}
{
  "v": 3,
  "q": {
    "find": {
      "MAP.app": "twetch"
    },
    "limit": 10
  }
}

が、このMAP.appで検索なんですが、何度かやって失敗したのは別の理由がありそうです。
先ほどまでtest_appでヒットしていたのが、ゼロ件になってしまいました...うーん。
今度は最初にうまく行かなかったtest.appがヒットしました。エクスプローラーの黄色時の「c」「u」がポイントの様です。
試しにもう一度登録するとcはblkありで、uはblkがありません。つまるところこれはあれですね。
confirmed: 確認済み
unconfirmed: 未確認
気にしてなかったけど...しかも今回は気にしなくていいかも
4回やって、3回目だけ出てたと思ったら、3回目だけでなくなってしまいました。
もしかするとfilenameが2回目と3回目が同じだからでしょうか...うーん。

ちなみにテスト中同じアドレスだと思うので、以下の方が追いかけやすいです。

{
  "v": 3,
  "q": {
    "find": {
      "in.e.a": "address"
    },
    "limit": 10
  }
}

とりあえずもう少しいじって安定感確認したい。


確認しました。v2策定中なので現在初版を導入する必要はなさそうです。
github.com

Dプロトコル(D://)を試しました。

Bitcoin dynamic content protocolらしいです。

型はこれなんですが、パイプもできます。

OP_RETURN
19iG3WTYSsbyos3uJ733yK4zEioi1FesNU
[key]
[value]
[type]
[sequence]

一旦前回の試したBをDれるかテストします。
....
で、これ幾度かミスって、bico.mediaやD用のエクスプローラーで確認していくうちに分かりました。

D用のエクスプローラ
https://d.onchain.ch/query/1G3BpTyEK6xF4LaQTHqdFBBaVxYHZzts4M/ewogICJ2IjogMywKICAicSI6IHsKICAgICJmaW5kIjoge30sCiAgICAibGltaXQiOiAxMDAwCiAgfSwKICAiciI6IHsKICAgICJmIjogIlsuW10gfCB7IHByb3RvY29sczogLnByb3RvY29scywgdHJhbnNhY3Rpb246IC50eGlkLCBibG9jazogLmJsaywgc2VuZGVyOiAuc2VuZGVyICwga2V5OiAua2V5LCB2YWx1ZTogLnZhbHVlLCB0eXBlOiAudHlwZSwgc2VxOiAuc2VxLCBcIlVSSSBvdmVyIGh0dHBzXCI6IChpZiAudHlwZSA9PSBcImNcIiB0aGVuIFwiaHR0cHM6Ly9kYXRhLmJpdGRiLm5ldHdvcmsvMUt1VXIycFNKRGFvOTdYTThKc3E4endMUzZXMVd0RmZMZy9jL1xcKC52YWx1ZSlcIiBlbGlmIC50eXBlID09IFwidHh0XCIgdGhlbiBudWxsIGVsc2UgXCJodHRwczovL2IuYml0ZGIubmV0d29yayNcXCgudmFsdWUpXCIgZW5kKX1dIgogIH0KfQ==

まずBプロトコルではひたすら一意のtxでデータが入り続けます。
このBが一体何なのかをDで指定します。

Dプロトコルのtypeでtxを指定します。
で、そのtxをvalueにいれます。
Bプロトコルで出力されたtxをvalueに突っ込む感じです。
するとDプロトコルでtypeがtxだからvalueにtxはいってるなって判断されて、

https://bico.media/ tx生んだアドレス / キーで指定したパス

と言ったことができます。このtypeが以下のマニュアルにあります
planaria.network

tx生んだアドレスはmoneybuttonで今回決済しているので、moneybuttonのtxを調べると自分の今回のアドレスが分かります。
マニュアルに話を戻すと、c,b,tx,txtなどが指定できるようです。
ざーっと他人のDのtxみましたがほとんどがBでたまにtxでした。なのでみんなパイプしていると思われる。

OP_RETURN
19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
[DATA]
[MEDIA TYPE]
[ENCODING] or NULL
[FILENAME] or NULL
|
19iG3WTYSsbyos3uJ733yK4zEioi1FesNU
[key]
NULL
b
[sequence]

Dのプレフィックスは「19iG3WTYSsbyos3uJ733yK4zEioi1FesNU」です。もうBの流れで分かると思います。

"B | (パイプ) D" だとtypeにB指定してvalueはnullでいいっぽい。

無事いけた。

リダイレクトが掛からないのはシーケンスか、Bでnullにしたからかも?
それはどれでもいいかな。

お、そうそうそしてさらに上書きテストをします。

シーケンス2にして...


いけました。


キャッシュがきついですが、ちゃんとシーケンスの大きい数字が表に出ます。
BSVUP使うまでもないな。これなら個人のmoneybutton使わせて、ブログ記事の投稿更新とかいけますね。
ドメインサブドメインを選ばせて、暗号復号のプロトコルが出来るかなと思ったけどパブリックだと難しいかも。自前でやりたければやればいい。

Bプロトコル(B://)を試しました。

BプロトコルBitcoin Data Protocol言いまして、これをMetaNetの場合ラッピングしたりするので、以前MetaNetで試したと言えば試しました。今回はBのみでやったところ一応すんなり記録できました。

こんな型です。

19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [Data] [Media Type] [Encoding] [Filename]

19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAutは固定値でプレフィックスとなります。
これがB://で稼働するという合図であって、あなたのアドレスを好きに入れていい訳ではありません。

今回これでFilenameが上手く稼働しません。私に非がないように思うので、これは聞いてみようかな。(聞く必要なくなた)

<html>
<head>
<style>
input#file { display: block; padding: 10px; background: whitesmoke; width: 100%; margin: 10px 0; }
a#tx { display: block; padding: 10px; margin: 10px 0; color: red; font-size: 12px; font-family: Menlo, monaco, Courier; }
</style>
<script src="//www.moneybutton.com/moneybutton.js"></script>
<script src='//unpkg.com/datapay'></script>
<script src='//unpkg.com/databutton@0.0.4/index.js'></script>
<script>
document.addEventListener("DOMContentLoaded", function(e) {
	databutton.build({
		data: ["19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut", "<html><body><h1>ここに何かいれてみよう!</h1></body></html>", "text/html", "UTF-8", "test.html"],
		button: {
			$el: "#button",
			$pay: {
				feeb: 0.5,
			},
			onPayment: function(msg) {
				console.log(msg)
				document.querySelector("a#tx").innerHTML = "View on B (" + msg.txid + ")"
				document.querySelector("a#tx").setAttribute("href", "https://b.bitdb.network#" + msg.txid)
				console.log("https://bico.media/" + msg.txid);
			},
			onError: function(err) { console.log(err) }
		}
	})
})
</script>
</head>
<body>
	<p>B:// 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [Data] [Media Type] [Encoding] [Filename]</p>
	<a target='_blank' href='#' id='tx'></a>
	<div id='button'></div>
</body>
</html>

古い記事から辿っている人にはおなじみですが、moneybuttonで1500satくらい払えばこれで記録出来て、txが返ってきます。
test.htmlを指定しているので、このパスが通って欲しいんですが難しいですね。
そうそうBSVUPが失敗したと伝えましたが、txベースの参照だと出来てはいるんです。ただURLパスで参照できない。
他人のtxとかDと混同してますが、これでみれます。

https://d.onchain.ch/query/1G3BpTyEK6xF4LaQTHqdFBBaVxYHZzts4M

これみてもやっぱりパス通って参照できないんですよねぇ。何故でしょう。と、思いながらおもむろにアドレスで検索してみたらどうもsenderとkeyを組み合わせると行ける臭い。しかもDプロトコルしかヒットしない。Bだけだとだめなのかな?わからん。

まぁこれがうまく行けばユーザに自身のアドレスをいくつか登録してもらえば、その傘下のパスでデータを引っ張ってくることが出来るようになる。ユーザ毎にサブドメインとかではてなブログ的な展開すれば良さそう。Dは本来更新用、バージョン管理用なのでそっちもテストする。※Dでこれらが解決しました。