話題の Fake Stake 攻撃についての解説

はじめに

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

今回は普段の連載ではなく、先日、米国研究グループから公表された、
Fake Stake 攻撃に関するレポートについて、解説してみようと思います。

この記事は、脆弱性を周知することでコインノードを運用している方々に指摘があったことを
認知していただくためのものであり、決して DoS 攻撃を推奨するものではありません。
実際に攻撃を行った場合、法律により罰せられますのでご注意ください。

前提知識

昨今の暗号通貨の系譜

暗号通貨っていろいろ種類がありますが、その大半は、bitcoin の実装を元に、
ソースコードを改造して作られたものです。

bitcoin から派生していない暗号通貨といえば、Ethereum が筆頭にあがりますが、
それ以外はほとんどが、bitcoin をベースに開発されたものとなっています。

つまり、bitcoin を改造して作られている以上、bitcoin の性質を色濃く受け継いでいるわけです。

今回、問題になっている「チェーンベース PoS」というのも、
元々は PoW で実装されていた bitcoin を改造して、
PoS を導入した暗号通貨のことを指しています。

bitcoin のシステム構造

bitcoin は、それぞれのノードが自分のデータベースを持っていて、
相互に通信しながらそれを同期する仕組みになっています。

f:id:y-hoshizuki:20190125183135p:plain

そして、誰かがマイニングに成功したら、それをブロードキャストして、
それぞれのノードが自分で新しいブロックを検証してから、自分のデータベースに追記します。

f:id:y-hoshizuki:20190125183152p:plain

bitcoin のブロックの構造

ブロックは、大きく分けて2つのデータから成り立っています。

  1. ブロックヘッダ(ブロックの中身のハッシュ値、タイムスタンプ、Nonce など)
  2. ブロック本体(トランザクションデータ)

PoW と PoS

そもそも PoW, PoS とはなんでしょう。

PoW は、ブロックヘッダに Nonce と呼ばれるフィールドを用意して、
ブロックヘッダのハッシュ値が一定値以下になる Nonce を探し当てるゲームです。

SHA256(ブロックヘッダ) < target (difficulty から算出)

この等式を成り立たせる Nonce を総当りで探します。
difficulty は、ブロック発見頻度が概ね 10 分(bitcoin の場合)になるように、
自動で調整される値です。

一方、PoS は、Stake、つまり今持ってる資産に応じて当選確率が上がる抽選です。

SHA256(ブロックヘッダ) < target * 今持ってる資産

この抽選を一定時間ごとに行い、当選したらマイニング成功というわけです。

PoS にもいくつかバリエーションがありますが、この先、
単純に PoS と書いた場合は PoSv3 のことを指すとお考えください。

PoW の欠点、PoS の欠点

PoW の欠点はもう有名ですが、とにかく大量に電力に消費するところです。

これを解決するのが、PoS ですが、こちらはこちらで、
お金持ち(暗号資産をたくさん持っている人)ほどマイニング報酬を得やすくなり、
経済格差が広がる一方、という問題が既に指摘されています。

とはいえ、PoW だって、現金を持っている人ほどいい ASIC や GPU を買えるので、
どっちもどっちと言えなくはないと思います。

もう1つ、今回の鍵になる PoS の欠点ですが、
各ノードが新規に追加されるブロックを検証するときに、
PoW なら「ブロックヘッダのハッシュ値を求めて比較するだけ」で済むのに対して、
PoS だと、「マイナーの資産を確認する」必要があるという点があります。

つまり、PoS はマイナーの資産を確認する分だけ、検証が重い、という問題があるわけです。
今回の脆弱性はすべて、ここが発端となります。

bitcoin から派生した PoS コインの仕組み

bitcoin には、マイナーが報酬を得るためのトランザクション
coinbase トランザクションが、各ブロックに 1 つあります。

coinbase トランザクションは、入力を持たず、出力で 50BTC や 25BTC などを、
マイナー宛に送金するトランザクションです。

bitcoin から派生した PoS コインでは、この coinbase トランザクションに加え、
新たに coinstake トランザクションというものを追加しました。

これは、マイニングに成功したか否かを確認するために、
マイナーの未使用資産(UTXO)を入力としているトランザクションで、
PoS でマイニングされたブロックには 1 つあるものです。

また、coinstake トランザクションでは手数料をマイナスの数にすることができます。
これによって実質のマイニング報酬としています。
そのため、coinbase トランザクションは未使用として運用されています。

このあたりに、bitcoin の血を受け継いでいる感じがありますね。

