GoでMQTTをsubscribeする
IoTの文脈ではよく使われるMQTTプロトコルで送信されたメッセージをGoで Subscribeする.
開発環境の準備
$ brew intall mosquitto
Macに MQTT Client の mosquitto をインストールする.他の開発環境の場合は、下記のリンクから参照
インストールをすると、コマンドとして、
mosquitto
mosquitto_sub
mosquitto_pub
が用意される
mosquitto broker の立ち上げ
mosquitto broker を立ち上げる
Mac の場合には、
$ mosquitto 1586499763: mosquitto version 1.6.9 starting 1586499763: Using default config. 1586499763: Opening ipv6 listen socket on port 1883. 1586499763: Opening ipv4 listen socket on port 1883.
で立ち上がる
MQTTはデフォルトのport が 1883 になっている.
もし、TLS といった証明書をつかった通信をしたい場合は、
/usr/local/Cellar/mosquitto/1.6.9/etc/mosquitto/mosquitto.conf
に port の変更と証明書の記載ができるので、そこを変更する.
pub / sub
実際にメッセージを送ってみる
subscribe の立ち上げ
$ mosquitto_sub -t sensors/temperature
topic オプションなしでは立ち上がらないので注意、何かしらのtopicが必要
publish
$ mosquitto_pub -t sensors/temperature -m "{ "hoge": "foo" }"
同じtopic でコマンドを実行すると、
$ mosquitto_sub -t sensors/temperature { hoge: foo }
と表示される.
Go で subscribe
参考というか、そのまま使ったコードがこれ
$ go run main.go
これで立ち上がるので、
$ mosquitto_pub -t sensors/temperature -m "{ "hoge": "foo" }"
を打つと、
Received message on topic: sensors/temperature Message: { hoge: foo }
と表示される.
Learn or Die 死ぬ気で学べ 読了
現代で 日本(もしくは世界?) で1番熱量のある企業の preferred networks(PNF) のことが書かれた 「Learn or Die 死ぬ気で学べ」を読了した.
私自身は、この企業の名前と何の業界にいるのかというのは、雑誌などで見てはいたのだが、実際のところ、それ以上のことは知らなかった. 読み終わった感想を端的に述べると、「会社という皮を被った天才たちの遊び場」という印象を受けた.
なぜそのような表現をするかというと、この企業の中の人が、世の中でできてないことをテクノロジーの力で実現することに全力を注いでいると感じたからだ.しかも、業界トップレベルの頭脳で. それをみんなでやろうとしている場が、あくまでも会社という体を為していただけだと思う.
世の中では右を見てもAI、左を見てもAIといった感じで、AIがあれば何でも解決できるという風潮を出し、あまり技術に強くない会社のトップは、「AIで何かできないか?うちもAIやろう」ということを言い始めている.しかし、実際に機能するものが生まれるかというとそうではない.理由としては、技術力というのもあるが、そもそものデータが足りないかつ、データの使い方がわからないなどなどがあげられる.
だが、PNFは元々、PNIの時に分散データ処理を主軸にしていたこともあり、データ収集、分析にかけては非常にナレッジがある.そのため、必要になるのは、深層学習で実現したいことのロジックに注力することだ.他にもたくさんあるかもしれないが
上記のことに加えて、PNFは深層学習のトップカンファレンスに採択される論文をバンバン出している.技術に強い企業であるということを自信を持って言えるのではないだろうか.
日本にもこんなに凄い企業があることを尊敬する一方、自分ももっと死ぬ気で学び続けていかなければいけないと思う一冊だった.
Ethereum Transaction
Accounts
Externally Owned Account(EOA)
外部所有のアカウント
Contract Account
スマートコントラクト これがつくられる時に作成されるアドレス
アカウントの構造
- nonce -> メッセージ実行時にインクリメントされる値
- balance -> このアカウントが保有しているWeiの量
- storageRoot -> 状態dataのMerkle Patricia tree のルートハッシュ 256bit
- codeHash -> このアカウントのcodeのhash値. 検索に利用される
これらの4つの要素が内包されている
EOA と Contract Account の見分け方
codeHashがnilのHash値の時はEOA
Transactionの構造
受取手が EOAの場合は 送金トランザクション 受取手が Contract の場合は、execution トランザクション(スマートトランザクションのコードを何かしら実行するトランザクションとなる)
構造
- nonce
- gasPrice
- gas
- to
- value(何かしらのetheを送る場合)
- このtransaction全体に対する署名
- data(仕様上は無限の値を入れれる)
Transaction is Message
- nodeの中ではMessage Callとして扱われる
- TransactionもMessage Callに変換される
- Contract -> Contract の呼び出しも EOA -> Contract の呼び出しも同じように扱える
- Messaage Callの発生源はEOAであるため、発生源を示すフィールドも用意されている
Message Callの構造
- sender -> messageを投げたAddress
- originator -> messageの発生源のAddress
- recipient -> messageの受信Address
- execute account -> messageを受けとって、codeを実行する人.recipient = exexute account
- available gas -> 利用可能なgasの量
- gas price
- data
- depth of stack -> 実行時のcontextの深さ
- state modification -> 実行時にこのアカウントのstateの変更を許可するフラグ
送金トランザクションの流れ
- Transactinが有効かチェック
- 送金対象のアカウントがなければ作成
- 送金を実行
- evmを起動してcodeを実行
Bitcoinとの違い
ビットコインのマイニング
なにやってるの
- Bitcoinのマイニングは計算競争を行い、その勝者がブロックを作ることができる.
- その報酬として、新たなBitcoinを受け取ることができる.
- 全体のマイニング量は確定している
- BitcoinのマイニングにはProof of Works というアルゴリズムが使用されている
補足
ブロックヘッダの構造
フィールド | Bit長 | 概要 |
---|---|---|
version | 32bit | プロトコルのバージョン |
前のブロックのハッシュ | 256bit | ブロックがつなっがているということの証明用途 |
マークルルートのハッシュ | 256bit | マークルツリーというデータ構造でブロックに含まれるすべてのトランザクションを集約した値 |
ブロック生成日時(time) | 32bit | ブロックを生成したおおよその日時.ネットワークが伝搬するのに要する時間に差があるので、おおよそ |
難易度 | 32bit | マイニングの難易度 |
Nonce | 32bit | マイニングのためのフィールド.この値を変えながらハッシュ値を計算する(約42億程度) |
プロセス
- Mempool(ブロックに取り込まれていないトランザクションのプール)からトランザクションを収集し、ブロックの雛形を作る
- ヘッダーのNonceフィールドをインクリメント
- ブロックヘッダーのハッシュ値を計算する
- ハッシュ値が指定された難易度よりも小さければ成功.そうでなければ失敗として2に戻る
検証
- ブロックのデータ構造が正しいこと
- ブロックヘッダーのハッシュ値が難易度より小さいこと
- ブロックのタイムスタンプがノードのタイムスタンプの2時間未来よりも小さいこと(伝搬に時間がかかることを考慮)
- ブロックサイズが1MB以下であること
- ブロックに含まれるすべてのトランザクションが正しいこと
チェーンの分岐
ケース:
たまたま同時にブロックが見つかるなどで複数の正しいブロックが生まれることがある
解決:
より長いチェーンが正しいチェーンとして扱われる difficulty がより高いものとも言える そのチェーンが形成されるのに、より高い計算能力が使用されている -> より改竄されにくい
分岐が発生するのをできるだけ防ぐために10分という時間を設けている
Difficulty
- Difficultyは10分に1回ブロックが生成されるように調整される
- 2週間に1回(2016ブロックごと)見直される
- マイナーのハッシュパワー(秒間あたりのハッシュ計算回数)は変動しているため、10分間隔を守るために定期的に見直す必要がある
51%攻撃
悪意のあるマイナーが51%を超えるハッシュパワーを手にすると、ある程度自在に履歴をつくることができる
- マイニングの独占による、他人の取引の妨害
- 51%攻撃による履歴の改竄
ハッシュパワーが強いということで独占後の改竄は容易だが、過去の改竄は再度計算を要するため難しい
改竄の流れ
- ある時点で、そのときの最新のブロックに続くブロックをマイニングする
- そのまま複数のブロックをマイニングするが、ネットワークにブロードキャストせずに、手元にそれらのブロックを持ち続ける
- ハッシュパワーが51%を超えているので、メインネットよりも長いチェーンを手元で作ることができる
- メインネットで自分のビットコインを売って円などの別の通貨を手に入れる
- 手元に隠しもっていたブロックをブロードキャストする.このブロックが最長のチェーンとして正規のチェーンとなる
- 隠し持っていたブロックは、手元のBitcoinはどこにも送っていない状態になっているので、売ったはずのBitcoinが戻ってくる
補足
このような攻撃をBlock withholding Attach と呼ばれることもある このようなブロックの構造が再構成されることをReorg(リオルグ)と言われる
Truffle について学ぶ
概要
最も有名なDAppsの開発ツール
何が含まれているか
- Deploy Tool -> Migration
- Test Tool -> Mocha
- Node For Dev -> Ganache
Migration
- Smart Contract の Deploy 方法を記述するもの
- DB Migration のようにバージョンを分けることが可能
- RollBackはできない
※ RoRのMigrationに似てるっちゃ似てる
eltoo と SIGHASH_NOINPUT
Off-chain Scaling
Payment Channel
2人のユーザーがいた場合に、お互いが資金を出し合って、お互いの署名がないとunlockができないようなマルチシグに送金するトランザクションを生成し、それをblockchainにbroadcastし、そのfunding transactionをinputとし、お互いの残高を更新していく
この仕組みは資金をブロックチェーンに固定し、固定した金額を上限として、trustlessにoff-chainで決済を切り返すためのプロトコル
どのようなコントラクトで行われるのか
- AとBは、Payment Channelをセットアップするためにチャネル決済に使用するコインをblockchain常にlockするFunding Transactionを生成する(この段階では、生成をしただけで、署名をしていないので、broadcastはされていない)
- AとBは、それぞれ秘密の値(Secret)とその値のHashを生成する.その中でHashのみを相手に伝える
- AとBは相手から受け取ったHashを使って、Funding TransactionのOutputをInputにしたCommitment Transactionをそれぞれ作り、自分の署名を付与して相手に送る.この時点で、お互いに相手が作成した相手の署名が付与されたCommitment Transactionを持っている.これにTransactionを付与すれば、Transactionは完成する.かつこのTransactionがBroadcastされれば、Broadcastしたユーザーが1000ブロック(条件(仮))待てば、コインを入手できる
- 最初のCommitment Transactionの交換が完了したら、1で作成したFunding Transactionに署名して、ネットワークにBroadcastして、Channelをオーブンできる
Channelがオープンしたら、そのChannelの範囲内でお互いにオフライン決済ができるようになる
Off-chain Payment
off-chain paymentは新しいシークレットの作成・交換を行い、決済の結果で残高を更新したCommitment Transactionを作り、自分の署名を加えて、相手に送る
着目すべきところは、Commitment Transactionを作る際に、前回のCommitment Transactionを生成する時に生成したSecretの値を相手に明らかにするということ
不正を働いた場合のペナルティ
Bが自分の取り分の多い過去のCommitment Transactionを Broadcastしようとしたとする その場合、AはBが1000ブロック(仮条件)を待っている間にA宛のTransactionを入手でき、かつ新規のTransactionのSecretも知っているので、全資金を入手できる しかし、そのためには、古いCommitment TransactionがBroadcastされていないかChainの監視をする必要がある
eltoo
Setup
1. Channlを開く前に各参加者はUpdate用(Au, Bu)とSettlement用(As, Bs)のキーペアを生成し、各公開鍵を相手と交換する - Update用の鍵 Channelの状態を更新する(新しい支払いをする)際に使用する鍵 - Settlement用の鍵 Channelを最終残高で閉じる際に使用する鍵
※ eltooでは、Channelの最新状態を表したTransactionを保持しておけば、古い状態がBoradcastされても、そのTransactionを最新状態を表すTransactionに置換することができる
- Aの資金を2-of-2のマルチシグにlockするFunding Transactionを生成する
- Funding TransactionのUTXOをInputにしたTrigger Transactionを作成
- Trigger TransactionをInputとしたSettlement Transactionを作成する.setupフェーズでは払い戻し用として機能し、Outputは5BTCがそのままAのアドレスにいく(Bが途中で消えてもいいように)
- AはFunding Transactionに署名し、Broadcastする
着目すべき点は、Lightning Networkの ContractはCommitment Transaction 1つでお互いの残高を管理していたが、eltooではTrigger Transaction(Update Transaction) と Settlement Transactionの2つでChannelの残高を管理する
Payment(1回目)
- A -> B に1BTCを支払うために、Trigger TransactionをInputとして、新しいUpdate Transactionを生成する
- Update TransactionのUTXOをInputとして、Outputに残高を反映してSettlement Transactionを生成する
Payment(2回目)
- B -> A に0.5BTCを支払うため、Trigger TransactionをInputとして、新しいUpdate Transactionを生成する
- Update TransactionのUTXOをInputとして、Output
eltooを可能にするSIGHASH_NOINPUT
通常、Transaction Dataが署名対象のメッセージダイジェストとなるため、Transaction Dataが1部でも変更されるとその署名は無効になる.そのため、現時点でのBTCの使用では実現不可能.
SIGHASH_NOINPUT
インプットが参照する前のTransactionのOutputの情報は全て空になる.署名はTransactionのOutPintにcommitしなくなり、署名後にInputが参照するOutPointの変更が可能になる
eltooのポイント: セトルメント鍵のローテーション
Settlement Transactionに署名する際に、SIGHASH_NOINPUTが使用される.不正があった場合に、対応するUpdate Transactionの参照先が変わると、Update TransactionのTXIDも変わり、Settlement TransactionのInputの参照先も変更する必要がある.
Update Transactionの条件で、セトルメント鍵でunlockする場合、その鍵は各状態ごとに異なる鍵を使用する.キーペアの導出自体はHDウォレット等と同様に、決定論的に導入される.これによりSettlement Transactionは対応するUpdate Transactionのみにbindされる
まとめ
eltooはPayment Channelで旧状態でBroadcastされた際に、罰ではなく、最新の状態を後から置換可能にするコントラストをベースにした 新しい Payment Channelの提案になる