[プログラミング言語の作り方] 字句解析、構文解析、インタープリタ、コンパイラ

プログラミング言語を作るには、ルールに合致した機械的な文字列だけを扱う割り切ったプログラムを作ること
インタプリタとコンパイラの共通処理として、字句解析と構文解析がある
※インタプリタは1行ずつ変換すると同時に、その都度命令を処理実行する
※コンパイラは全ての命令をまとめて一括で変換して、一気に処理実行する

### 字句解析(lexical analysis)とは
単語を意味のあるトークンに区切る

num=13-5*2;
print(num);

こちらをtoken配列に入れる文字列処理する

tokens = [
	"num", "=", "13", "-", "5", "*", "2", ";",
	"print", "(", "num", "num", ";"
];

文字列を分割するsplit機能や正規表現は最近の言語では備わっている
C言語の場合は、一文字ずつアルファベットか数字か記号かをチェックしていく
字句解析は、簡単な文字列分割機能だけで十分

### 構文解析(parsing)
処理を途中で止める手段が必要だが、例えば引き算を解析する関数を呼ぶ
tree構造のデータにすると分かりやすくなる。抽象構文木(AST: abstract syntax tree)
tree構造にすると、leftとrightに分けて、=, *, -, () などはopと呼ぶのが面白い。bitcoinのOPやハッシュ値のparseとプログラミング言語のparsingにかなり共通点があることがわかる。

{
	left: {
		left: 'num',
		op: '=',
		right: {
			left: '13',
			op:'-',
			right: {
				left: '5',
				op: '*',
				right: '2' 
			}
		}
	},
	op: ';'
	right: {
		left: 'print',
		op: '()',
		right: 'num'
	}
}

parsingとは、token配列をASTに変換する

### インタプリタ
字句解析、構文解析の後、ASTをそのまま実行する

### コンパイラ
字句解析、構文解析の後、ASTを元に、アセンブラを出力する
アセンブラのテキストファイルはasコマンドでバイナリに変換する
その後、リンカと呼ばれるldコマンドで、複数のオブジェクトファイルを連結して1つの実行ファイルにする
実行ファイルを実行すると、execシステムコールが呼ばれ、OSはバイナリ中で指定されたローダーと呼ばれる外部プログラムを起動する。
ローダーは実行ファイルや動的ライブラリなどをメモリ上に配置して、指定されたエントリポイントからCPUに制御を渡す

[LightningNetwork] pathfinding

支払い人から受取人へのパスを見つけることをpathfindingと呼ぶ
PathfindingはBOLTでは定義されておらず、さまざまなアルゴリズムを選択できる
平均チャネル数は8.8で上位のノードは2000のチャネル数もある
pathfindingはグラフトラバーサルに分類される
MCFPと呼ばれるコストを最小にしながら特定のフローを実現

パス候補のリストを作成し、何らかの関数でフィルタリングしてソートする。続いて、送信できるパスが見つかるまで、パスのプロービングを行う
チャネルグラフの構築で、node_announcementでIP情報が含まれているため、地図を作成できる
マルチパートペイメントでpathを柔軟化できる

[LightningNetwork] オニオンルーティング

オニオンルーティングはTorで使われている暗号化通信の手法
メッセージの送信者が入れ子になった暗号化の層を作成
origin nodeとfinal nodeがある

共通シークレット、セッションの秘密鍵、公開鍵からECDHアルゴリズムにより、rho, mu, um, padの鍵を生成する
オニオンをラッピングする

### ゴシッププロトコル(共有)
LNのイニシャルピアディスカバリはDNSに基づく
チャネルを、チェーン内の位置に基づいて参照する

[LightningNetwork] ルーティング

パス上の中間ノードをルーティングノードという
ライトニングネットワークはHash Time-Locked Contractを採用している
経路探索はチャネルグラフを調べる
ルーティングは経路探索によって事前に選択されたパスを使って、AからBにペイメントを転送しようとするネットワーク経由の一連のやり取り

エスクロー契約にして、ペイメントハッシュでやり取りを行う
契約には期限を設定する
ノードが預託を行うに十分な資金を持っている必要がある
PTLC(Point Time-Locked Contract)はSchnorr signature
インボイスをAliceからDinaにリクエストし、発行する

### HTLC(Hash Time-Lock Contract)
インボイスに暗号学的ハッシュ関数が入っている
H = Sha256(R)
OP_HASH160 OP_EQUALVERIFY
ペイメントプリイメージとの比較
受取人とマッチする公開鍵とその署名をスクリプトに入れる
OP_SHA256 OP_EQUALVERIFY OP_ChECKSIG

[LightningNetwork] ペイメントの送信

### ペイメントの送信
AliceとBobでコミットメントトランザクションを作成する
ブロードキャストするとファンディングアウトプットが消費される

### ライトニングプロトコルの失効とペナルティのメカニズム
– 非対称コミットメントトランザクション
L self, remotoとする
L 資金を取り戻す時間が与えられる
– 遅延支払い
– 失効鍵
L ペナルティトランザクションを作成することでチャネルの資金を独り占めできる