チェーンの分岐

bitcoin はマイナーが複数人いる上、ネットワークの伝播にラグがある関係上、
チェーンが分岐する場合があります。

そのため、同じブロック高で複数種類のブロックを受け取った場合には、
どちらも正当なものとして一旦保存しておきます。
ある程度伸びた時点で、長く伸びたほうにはたくさんの計算量(マイナー)が集まっている
という仮定のもと、短いほうを廃棄する、という仕組みになっています。

それまでは、分岐した両方のチェーンを保持しています。

そしてこの仕組みは、bitcoin から派生した PoS コインにも受け継がれています。

今回の脆弱性

メモリを大量に消費する DoS 攻撃

bitcoin では、ブロックヘッダの伝播と、ブロックデータの伝播は分けて行われます。

それは、まずブロックヘッダだけ受け取って検証してから、
中身であるブロックデータを受け取れば済むからです。

ところが、bitcoin から派生した PoS コインでは、
ブロックヘッダだけでは検証ができません。ブロックデータに含まれる
coinstake トランザクションに検証用のデータが入っているからです。

そのため、新規にブロックを受け取った際には、
ブロック全体をダウンロードしてメモリに載せる必要があります。
つまり、PoW だった bitcoin と比べて、新規ブロック受け取り時の
メモリ消費量が桁違いに多いわけです。

ここを突くのが、1 つめの攻撃方法です。

例えば、ターゲットのノードに複数のプロセスから同時に接続し、
同時に適当なブロックヘッダとブロックデータを流し込むと、
ターゲットのノードは律儀に全部メモリに載せようとします。

これでメモリを大量に消費してクラッシュする場合もあります。

この攻撃は、特に暗号資産を持っている必要がなく実行できます。

ディスクを大量に消費する DoS 攻撃

前述の通り、coinstake の検証には、マイナーの保有資産を確認する必要があるため、
非常に重いという問題があります。

マイナーの保有資産は、UTXO set と呼ばれるデータベースで管理していますが、
これは現在一番長いチェーンの先端時点での情報であり、
分岐したチェーンの状態ではありません。

そのため、分岐したチェーンでは、coinstake が UTXO として指し示す先が、
トランザクションの出力として存在するか、という最低限の検査のみ行い、
実際に未使用か否かの検査は省略してディスクに保存します。

これがこの脆弱性の肝ともいえる部分です。

そのため、実際には使用済みのトランザクション出力を UTXO と偽って
coinstake を作成し、ターゲットのノードに受信させることで、
ディスクをどんどん圧迫することができます。

これが 2 つめの攻撃方法で、メモリの消費に比べて
「ただの再起動じゃ直らない」という点においてより悪質と書かれています。

ただし、この攻撃を実現させるためには、少なくともハッシュ値は十分、
当選に値するものである必要があるため、ある程度多くの暗号資産を持つ必要があります。

攻撃をしやすくする、Stake Amplification

前述の攻撃手法をとるためには、少なくともハッシュ値の計算で
当選した coinstake を量産しなければならないという問題があります。

そのため、ある程度多くの暗号資産を持つ必要があるわけですが、
ここでポイントとなるのは、coinstake の指し示す先が使用済みであってもよい、
という事実です。

そのため、自分への送金を何度も何度も繰り返します。
そうすると、自分宛のトランザクション出力(ただし使用済み)が大量に生まれます。

これを前述の攻撃に使用することが可能、というわけです。

まとめ

一次ソースの情報を斜め読みして、ざっくりと攻撃の仕組みを解説してみました。
攻撃について、まとめると以下の通りです。

攻撃を受ける可能性があるコイン:bitcoin から派生した PoS 型の暗号通貨(おそらく全て)
攻撃を受ける可能性のある人:コインノードを立てている人(マイニングを行っている人とほぼ同義)
攻撃を受けた結果:メモリ使用量が増えてクラッシュ、もしくはディスクを食いつぶしてシステム停止
攻撃では出来ないこと:他人の暗号資産を奪うこと、など

おそらく、近いうちに対策を施したバージョンがリリースされると思いますので、
今回対象となっている暗号通貨のコインノードを立てている人は、
可能な限り、早めのバージョンアップを心がけると良いのではないでしょうか。

もしくは、リスクを少しでも避けるならば、対策バージョンがでるまで、
マイニングをおやすみしてコインノードを止めるのが、もっとも確実かもしれません。

