build, compile

ソースコードインストール時は、build、コンパイルを経てインストールとなる。
こちらはお馴染みですね。

$ ./configure # 設定
$ make # build
$ sudo make install # インストール実行

C言語、C++をコンパイルするには、GNU Compiler Collection, GCCのインストールが必要
コンパイル → オブジェクトファイル → リンク → コマンド
↑コンパイルからリンクまでの一連の流れがビルド

ubuntuにgcc, makeが入っているか確認します。
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ gcc –version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ make –version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-pc-linux-gnu

hello.c を作る

#include <stdio.h>
	main(){
		printf("hello world.\n");
	}

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ls
hello.c
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ gcc hello.c
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ls
a.out hello.c
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ./a.out
hello world.

makefile

hello : hello.c
	gcc -o $@ $<

clean :
	rm -f hello

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ls
a.out hello.c Makefile
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ make
gcc -o hello hello.c
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ls
a.out hello hello.c Makefile
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ./hello
hello world.

makeはカレントディレクトリにmakefileがあるとそれに従って動く

bitcoin coreのmaikefile
https://github.com/bitcoin/bitcoin/blob/master/Makefile.am

WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \
  $(top_srcdir)/share/pixmaps/nsis-header.bmp \
  $(top_srcdir)/share/pixmaps/nsis-wizard.bmp \
  $(top_srcdir)/doc/README_windows.txt

OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \
  $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_SVG) \
  $(OSX_DSSTORE_GEN) \
  $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \
  $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh

OSXとwindowsだとビルド方法やパッケージが異なるなるのかな。

DNSシードのanswer section

digでmainnetのdnsseed.bluematt.meを叩く。
2つ目の項目”59″はTTL。CNAMEはあだ名みたいなことで、dnsseed.bluematt.me = x1.dnsseed.bluematt.me
下のIPがアクティブノードの接続先。
こうやってみると、DNSシードのレスポンスはアクティブノードのIPのみってことになる。

dnsseed.bluematt.me.	3599	IN	CNAME	x1.dnsseed.bluematt.me.
x1.dnsseed.bluematt.me.	59	IN	A	193.111.156.2
x1.dnsseed.bluematt.me.	59	IN	A	40.115.137.28
x1.dnsseed.bluematt.me.	59	IN	A	199.188.207.22
x1.dnsseed.bluematt.me.	59	IN	A	51.154.60.34
x1.dnsseed.bluematt.me.	59	IN	A	185.233.186.20
x1.dnsseed.bluematt.me.	59	IN	A	84.59.243.22
x1.dnsseed.bluematt.me.	59	IN	A	151.228.87.150
x1.dnsseed.bluematt.me.	59	IN	A	125.236.215.133
x1.dnsseed.bluematt.me.	59	IN	A	91.204.149.5
x1.dnsseed.bluematt.me.	59	IN	A	182.239.237.53
x1.dnsseed.bluematt.me.	59	IN	A	159.138.87.18
x1.dnsseed.bluematt.me.	59	IN	A	94.68.239.149
x1.dnsseed.bluematt.me.	59	IN	A	96.31.1.212
x1.dnsseed.bluematt.me.	59	IN	A	185.83.110.53
x1.dnsseed.bluematt.me.	59	IN	A	193.58.196.212
x1.dnsseed.bluematt.me.	59	IN	A	203.132.95.10
x1.dnsseed.bluematt.me.	59	IN	A	92.65.24.209
x1.dnsseed.bluematt.me.	59	IN	A	80.111.142.213
x1.dnsseed.bluematt.me.	59	IN	A	88.212.44.33
x1.dnsseed.bluematt.me.	59	IN	A	93.175.204.121
x1.dnsseed.bluematt.me.	59	IN	A	193.112.93.235

mainnetの、dnsseed.bitcoin.dashjr.orgの方もみてみます。あれ、dnsseed.bluematt.meとdnsseed.bitcoin.dashjr.orgだと、登録されているアクティブノードのIPが異なりますね。