### チャネルの状態遷移
commitment_signedとrevoke_and_ackの2つのメッセージを交換する

commitment_signed: channel_id, signature, num_htlcs, htlc_signature
revoke_and_ack: channel_id, per_commitment_secret, next_per_commitment_point

[LightningNetwork] payment channel

2of2マルチシグのトランザクションを保管していて、そのトランザクションを独占的に使う手段となり得たら、そのビットコインを事実上所有していることになる。
ペイメントチャネルは2人のチャネルパートナーが2of2マルチシグアドレスにファンディングを行うことによって確立される
ライトニングノードはノードの公開鍵によって識別
ネットワークアドレスはTCP/IPもしくはTCP/Tor

識別子は ノードID@address:port
2つのノード間の通信をLightning Peer Protocol for Channel Managementと呼ぶ
チャネルはメッセージの交換で確立される
open_channel, accept_channel, funding_created, funding_signed, channel_ready, channel_readyの6つの時系列
トランザクションが十分な数の承認を得た時点で、channel_readyメッセージを交換し、チャネルは通常の実行モードを開始

### マルチシグアドレス
2 2 CHCKMULTISIG
=> p2wshのアドレスとしてエンコードされる
トランザクションを作成し、署名するがブロードキャストしない
払い戻しトランザクションを作成する…ファンディングトランザクションのインプットを計算する

### funding_created
funding_txid
funding_output_index

### funding_signed
channel idはfunding transaction idとoutput indexのビットごとのxor

### funding_transactionをブロードキャスト
ブロックチェーンでの承認数がminimum_depthになるのを待つ。その後channel_readyメッセージで相手に送信

[bitcoin] IBDが終わるとどうなるか

$ bitcoin-core.daemon -testnet -prune=1000
// 省略
2024-01-08T08:05:09Z UpdateTip: new best=000000000000000d549bd14334c241abfeb36cc5b6d04541af6061c0a21cdc92 height=2571591 version=0x20800000 log2_work=75.635907 tx=68073107 date=’2024-01-08T07:53:55Z’ progress=0.999999 cache=10.3MiB(35178txo)
2024-01-08T08:08:24Z Disconnecting outbound peer 15 for old chain, best known block =
2024-01-08T08:08:24Z New outbound peer connected: version: 70016, blocks=2571591, peer=17 (outbound-full-relay)

$ bitcoin-core.cli -getinfo -testnet
Chain: test
Blocks: 2571591
Headers: 2571591
Verification progress: 99.9999%
Difficulty: 38940120.97505151

Network: in 0, out 10, total 10
Version: 250100
Time offset (s): -2
Proxies: n/a
Min tx relay fee rate (BTC/kvB): 0.00001000

Warnings: Unknown new rules activated (versionbit 28)

progressが99.9999%で待受状態となる
outbound-full-relay隣nodeが待機しているのね。
なるほど〜

[LightningNetwork] LN node software

LNの仕様はBOLT(basis of lightning technology)に定義
LNのプロトコルスタックは5つの層になる

– ネットワーク接続層
TCP/IP, オーバーレイプロトコル(Tor v3), 暗号トランスポートプロトコル

– メッセージング層
negotiate, message format, message field

– P2P
message

– routing
ノード間でのペイメントのルーティングをエンドツーエンド方式でアトミックに行う

– ペイメント

regtestモードのbitcoin coreコンテナをbuildする

Bitcoin CoreとRegtest
ライトニングノード実装のほとんどは、正常に動作するためにビットコインのフルノードにアクセスできなければならない。

### regtestモード
テスト用にシミュレートされたビットコインブロックチェーンがローカルに作成される
10秒ごとに新しいブロックを6つずつマイニングするよう設定されている
RPC(Remote Procedure Call)はポート18443で提供されており、ユーザ名regtest, パスワードregtestでRPC呼び出しにアクセスできる
マイニングされたビットコインはブロック数が100を超えるまで使えない制約がある

$ sudo docker pull lnbook/bitcoind
$ sudo docker run -i –name bitcoind lnbook/bitcoind –platform linux/amd64/v8
WARNING: The requested image’s platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
exec /usr/local/bin/bitcoind-entrypoint.sh: exec format error

m1に対応していない?
LNには、c-lightning, LND, Eclairなど様々なプロジェクトがある。

Ubuntu22.04にdockerをインストール

1. Set up Docker’s apt repository.
# Add Docker’s official GPG key:
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
$ echo \
“deb [arch=$(dpkg –print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo “$VERSION_CODENAME”) stable” | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update

2. Install the Docker packages.
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
$ sudo docker -v
Docker version 24.0.7, build afdd53b
$ sudo docker run hello-world
Unable to find image ‘hello-world:latest’ locally
latest: Pulling from library/hello-world
478afc919002: Pull complete
Digest: sha256:ac69084025c660510933cca701f615283cdbb3aa0963188770b54c31c8962493
Status: Downloaded newer image for hello-world:latest

Hello from Docker!