今回の脆弱性の発見についての記事では、既に多くの暗号通貨において、
何らかの緩和策が取られているとのことですので、その場合はあまり問題にならないかも知れません。
しかし、bitcoin から派生した PoS コインでは仕組み上「完全な解決」は不可能なため、
各自で具体的な対応状況や、リスクの大小など、判断していただくよう、お願いいたします。

ご質問、ご意見等ありましたらお気軽にリプライください。

楕円曲線論はじめの一歩 (4)

今回のおはなし

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

前回は、時計の短針を例に、有限巡回群について語りました。
有限巡回群について、もう少しだけ、お話しておくことがあります。

群の位数、元の位数

群に含まれる要素の数を、「群の位数」と呼びます。
前回触れた時計の短針の場合、群の位数は 12 です。
なぜなら、要素(元、つまり時刻)は 12 種類あるからです。

こちらは簡単ですね。

また、「その元を何回足し合わせると単位元になるか?」という値を、
「元の位数」と呼びます。

こちらは少し難しいので例を挙げましょう。

f:id:y-hoshizuki:20181225191800p:plain

3 は、単位元(0)から 4 回足すと、元の単位元に戻ってきます。

(0 + 3 + 3 + 3 + 3) \bmod = 12 \bmod 12 = 0

だから、元 3 の「元の位数」は 4 となります。

f:id:y-hoshizuki:20181225191816p:plain

4 の場合を見ると、3 回足すと単位元に帰ってきます。
だから、4 の「元の位数」は 3 です。

群の位数と元の位数の関係

それぞれの元に対する、元の位数を表にしてみましょう。
単位元 0 は既に単位元に戻っているため、省略します。

元の位数
1 12
2 6
3 4
4 3
5 12
6 2
7 12
8 3
9 4
10 6
11 12

すべて 12 の約数であることにお気づきでしょうか?

そう、有限巡回群においては、どの元の位数も、群の位数の約数になるという法則があります。
証明は今回も省略します。

素数位数の群

「元の位数」は「群の位数」の約数であるというお話をしました。
ということは、群の位数が素数、例えば 7 ならばどうでしょう?

f:id:y-hoshizuki:20181225191830p:plain

また表にしてみましょう。

元の位数
1 7
2 7
3 7
4 7
5 7
6 7

「群の位数」が素数であるということは、約数は「群の位数」それ自身か、1 しかありえません。
ということは、必然的に全ての元の位数は、群の位数に一致します。

ラグランジュの定理」と呼ばれる性質です。

まとめ

今回は、群の位数と元の位数についてお話しました。
そして、ラグランジュの定理にも少し触れました。
大事な性質なので、よく覚えておいてください。

今回はここまで。
ご質問、ご意見等ありましたらお気軽にリプライください。

楕円曲線論はじめの一歩 (3)

今回のおはなし

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

前回は「足し算」とは何か。つまり「群」について語りました。
今回は、「モノの個数」以外にも「群」の条件を満たすものがあるので、
それについて見ていきましょう。

時計の短針、実は群

f:id:y-hoshizuki:20181225191622p:plain

これは 1 時間に 1 つずつ進んでいく時計の時針です。

モノの個数ではないですが、これも実は群の条件を満たしています。
1 つずつ確認してみましょう。

演算に対して閉じている

1 時から 1 時間経つと 2 時。
3 時から 4 時間経つと 7 時。
8 時から 6 時間経つと 14 時...かと思いきや 2 時。

ちゃんと演算に対して閉じていますね。

結合法則

1 時から 2 時間経って、さらに 3 時間経つと 6 時。
2 時間と 3 時間、あわせて 5 時間が 1 時から経過すると 6 時。

ちゃんと成り立ちますね。

単位元

0 時から n 時間経てば n 時。
n 時から 0 時間経っても n 時。

間違いなく単位元です。

逆元

3 時の 3 時間前は 0 時。
5 時の 5 時間前も 0 時。

逆元はきちんと存在しています。

記号の世界の言葉で説明してみる

今の短針の位置、つまり 0 時からの経過時間を x、追加する経過時間を y としましょう。
この時計の短針の位置は (x + y) \bmod 12 で計算できます。
mod は剰余、つまり「あまり」のことで、x と y を足して、12 で割ったあまりが、
新しい短針の位置になります。

このように、ぐるっと回って元に戻る構造をしている群のことを「巡回群」と呼び、
特に「巡回群」の要素となっている元の個数が有限であるもののことを「有限巡回群」と呼びます。

数学の世界では、12 個の要素からなっている有限巡回群\mathbb{Z}/12\mathbb{Z} と書いたりします。