dnsseed.bitcoin.dashjr.org. 429	IN	A	67.80.165.100
dnsseed.bitcoin.dashjr.org. 429	IN	A	37.187.122.82
dnsseed.bitcoin.dashjr.org. 429	IN	A	90.187.75.113
dnsseed.bitcoin.dashjr.org. 429	IN	A	155.138.208.87
dnsseed.bitcoin.dashjr.org. 429	IN	A	84.255.244.61
dnsseed.bitcoin.dashjr.org. 429	IN	A	85.214.38.87
dnsseed.bitcoin.dashjr.org. 429	IN	A	95.179.221.214
dnsseed.bitcoin.dashjr.org. 429	IN	A	173.249.0.235
dnsseed.bitcoin.dashjr.org. 429	IN	A	185.107.83.55
dnsseed.bitcoin.dashjr.org. 429	IN	A	139.162.7.9
dnsseed.bitcoin.dashjr.org. 429	IN	A	178.63.40.164
dnsseed.bitcoin.dashjr.org. 429	IN	A	96.241.146.239
dnsseed.bitcoin.dashjr.org. 429	IN	A	73.93.12.65
dnsseed.bitcoin.dashjr.org. 429	IN	A	119.17.151.61
dnsseed.bitcoin.dashjr.org. 429	IN	A	34.244.231.62
dnsseed.bitcoin.dashjr.org. 429	IN	A	94.112.167.129
dnsseed.bitcoin.dashjr.org. 429	IN	A	155.138.235.87
dnsseed.bitcoin.dashjr.org. 429	IN	A	199.247.18.168
dnsseed.bitcoin.dashjr.org. 429	IN	A	45.16.103.141
dnsseed.bitcoin.dashjr.org. 429	IN	A	5.135.159.65
dnsseed.bitcoin.dashjr.org. 429	IN	A	89.47.217.222
dnsseed.bitcoin.dashjr.org. 429	IN	A	185.25.48.148
dnsseed.bitcoin.dashjr.org. 429	IN	A	35.209.163.61

bluemattの方のipをjsonファイルに書き換えてみます。

{
	"ip": ["193.111.156.2", "40.115.137.28", "199.188.207.22", "51.154.60.34", "185.233.186.20", "84.59.243.22", "151.228.87.150", "125.236.215.133", "91.204.149.5", "182.239.237.53"]
}

Bitcoin Coreはノード情報をディスク上のDBに保存って仕組みでしたね。
あれ、ディスクのDBってどういうこと?ubuntuだったら、postgresってこと?

DNS

DNSはDomain Name Systemの略
ドメイン名とIPアドレスの対応付け
メールの宛先ホストを指示

→ IPアドレスではわかりにくい為、名前で指定
ARPANETではホスト名とIPアドレスの対応表としてHOSTS.txtを使用していた。
SRI-NICから入手して接続。SIR-NICはホストとIPの更新作業を行なっていた。実態はAT&Tなど
現在の/etc/hosts と同様

ファイルの増大化に伴い、1983年にRFC882、RFC883発表 これが現在のDNSの元
RFC882:https://tools.ietf.org/html/rfc882
RFC883:https://tools.ietf.org/html/rfc883

DNSの仕組み
名前空間最上位にルートサーバが作成。ルートサーバはjp, comなどドメイン名を管理
ドメインを階層構造で管理、更新を分散化

問い合わせを行う為のDNSサーバはキャッシュ機能がある

セカンダリDNSとは負荷分散、障害対策のために、DNSを二つ用意する
DNSSECとはデータ作成元の認証やデータの完全性を確認できるよう仕様を拡張するもの

1つの権威DNSサーバが管理する範囲をゾーンと呼び、その情報をゾーン情報と呼ぶ
ゾーン情報は、Aレコード、MXレコード、NSレコードなど多数のゾーン情報がある

