トランザクション

トランザクションはインプット、アウトプット、その他トランザクションに関わる情報を含んでいる
version 4byte 32bit符号なし整数
tx_in_count 1-9byte 可変長整数 インプットのリストに含まれるアイテム数
tx_in 可変 TxIn インプットのリスト
tx_out_count 1-9byte 可変長整数 アウトプットリストに含まれるアイテム数
tx_out 可変 TxOut アウトプットリスト
locktime 4byte 32bit符号なし整数 ブロックに取り込まれる値を制御

インプットの構成
hash 32byte char[32] 全てのビットが0
index 4byte 32bit符号なし整数 値は0xffffffff
coinbase data bytes 可変 可変長整数 コインベースデータのバイト数 2~100
coinbase data 可変 char[] 任意のデータ
sequence 4 32bit符号なし整数 値は0xffffffff

ビットコインではスクリプト言語を利用して電子署名と署名の検証を行なっている
アウトプットのscriptpubkeyには電子署名を検証する命令、インプットのscriptsigには電子署名をスクリプト言語で記述する

電子署名はUTXOの持ち主であることを証明する。署名には秘密鍵を使用
トランザクション -> sha256 -> sha256 -> signature hash -> ecdsa署名 -> signature -> signature -> トランザクション インプット0

トランザクション作成の工程
– インプットにセットするUTXOの準備
– トランザクション全体の作成
– インプットの作成
– アウトプットの作成
– 署名
– ブロードキャスト

ブロックチェーンのブロック

ブロックチェーンの仕様の修正はソフトフォークとハードフォークがある。ソフトフォークは古いブロックの仕様と互換性がある仕様の修正。ハードフォークは大きな仕様の変更。マイナーがフォークを採用するかどうかにかかっている

ブロック構造
4バイト: Block Size: ブロックのデータサイズ
80バイト: Block Header: ブロックヘッダ
1〜9バイト: Transaction Counter: ブロックに含まれるトランザクション数
可変長: Transactions: ブロックに含まれるトランザクションのリスト

ブロックの識別子はブロックハッシュとブロック高がある
getchaintipsで先端がわかる
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli getchaintips
[
{
“height”: 0,
“hash”: “000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f”,
“branchlen”: 0,
“status”: “active”
}
]

マイニング処理
当初の設計ではnonceフィールドの値を順次変更しながらsha-256によるハッシュ値の計算を求め、そのハッシュ値がブロックヘッダのdifficulty targetフィールドで定められた難易度ターゲットよりも小さい数値であれば成功

現在は、Thash/sec, PHash/sec, EHash/sec
新規ブロックの作成と同時にマイナーが作成するコインベーストランザクションの領域を利用
コインベーストランザクションをextraNonceとして利用している
hash char[32] 32byte
index uint32_t 4byte
script bytes compactSize unit
height script
coinbase script None
sequence uint32_2 4byte

マイニング難易度はdifficulty target
target = 係数部*2**(8*(指数部-3))

def target(difficulty_target)
	exponent=difficulty_target[0..1].hex
	coefficient=difficulty_target[2..7].hex
	(coefficient*2**(8*(exponent-3)))
end

ビットコインの送金

取引手数料の設定
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli settxfee 0.00001
true

bitcoin-cli sendfrom <送信元アカウント> <送信先ビットコインアドレス> <送信金額>

トランザクション内容の確認
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli gettransaction 01307080d1961631b0da844024d8c842bd805dac38bfadb9ce5a771b6a55691a

トランザクションの一覧
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli listtransactions

支払い請求のURI形式の標準がBIP0021として定義されている
walletの秘密鍵が漏洩すると、資産が盗まれてしまう
 → これってつまり、リミックスもwalletの秘密鍵が盗まれたって事??でも秘密鍵は暗号化していたと会見で言っていたみたいだが。。そういえば、suicaとか電子マネーの上限が決まっているのも、盗難の懸念を考慮してなのかもしれませんね。