まとめ

モノの個数以外にも、群の条件を満たすものがあり、
その一例を見てみました。

今回はここまで。
ご質問、ご意見等ありましたらお気軽にリプライください。

楕円曲線論はじめの一歩 (2)

今回のおはなし

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

前回は「1+1」を題材に、「1ってそもそも何?」「抽象的な考え方」について
語りました。お気づきの方はいると思いますが、途中で投げかけた質問、
「+ ってどういう意味?」についてはスルーしていました。
今回はそこから語ろうと思います。

「足し算」と呼んでもいい条件

+ も 1 と同じく単なる記号で、「足し算」であることを示しています。
じゃぁ、「足し算」って何でしょう?

これについては、過去の偉い人たちが散々検討を重ねた結果、
「最低限、4 つの条件を満たせば『足し算』と呼んでも差し支えないのではないか」
という結論を得ました

その 4 つを順に見ていきましょう。

「りんごの個数」と「りんごの個数」を足したら「りんごの個数」

当たり前といえば当たり前です。
これを満たさないものは足し算ではありません。

例えば、「りんごの個数」と「小麦粉の量」を足して「アップルパイの個数」
なんてものは足し算とは呼べません。

これを専門用語で「演算に対して『閉じている』」と表現します。
答えがアップルパイになってしまったら「閉じていません」。

(1+2)+3 = 1+(2+3)

足し算がいくつか並んでる場合、どの順で計算しても結果が変わらない、ということです。

1+2 に 3 を足しても、1 に 2+3 を足しても結果は同じ。

モノの個数で考えているうちは当然のことですが、
いずれ「個数」じゃないものを扱い始めると実は重要な条件です。

小学校でも習ったと思います、「結合法則」というやつです。

0 がある

0 に何を足しても答えは変わらず(0+?=?)。何に 0 を足しても答えは変わらず(?+0=?)。
そんな性質を持つ「記号」が必ず 1 つあることです。

これを専門用語で「単位元」と呼びます。

ちなみに単位元は 2 つ以上存在できません。
証明は省略します。

マイナスの数がある

ちょっとややこしいですが、
要するに引き算のことも同じに扱うことで、
足し算について考えるだけにしたいんです。

「3 を引く」のは「-3 を足す」のと同じ、というわけです。
わざわざ引き算の概念を作らなくても、マイナスがあれば、
足し算の概念だけですべて片付きます。

つまり、本質的には足し算も引き算も同じものである、と言いたいわけですね。

マイナスのことを専門用語で「逆元」と呼びます。
何が逆なのか?「3」の逆が「-3」というイメージです。

ある記号と、その逆元を足したら 0 になる。という条件です。

4 つの条件を満たしたら「足し算」と呼ぶ

ここまでで並べた 4 つの条件こそが、「モノの個数の足し算」から
具体的な要素を極限までそぎ落とした、いわば「足し算の本質」です。

この足し算の本質を満たす計算と、その計算ができる記号(今回は数字ですね)、この 2 つを
セットにして「群」と呼んでいます。

そして、「群」の要素となっている記号のことを「元」と呼びます。

まとめ

今回は、足し算というものの本質、群についてお話しました。

今回はここまで。
ご質問、ご意見等ありましたらお気軽にリプライください。

楕円曲線論はじめの一歩 (1)

はじめに

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

今回は、暗号通貨で電子署名に使われている、楕円曲線暗号について語ろう...
と思ったのですが、楕円曲線暗号の実装方法や簡単な説明は、イマドキありふれているので、
ここはもう少し踏み込んで、楕円曲線論について語ろうと思います。

このあたりの話になってくると、難しい言葉や難しそうな数式がたくさん出てくる説明なら
WikipediaGoogle で探せば見当たりますが、数学に造詣がないと読み解くのは困難だと思います。
なので、証明や厳密な定義などはそちらにおまかせする方向で、
概念の生まれた背景や考え方のような、ストーリー性に重点を置いて語っていければと思います。

すべてのはじまり、1+1 は?

初っ端から「バカにしてるのか?」と思われそうなタイトルですが、
いたって大真面目です。もちろん、小学一年生でもわかるような 2 という話でも
ないですし、「田んぼの田」みたいななぞなぞでもありません。

注目したいのは以下の点です。

  1. そもそも 1 ってなに?
  2. + ってどういう意味?

どうでしょう?小学校で天下り式に教わった数式ですが、
実はちゃんと説明できる人は多くないのではないでしょうか?

小学校ではどう教わった?