SOA: ゾーン情報を記載(ドメインDNS, ドメイン管理者、更新間隔、転送再試行、レコード有効時間、キャッシュ有効時間) 他のDNSに転送する
NS: ドメインのDNSサーバ名を指定
A: ホストのIPアドレス
PTR: IPアドレスに対するホスト名
CNAME: ホスト名のエイリアス
MX: ドメインのメール・サーバ名
HINFO: ホストの追加情報
WKS: ホストで実行されているサービス情報
TXT: ホストへのテキスト情報

ネームサーバーとは、インターネット通信時にドメイン名をIPアドレスに変換する名前解決を行うサーバー
ネームサーバー = DNSサーバー

Route53で言う所の SOAがゾーン情報、NSがドメインのDNSサーバーに当たる

AWSのroute53で登録するとDNSサーバーがawsになる。

サーバー側で、virtual hostを設定すると、指定したディレクトリをさす

<VirtualHost *:80>
DocumentRoot /www/example1
ServerName www.example.com

# Other directives here

</VirtualHost>

ルートネームサーバからサーバに繋げるのはわかるけど、シードDNSがクライアントにipを返す仕組みがわからないな。

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ nslookup google.com
Server: 10.0.2.3
Address: 10.0.2.3#53

Non-authoritative answer:
Name: google.com
Address: 216.58.199.238

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ nslookup 216.58.199.238
Server: 10.0.2.3
Address: 10.0.2.3#53

Non-authoritative answer:
238.199.58.216.in-addr.arpa name = kix05s02-in-f238.1e100.net.
238.199.58.216.in-addr.arpa name = kix05s02-in-f14.1e100.net.

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ dig google.com

; <<>> DiG 9.9.5-3ubuntu0.19-Ubuntu <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54587 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;google.com. IN A ;; ANSWER SECTION: google.com. 205 IN A 216.58.197.14 ;; Query time: 48 msec ;; SERVER: 10.0.2.3#53(10.0.2.3) ;; WHEN: Fri Nov 01 11:29:11 UTC 2019 ;; MSG SIZE rcvd: 55

P2Pネットワークの仕組みを作ろう

イメージとしては、DNSシードが複数のノードIPを持っていて、シードから取得すると、ノードにアクセスしてハンドシェイクって流れだ。

こんな感じ。

さて、これをどーやってコーディングしていきましょうか。。。

BIP, Open Asset Protocol

富士通の帳票ソフトウェアではありません。
Bitcoin Improvement Proposal
https://github.com/bitcoin/bips

ソフトフォークとハードフォークでプロセスが異なる

Open Asset Protocolは、仮想通貨以外のアセットを発行・取引する
https://github.com/OpenAssets/open-assets-protocol

bitcoin white paper
https://bitcoin.org/files/bitcoin-paper/bitcoin_jp.pdf

どうなってんだこれ。。

ノードとネットワーク

ビットコインのプロトコルに対応するノードはフルノードと呼ばれる全取引データを保持するノードとSPV(Simplified Payment Vertification)と呼ばれるブロックヘッダと自分に関連するデータのみを保持する軽量ノードがある
Bitcoin Coreはフルノード
ブロックのヘッダのみをダウンロードし、必要に応じてフルノードにトランザクションを要求するクライアントでSPVノードと呼ぶ

■ネットワークの発見
最初はDNSシードに問い合わせにいく
– seed.bitcoin.sipa.be
– denseed.bitcoin.dashjr.org
– eed.bitcoinstats.com
– seed.bitcoin.jonasschnelli.ch

DNSシードに問い合わせると、新しい接続を受け入れられるフルノードのIPアドレスが1つ以上返ってくる

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ dig seed.bitcoin.sipa.be