オンライン状態をホットストレージ、オフラインをコールドストレージ
秘密鍵はコールドストレージに保管する

ルートシードとマスター秘密鍵
walletのホットストレージ、コールドストレージを挟んだ鍵の設計は非常に複雑だな。。。
リミックスの場合は、ホットウォレットの秘密鍵が全部盗まれ解読されたんかいな。
でも普通、秘密鍵のストレージには外部からアクセスできないように、ファイヤーウォール、ip制御、token管理とかするよね。

ビットコインアドレスの生成

Bitcoin Coreで自分のwalletに新しい公開鍵暗号の鍵のペアを作成する
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoind -daemon
Bitcoin server starting
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli getnewaddress
39Gydphv6RaWwmx3bwEbGihtvXdXWXnobW

walletの秘密鍵の暗号化
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli encryptwallet password
wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup.
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoind -daemon
Bitcoin server starting

U01 testnet Faucet https://bitcoinfaucet.uo1.net/

あれ、rpc errorってなってる??

transactionがpendingになっているので、Proof of workがまだって理解でOK?
vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli getbalance
0.00000000

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ bitcoin-cli listunspent
[
]

bitcoin coreを動かすと、大分具体的になるね。

require 'bitcoin'
require 'net/http'
require 'json'
Bitcoin.network = :testnet3
RPCUSER = 
RPCPASSWORD =
HOST = "localhost"
PORT=18332

def bitcoinRPC(method, param)
	http = Net::HTTP.new(HOST, PORT)
	request = Net::HTTP::Post.new('/')
	request.basic_auth(RPCUSER,RPCPASSWORD)
	request.content_type = 'application/json'
	request.body = {method: method, params: param, id: 'jsonrpc'}.to_json
	JSON.parse(http.request(request).body)["result"]
end

ビットコインアドレス

ビットコインの送金は原理的には送金先の公開鍵があればできる
ビットコインで実際に送金先を表す固有名はビットコインアドレス
公開鍵と1対1に対応している

ビットコインアドレスは、チェックサム、プレフィックス、base58エンコーディングの利用を行なっている

0x04 公開鍵x 256ビット 公開鍵y 256ビット
↓                     チェックサム
1バイト ペイロード 20バイト(160バイト) 4バイト
↓ base58 エンコーディング
ビットコインアドレス アルファベット26-35文字

base58エンコーディングは1,l,0,o,+,/,=を使わない

プレフィックス
ビットコインアドレスの先頭1バイトはバージョン・種別を表す
0x00(mainnet), 0x6F(testnet), 0x05(mainnet), 0xC4(testnet)

チェックサム
SHA256(SHA256(プレフィックス + 512ビット公開鍵))

nonce

暗号学では、一度しか使わないランダムな数値の事をnonceと呼ぶ
メッセージにnonceを追加した上で、そのハッシュ値を計算し、メッセージとハッシュ値を公開した場合、nonceを知っている者だけしかハッシュ値を計算できない
ビットコインのマイニングは、nonceを変更しながらブロックのデータのハッシュ値を繰り返し計算する
ターゲットよりも小さいハッシュ値を最初に得たものが勝利者となる
ハッシュチェーンの一つにマークル木がある
SHA-256とRIPEMD-160をハッシュ関数として標準利用、SHA-1の衝突耐性は失われている

暗号鍵と公開鍵の作成

require 'ecdsa'
require 'securerandom'

group = ECDSA::Group::Secp256k1
n = group.order

private_key = 1 + SecureRandom.random_number(n-1)

# print private_key

pubKey = group.generator.multiply_by_scalar(private_key)
print pubKey.x
print pubKey.y

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
7200274859625909218305600661424454855533433802141920888525182327364340449554183445379063984485161576009152500901248299335294365713023890298728510086562018

ECDSA

ECDSA(Elliptic Curve Digital Signature Algorithm)
楕円曲線デジタル署名アルゴリズム
ビットコインの電子証明などに利用されている
ECDSAは公開鍵の暗号化技術の名前
RSAに比べ約1/10のコンパクトな容量