イマドキの学習指導要領でどうなってるかは知りませんが、
私のころは、りんごやおはじきで習いました。

f:id:y-hoshizuki:20181225190936p:plain

りんご1個とりんご1個、あわせるとりんごが2個。

ここで重要な事実が1つ、みんな当たり前に受け入れてきたことですが、
「実はりんごじゃなくてバナナでも同様なことが言える」のです。

つまり、りんごにこだわる必要は特になくて、
りんごとかバナナとか、梨とかみかんが、1個あることを
数式の中では「1」と表記しているのです。

言い方を変えれば、「1」というのは「何か」を示す「ただの記号」でしかなくて、
実は「#」とか好きな文字であっても良かったんです。
ここが混乱の元となるのですが、本文中で「1個」というときの1と、
数式の中で出てくる「1」は意味が違うのです。

f:id:y-hoshizuki:20181225191013p:plain

本文中で「りんごが1個」と言っているの「1」は「具体例の世界」の話、
「1+1」と数式で書いているときの「1」は「記号の世界」の話。

こんな風に、具体例から一旦記号に置き換えて、「計算」と呼ばれる作業をしてから
元の具体例の世界に戻ってくる。
...ということをやっていたのが、小学一年生で習った算数なのです。

どうでしょう?実は意外に複雑なことをやっていましたね?

どうしてそんな面倒な手順を踏むのか?

「記号の世界」つまり「数式の世界」であれば、これまで発明された
いろいろな公式がそのまま使えて便利だから、に他なりません。

言い方を変えれば、記号の世界で考案された公式の方が、より「汎用的」であるわけです。

また、記号の世界には具体的な概念がほとんど登場しなくなります。
これは具体例の要素を可能な限りそぎ落として、本質だけを捉えて扱うということです。

このように、記号の世界に一旦変換して物事を考えることを「抽象化」と呼び、
抽象化して「本質について」だけを考えることこそ、
「数学」という学問の真髄とも言えると思います。

まとめ

今回は 1+1 の数式から始まり、1 とは何か?抽象化とか何か?
というあたりについて語りました。

今回はここまで。
ご質問、ご意見等ありましたらお気軽にリプライください。

暗号通貨のトランザクションを手作りする (8)

今回のおはなし

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

前回までで raw トランザクションの作り方は一通り説明し終わりました。
今回はおまけ的な位置づけで、コインアドレスについて説明します。

コインアドレス

コインアドレスは、公開鍵ハッシュと相互に変換可能な文字列なので、
公開鍵ハッシュの代わりにやり取りするときに便利に使えます。

前回、手作りしたトランザクション
TXID 661b7e85f863232aff7344acd268bb9eaab306fc8b806d3e6101244c6d06c373
ですが、その直前のトランザクションとなる
TXID c37ab04631eef5813077fbbaae44e01bf26f9cab86426316ba81f99e2c9e8282
はどうやって作ったと思いますか?

実は、公開鍵ハッシュからコインアドレスを生成して、そこに送金しただけです。

ではコインアドレスの作成方法を見ていきましょう。

公開鍵ハッシュは db2e054bb576dc63283c0060abd46df14057c2de でしたね。
まずは先頭にモナコインのテストネットを表すプレフィックス、6f をつけます。

そして、sha256 を 2 回計算して、チェックサムを作ります。

$ printf "%b" "\x6f\xdb\x2e\x05\x4b\xb5\x76\xdc\x63\x28\x3c\x00\x60\xab\xd4\x6d\xf1\x40\x57\xc2\xde" | openssl sha -sha256 -binary | openssl sha -sha256
(stdin)= 1320a8f11585dd4764f6c8ffe4bd8824585d737b821b4b928a40be5e483e4f36

この先頭 4 Byte の「1320a8f1」がチェックサムです。

プレフィックス、公開鍵ハッシュ、チェックサムの 3 つをつなげると
6fdb2e054bb576dc63283c0060abd46df14057c2de1320a8f1
となります。

これを、Base58 エンコードすればコインアドレスの完成です。
Bass58 エンコードといっても、要はただの 58 進数なので、多倍長整数が扱える言語なら
簡単なコードで変換できます。

例えば python で書いてみましょう。

# util.py

def b58encode( src ):
	mapping = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

	r = ''
	n = long( src, 16 )
	for i in range( 0, 34 ):
		r = mapping[n % 58] + r
		n = n / 58

	return r

実行してみます。