; <<>> DiG 9.9.5-3ubuntu0.19-Ubuntu <<>> seed.bitcoin.sipa.be
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34073 ;; flags: qr rd ra; QUERY: 1, ANSWER: 25, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;seed.bitcoin.sipa.be. IN A ;; ANSWER SECTION: seed.bitcoin.sipa.be. 3599 IN A 104.248.20.174 seed.bitcoin.sipa.be. 3599 IN A 79.124.17.204 seed.bitcoin.sipa.be. 3599 IN A 5.135.186.15 seed.bitcoin.sipa.be. 3599 IN A 104.171.172.17 seed.bitcoin.sipa.be. 3599 IN A 94.130.207.23 seed.bitcoin.sipa.be. 3599 IN A 138.201.56.109 seed.bitcoin.sipa.be. 3599 IN A 73.255.112.134 seed.bitcoin.sipa.be. 3599 IN A 93.115.89.76 seed.bitcoin.sipa.be. 3599 IN A 108.11.187.129 seed.bitcoin.sipa.be. 3599 IN A 116.203.136.157 seed.bitcoin.sipa.be. 3599 IN A 15.164.169.200 seed.bitcoin.sipa.be. 3599 IN A 47.74.245.182 seed.bitcoin.sipa.be. 3599 IN A 74.98.242.97 seed.bitcoin.sipa.be. 3599 IN A 212.170.100.71 seed.bitcoin.sipa.be. 3599 IN A 59.110.18.37 seed.bitcoin.sipa.be. 3599 IN A 193.30.123.209 seed.bitcoin.sipa.be. 3599 IN A 217.125.246.37 seed.bitcoin.sipa.be. 3599 IN A 185.2.101.192 seed.bitcoin.sipa.be. 3599 IN A 94.26.190.7 seed.bitcoin.sipa.be. 3599 IN A 123.134.246.100 seed.bitcoin.sipa.be. 3599 IN A 78.47.168.239 seed.bitcoin.sipa.be. 3599 IN A 23.175.0.212 seed.bitcoin.sipa.be. 3599 IN A 5.2.194.97 seed.bitcoin.sipa.be. 3599 IN A 91.178.131.108 seed.bitcoin.sipa.be. 3599 IN A 173.212.207.249 ;; Query time: 271 msec ;; SERVER: 10.0.2.3#53(10.0.2.3) ;; WHEN: Thu Oct 31 15:16:59 UTC 2019 ;; MSG SIZE rcvd: 449 他のノードとの接続はディスク上のDBに保存する プロトコルバージョンのサポート vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli getnetworkinfo { "version": 170100, "subversion": "/Satoshi:0.17.1/", "protocolversion": 70015, "localservices": "000000000000040d", "localrelay": true, "timeoffset": 0, "networkactive": true, "connections": 3, "networks": [ { "name": "ipv4", "limited": false, "reachable": true, "proxy": "", "proxy_randomize_credentials": false }, { "name": "ipv6", "limited": false, "reachable": true, "proxy": "", "proxy_randomize_credentials": false }, { "name": "onion", "limited": true, "reachable": false, "proxy": "", "proxy_randomize_credentials": false } ], "relayfee": 0.00001000, "incrementalfee": 0.00001000, "localaddresses": [ ], "warnings": "" } コマンドがversionとverackのメッセージを使ってハンドシェイクを行う 相手のノードのバージョンとuser agentが表示され、ハンドシェイクが完了 ブロックチェーンの同期が終わったあとは、ブロードキャストされたブロックを受診してブロックチェーンを更新

P2PKH, マルチシグ

支払い形式によって、スクリプトの設定方式が複数存在
– ScriptPubKey

def self.to_address_script(address)
	hash160 = Bitcoin.hash160_from_address(address)
	case Bitcoin.address_type(address)
	when :hash160; to_hash160_script(hash160)
	when :p2sh; to_p2sh_script(hash160)
	end
end

– ScriptSig

UTXOを使用するには複数の署名が必要になる
m-of-nマルチシグはn人のうちm人が署名すればできる

ScriptPubKeyにスクリプトのハッシュを設定することで単純化したものがP2SH
ハッシュを用いてトランザクションに含まれるデータ量を少なくすることで取引手数料を低く抑える

ロックタイム(OP_CLTV, OP_CSV)
特定のUTXOを使用したトランザクションを設定したブロック高またはUNIXタイムまでブロックに含まれないよう制限をかけることができる