require 'ecdsa'
require 'securerandom'

group = ECDSA::Group::Secp256k1
n = group.order

private_key = 1 + SecureRandom.random_number(n-1)

print private_key

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
106515493506888278075922016172190811663525618981292515102301206639235796458599

スタートアップハブ Tokyo

スタートアップハブ Tokyoから、なんか手紙来た? と思ったら、quoカードだった^^
利用者アンケート。

dav

こういうの当たったことないから嬉しい^^
スタートアップの空気感だと、Gaiaxとかもいい印象だけど、スタートアップハブもサービスいいね。

ビットコインの暗号技術

OpenSSL
-> インターネット上で標準的に利用される暗号通信プロトコルであるSSLおよびTLSの機能を実装したオープンソースライブラリ

require 'openssl'

data = '*secret data*'

key = 'a' * 32
iv = 'i' * 16

enc = OpenSSL::Cipher.new('AES-256-CBC')
enc.encrypt
enc.key = key
enc.iv = iv
encrypted_data = enc.update(data) + enc.final
# print encrypted_data

dec = OpenSSL::Cipher.new('AES-256-CBC')
dec.decrypt
dec.key = key
dec.iv = iv 
decrypted_data = dec.update(encrypted_data) + dec.final
print decrypted_data

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
5????
g`??Ա?

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
*secret data*

IntelのIvy Bridge以降のCPUやRaspberry Pi, Apple A7以降のプロセッサには、熱雑音を利用して物理的に乱数を発生させるハードウェア乱数生成器が備わっている

rubyの安全な乱数: securerandom

require 'securerandom'
hex = SecureRandom.hex(32)
print hex

vagrant@vagrant-ubuntu-trusty-64:~/bitcoin$ ruby main.rb
1fbd11b0d5588de19571e3679ee86387d2449b6d376f6211498e4dbd2557fabd

ビットコインのトランザクション

総量保存則
データ構造は、インプットとアウトプットという2つの領域で出来ている
複数存在することが可能
複式簿記と同様、インプットとアウトプットの総額は一致しないといけない
確実性の保証の為、トランザクションに対する会計監査が必ず一致しないといけない
通貨的価値が増減することはない為、通貨価値の総量保存則と呼んでいる

自制式三色簿記構造
トランザクションのアウトプットには、未使用状態と使用済み状態があり、未使用状態のアウトプットをUTXO(unspent transaction output)と呼ぶ
使用済みアウトプットは次のトランザクションのインプットから参照

トランザクションの手数料
送信者はマイナーに対して自分のトランザクションを優先的にブロックに取り込んでもらう為、手数料を支払う必要がある
インプットの総額とアウトプットの総額の差額が手数料
どのトランザクションをブロックに含めるかどうかはマイニングに成功したマイナー次第

-トランザクション手数料に関するパラメータのデフォルト値
txconfirmtarget: 2(block)
paytxfee: 0(BTC/kB)
fallbackfee: 0.0002 BTC/kB
maxtxfee: 0.10BTC

マイナーは受け取ったトランザクションをメモリープールに保管し、マイニングに成功するとブロックに格納する
ブロックサイズは固定
ハッシュチェーンという暗号技術とマイニングと呼ばれる計算競争が行われている

ハッシュチェーンは暗号学的ハッシュ関数を利用
1つのブロックには、平均10分間、数百から数千程度のトランザクションが格納
ブロック高0はジェネシス・ブロックと呼ばれる
マイニングの計算競争の難易度は、要する時間の平均が10分になるように自律的に調整されている
マイナーは中国を中心とする専門業者の独壇場になっている(10社程度でシェア90%)
通貨発行権はマイナーが持つ

公開鍵暗号を採用しており、ワレットをインストールすると、秘密鍵、公開鍵が生成されてワレットに登録される
最も長い枝が正統なブロックチェーンというルール
最新のブロックが接続するまでに何個のブロックが存在しているかの数を確認数という