$ python
>>> import util
>>> util.b58encode( '6fdb2e054bb576dc63283c0060abd46df14057c2de1320a8f1' )
'n1VsQdyHFc15HzZMxfGgEC2zRQKWqu4XSQ'

はい、できました。

あとは、このコインアドレスに送金すれば、
TXID c37ab04631eef5813077fbbaae44e01bf26f9cab86426316ba81f99e2c9e8282
が作られます。

今回の連載はこれで終了となります。
みなさん、お付き合いいただき、ありがとうございました。
ご質問、ご意見等ありましたらお気軽にリプライください。

暗号通貨のトランザクションを手作りする (7)

今回のおはなし

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

前回までで、P2PKH で必要な「電子署名」「公開鍵」「公開鍵のハッシュ値」ができました。
今回は raw トランザクションを完成させてブロックチェーンに取り込んでもらいましょう。

scriptSig の組み立て

P2PKH の scriptSig は以下の形式でした。

PUSH 電子署名
PUSH 公開鍵

これにあわせて scriptSig を組み立てます。
1点注意、openssl dgst で作った電子書名は DER 形式というフォーマットになっているため、
そのまま使えますが、OP_CHECKSIG はその後ろに 01 をつけたものを PUSH する必要があります。

47                        ... 前回作った電子署名の長さ + 1 (PUSH 命令)
30 44 02 20 5C 66 D2 C6 F1 AE 9D 91 D4 10 3F 4F
40 B7 26 CC 9C 27 21 42 B1 A1 7F CE B5 23 74 45
FD BD 95 63 02 20 21 F1 2C 9D A7 7E AC 95 35 31
61 6E E6 73 DC 19 69 A0 48 C3 C1 6A EB 60 22 E0
D2 E8 CA D3 E6 4F         ... 前回作った電子署名
01                        ... 後ろにくっつける

21                        ... 公開鍵の長さ (PUSH 命令)
02 B4 EE A1 4B 61 45 A8 97 F8 75 61 3C 80 FE 3B
3F 50 D4 69 A5 B2 88 6B 50 5F 55 F6 A3 08 B9 E8
74                        ... 第5回で作った公開鍵

本番用 raw トランザクションの組み立て

前回仮組みしたのと同じ構成にする必要があります。
scriptSig は今回は正しく電子署名の入ったものを使います。

02 00 00 00      ... バージョン 2
01               ... 入力は 1 つ

入力データ
 82 82 9E 2C 9E F9 81 BA 16 63 42 86 AB 9C 6F F2
 1B E0 44 AE BA FB 77 30 81 F5 EE 31 46 B0 7A C3
                  ... 前 TXID: c37ab04631eef5813077fbbaae44e01bf26f9cab86426316ba81f99e2c9e8282
 00 00 00 00      ... 前 TX の第0出力を使用する
 6A               ... scriptSig の長さ 106 Byte
 47
 30 44 02 20 5C 66 D2 C6 F1 AE 9D 91 D4 10 3F 4F
 40 B7 26 CC 9C 27 21 42 B1 A1 7F CE B5 23 74 45
 FD BD 95 63 02 20 21 F1 2C 9D A7 7E AC 95 35 31
 61 6E E6 73 DC 19 69 A0 48 C3 C1 6A EB 60 22 E0
 D2 E8 CA D3 E6 4F
 01
 21
 02 B4 EE A1 4B 61 45 A8 97 F8 75 61 3C 80 FE 3B
 3F 50 D4 69 A5 B2 88 6B 50 5F 55 F6 A3 08 B9 E8
 74               ... 正しい scriptSig
 00 00 00 00      ... シーケンス番号はとりあえず 0

01               ... 出力は 1 つ

出力データ
 C0 9E E6 05 00 00 00 00 ... 0.99 tMONA
 19               ... scriptPubKey は 25 Byte
 76 A9 14
 DB 2E 05 4B B5 76 DC 63 28 3C 00 60 AB D4 6D F1 40 57 C2 DE
 88 AC            ... scriptPubKey 本体

00 00 00 00      ... ロックタイムはとりあえず 0

これで P2PKH の raw トランザクションが完成しました。


後はこの16進文字列を、

$ monacoin-cli sendrawtransaction "0200000001...00000000"

とコインノードに送りつければ、ブロードキャストされてブロックチェーンに取り込まれます。

こうしてできたのが、
TXID 661b7e85f863232aff7344acd268bb9eaab306fc8b806d3e6101244c6d06c373
です。

今回はここまで。あと 1 回だけ続きます。
ご質問、ご意見等ありましたらお気軽にリプライください。