比特幣學習地圖

比特幣學習目標

  1. 理解比特幣是為了解決什麼問題
  2. 理解比特幣的分散式帳本技術 (DLT)
  3. 理解中本聰對比特幣的期待
  4. 理解比特幣的共識算法 (POW)
  5. 理解比特幣的UTXO
  6. 理解比特幣的交易類型
  7. 理解比特幣的 raw 交易
  8. 理解比特幣的側鏈
  9. 說明比特幣目前遇到的瓶頸及困難
  10. 理解閃電網絡及隔離驗證
  • 前情提要
    • DLT, Distributed Ledger Technology
    • UTXO, Unspent Transaction Output
    • Consensus Proof-of-Work

Bitcoin Script

轉移權說明:

在比特幣的世界裡,所謂交易是輸入腳本 (scriptSig) 與配合的UTXO轉移BTC至輸出腳本 (scriptPubKey)。

日後,如果要轉移這筆輸出腳本的錢,必須要把該輸出腳本弄成這次交易的輸入。

輸入 (vin):交易ID與第幾筆 out (UTXO)[1]、輸入腳本 (scriptSig)
輸出 (vout):value、scriptPubKey

[1] 交易ID與第幾筆out為一個UTXO


工具

1
2
3
4
5
6
7
8
# 常用 opcode
0xae OP_CHECKMULTISIG
0x76 OP_DUP
0xa9 OP_HASH160
0x88 OP_EQUALVERIFY
0xac OP_CHECKSIG
0x87 OP_EQUAL
0x6a OP_RETURN # Marks transaction as invalid

交易型態

一、P2PK (Pay to Public Key) or pubkey

地址形式:1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
e.g. 1Q2TWHE3GMdB6BZKafqwxXtWAWgFt5Jvm3

scriptPubKey:
<公鑰> OP_CHECKSIG

e.g.

1
04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_CHECKSIG

raw:

1
434104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac

scriptSig:
<簽名>

e.g.

1
30440220576497b7e6f9b553c0aba0d8929432550e092db9c130aae37b84b545e7f4a36c022066cb982ed80608372c139d7bb9af335423d5280350fe3e06bd510e695480914f01

raw:

1
4730440220576497b7e6f9b553c0aba0d8929432550e092db9c130aae37b84b545e7f4a36c022066cb982ed80608372c139d7bb9af335423d5280350fe3e06bd510e695480914f01

題:https://blockchain.info/tx-index/15029
解:https://blockchain.info/tx-index/180223


key generation

b58check_encode

b58check_encode

二、P2PKH (Pay to Public Key Hash) or pubkeyhash

地址形式:1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
e.g. 15kDhRAcpgsugmh6mQsTcCHdvbsuYncEEV

scriptPubKey:

1
OP_DUP OP_HASH160 <地址 hex> OP_EQUALVERIFY OP_CHECKSIG

1
2
3
4
5
6
# pybitcointools
b58check_to_hex('15kDhRAcpgsugmh6mQsTcCHdvbsuYncEEV')
# '340cfcffe029e6935f4e4e5839a2ff5f29c7a571'

hash160('04fc60372d27b067ca306ba812ced9c8cd69296b83a40b9b57c593258c1b9e0ee1c0c621ca558b878395f9645a4b67a96e51843e9c060d43a3833fdd29a91f4f31'.decode('hex'))
# '340cfcffe029e6935f4e4e5839a2ff5f29c7a571'
1
2
3
4
5
6
7
8
# python3
hash160(bytes.fromhex('04fc60372d27b067ca306ba812ced9c8cd69296b83a40b9b57c593258c1b9e0ee1c0c621ca558b878395f9645a4b67a96e51843e9c060d43a3833fdd29a91f4f31'))
'340cfcffe029e6935f4e4e5839a2ff5f29c7a571'

# or
import codecs
hash160(codecs.decode('04fc60372d27b067ca306ba812ced9c8cd69296b83a40b9b57c593258c1b9e0ee1c0c621ca558b878395f9645a4b67a96e51843e9c060d43a3833fdd29a91f4f31','hex'))
# '340cfcffe029e6935f4e4e5839a2ff5f29c7a571'

e.g.

1
OP_DUP OP_HASH160 340cfcffe029e6935f4e4e5839a2ff5f29c7a571 OP_EQUALVERIFY OP_CHECKSIG

raw:

1
1976a914340cfcffe029e6935f4e4e5839a2ff5f29c7a57188ac

scriptSig:

1
<簽名> <公鑰>

e.g.

1
2
30440220694ff325724a4f4b0f3f0c36bf8e94cac58ad7c9b4d5bd8c7286c0da623f0b2c02206ae94680a8f31f30cd846da258e919c94afe2dd629b4f4ce11bbe8165ff99a5f01 
04fc60372d27b067ca306ba812ced9c8cd69296b83a40b9b57c593258c1b9e0ee1c0c621ca558b878395f9645a4b67a96e51843e9c060d43a3833fdd29a91f4f31

raw:

1
8a4730440220694ff325724a4f4b0f3f0c36bf8e94cac58ad7c9b4d5bd8c7286c0da623f0b2c02206ae94680a8f31f30cd846da258e919c94afe2dd629b4f4ce11bbe8165ff99a5f014104fc60372d27b067ca306ba812ced9c8cd69296b83a40b9b57c593258c1b9e0ee1c0c621ca558b878395f9645a4b67a96e51843e9c060d43a3833fdd29a91f4f31

題:https://blockchain.info/tx-index/180223
解:https://blockchain.info/tx-index/180233

三、 P2SH (Pay to Script Hash) or scripthash

地址形式:3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
e.g. 3HfFJ5cGCG2m2RbadnsCHit9UzhPR5J2GF

scriptPubKey:

1
2
3
4
5
6
7
8
OP_HASH160 <地址 hex> OP_EQUAL

# pybitcointools
b58check_to_hex('3HfFJ5cGCG2m2RbadnsCHit9UzhPR5J2GF')
# 'af2c57a99f55747423e4af65bbae772b613d34a7'

hash160('52210354d112cce2b32134dad744e8a6c82a346291b6d2f4fdaef742264ace4c603e0d2103745a7c2f39946a14ab8a6d61aea55c1b64bc9c9d5b83d47b794782cc90609fad52ae'.decode('hex'))
# 'af2c57a99f55747423e4af65bbae772b613d34a7'

1
2
3
4
5
6
7
8
# python3
hash160(bytes.fromhex('52210354d112cce2b32134dad744e8a6c82a346291b6d2f4fdaef742264ace4c603e0d2103745a7c2f39946a14ab8a6d61aea55c1b64bc9c9d5b83d47b794782cc90609fad52ae'))
'af2c57a99f55747423e4af65bbae772b613d34a7'

# or
import codecs
hash160(codecs.decode('52210354d112cce2b32134dad744e8a6c82a346291b6d2f4fdaef742264ace4c603e0d2103745a7c2f39946a14ab8a6d61aea55c1b64bc9c9d5b83d47b794782cc90609fad52ae','hex'))
# 'af2c57a99f55747423e4af65bbae772b613d34a7'

e.g.

1
OP_HASH160 af2c57a99f55747423e4af65bbae772b613d34a7 OP_EQUAL

raw:

1
17a914af2c57a99f55747423e4af65bbae772b613d34a787

scriptSig:

1
OP_FALSE <簽名0> <簽名1> … <簽名n> <(multisig) redeem script>

e.g.

1
2
3
4
5
OP_FALSE 3045022100a7f1b5457dc955a5d4b4529473837828e3d9477e883bc3794d653f37578a58120220337a5c88b7a385e989f7c9aa7351d12f66f8ef68f3d26aa951034ac459b8cc3d01

304402204894f429c740f5cc16554575527c8cf01823abf60bd88bbb7e6938e15c28ffde022059f8f7be0440ab158b6568f7af1f97835d359fed20e160b2114089f1953851ce01

52210354d112cce2b32134dad744e8a6c82a346291b6d2f4fdaef742264ace4c603e0d2103745a7c2f39946a14ab8a6d61aea55c1b64bc9c9d5b83d47b794782cc90609fad52ae

raw:

1
00483045022100a7f1b5457dc955a5d4b4529473837828e3d9477e883bc3794d653f37578a58120220337a5c88b7a385e989f7c9aa7351d12f66f8ef68f3d26aa951034ac459b8cc3d0147304402204894f429c740f5cc16554575527c8cf01823abf60bd88bbb7e6938e15c28ffde022059f8f7be0440ab158b6568f7af1f97835d359fed20e160b2114089f1953851ce014752210354d112cce2b32134dad744e8a6c82a346291b6d2f4fdaef742264ace4c603e0d2103745a7c2f39946a14ab8a6d61aea55c1b64bc9c9d5b83d47b794782cc90609fad52ae

題:https://blockchain.info/tx-index/263681776/6
解:https://blockchain.info/tx-index/267355976

四、MultiSig

最早的多重簽名,目前已不推薦使用
地址形式:1xxxxxxxxxxx, 1xxxxxxxxxxx, 1xxxxxxxxxxx

scriptPubKey

1
M pubkey_1 pubkey_2 ... pubkey_n N OP_CHECKMULTISIG

e.g.

1
2
3
OP_2 037f0d8ccb11190cc5c13c703b2a1baffdd35eb4eb46541381e8baf4dad2603ea4
027a36e409b7b9ccb4bc7b952de453e0295c36243636adc55e92189ef076a3f357
03ace2c0bbc88c038e24b6d684c7832886dfd903d50bd2db75136ed7189ea472f6 OP_3 OP_CHECKMULTISIG

raw:

1
695221037f0d8ccb11190cc5c13c703b2a1baffdd35eb4eb46541381e8baf4dad2603ea421027a36e409b7b9ccb4bc7b952de453e0295c36243636adc55e92189ef076a3f3572103ace2c0bbc88c038e24b6d684c7832886dfd903d50bd2db75136ed7189ea472f653ae

scriptSig

1
OP_FALSE <簽名1> <簽名2> ... <簽名N>

e.g.

1
2
OP_FALSE 304502210085f76672bdc77135651eb31bba3933105c66357aa5ac5a7bf2c282ddc8270794022059925d692557b19a2fd3bec41318ade228bd5fca70ee7254722af8f83b740f0282
304402202f89f2c8454ec40509a73133a9fd5dac4e1e6705ff45f2a4632b8af5b2ba511e022072228f654e79aec334cb6546f56044d3f2daa571c84c1514171ea4e9ec8ae95182

raw:

1
0048304502210085f76672bdc77135651eb31bba3933105c66357aa5ac5a7bf2c282ddc8270794022059925d692557b19a2fd3bec41318ade228bd5fca70ee7254722af8f83b740f028247304402202f89f2c8454ec40509a73133a9fd5dac4e1e6705ff45f2a4632b8af5b2ba511e022072228f654e79aec334cb6546f56044d3f2daa571c84c1514171ea4e9ec8ae95182

題:https://blockchain.info/tx/2d96ee775ddc009bbb0eb7cab9775c07f6dc736121c1ce15a2f86ec435c38f3a
解:
https://blockchain.info/tx-index/97529992

五、Null-Data

Marks transaction as invalid

scriptPubKey

1
OP_RETURN xxxxxxx

e.g.

1
OP_RETURN 6a0d5e7cc043a18d6bc4a0c429f8a88c990f91b254fad766ae54dce0355979c1

1
226a206a0d5e7cc043a18d6bc4a0c429f8a88c990f91b254fad766ae54dce0355979c1

題:
https://blockchain.info/tx/b2072979c8e0f284fe86d8beafe7d9368725e230ea45844116b438272c482a9a

解:
無。因已標示交易無效,所以無法轉移BTC

六、Non-Standard

無法解析的非標準腳本

e.g.
題:https://blockchain.info/tx-index/55968320/0
解:https://blockchain.info/tx-index/55969885
題:https://blockchain.info/tx-index/55969885
解:https://blockchain.info/tx-index/56004092
題:https://blockchain.info/tx-index/12864193/0
解:https://blockchain.info/tx-index/12874719


驗證區塊

https://blockchain.info/block-index/962749/00000000000000000be983a81043933c38008010b849fd6a35d5dd2d57f929bd?format=json

block_hash = sha256(sha256(block_version+prev_block+merkle_root+ntime+nbits+nonce))

For block 00000000000000000be983a81043933c38008010b849fd6a35d5dd2d57f929bd:
version = 3, encoded as ‘03000000’ (4-byte little-endian);
previous_hash = ‘b6ae559e0678bbb2c926c78838c027ce925b0834e35d1f050000000000000000’;
merkle_root = ‘dba85df5822bbf6b3fb409d410d54848510b5b0d49563ab2ee87abecd318dbf4’;
ntime = 1442663985, encoded as ‘314efd55’ (4-byte little-endian);
nbits = ‘181287ba’, stored as ‘ba871218’;
nonce = 3548193207, encoded as ‘b7217dd3’ (4-byte little-endian).

以 python 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import hashlib

ver='03000000'

prev_block='0000000000000000051f5de334085b92ce27c03888c726c9b2bb78069e55aeb6'.decode('hex')[::-1].encode('hex')
print prev_block
'b6ae559e0678bbb2c926c78838c027ce925b0834e35d1f050000000000000000'

mrkl_root='f4db18d3ecab87eeb23a56490d5b0b514848d510d409b43f6bbf2b82f55da8db'.decode('hex')[::-1].encode('hex')
print mrkl_root
'dba85df5822bbf6b3fb409d410d54848510b5b0d49563ab2ee87abecd318dbf4'

ntime = hex(1442663985)[2:].decode('hex')[::-1].encode('hex')
print ntime
314efd55

nbits = hex(403867578)[2:].decode('hex')[::-1].encode('hex')
print nbits
'ba871218'

nonce = hex(3548193207)[2:].decode('hex')[::-1].encode('hex')
print nonce
'b7217dd3'
header_hex = ver+prev_block+mrkl_root+ntime+nbits+nonce
'03000000b6ae559e0678bbb2c926c78838c027ce925b0834e35d1f050000000000000000dba85df5822bbf6b3fb409d410d54848510b5b0d49563ab2ee87abecd318dbf4314efd55ba871218b7217dd3'

header_hex = '03000000b6ae559e0678bbb2c926c78838c027ce925b0834e35d1f050000000000000000dba85df5822bbf6b3fb409d410d54848510b5b0d49563ab2ee87abecd318dbf4314efd55ba871218b7217dd3'
header_bin = header_hex.decode('hex')
hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
print hash[::-1].encode('hex')
'00000000000000000be983a81043933c38008010b849fd6a35d5dd2d57f929bd'

難度 (Bits, Target, Difficulty)

How often does the network difficulty change?
Every 2016 blocks.

What is the formula for difficulty?
difficulty = difficulty_1_target / current_target

(target is a 256 bit number)

for nbits = 0x1b0404cb

1
0x0404cb * 2**(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000

The highest possible target (difficulty 1) is defined as 0x1d00ffff

1
0x00ffff * 2**(8*(0x1d - 3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000

It should be noted that pooled mining often uses non-truncated targets, which puts “pool difficulty 1” at

1
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

So the difficulty at 0x1b0404cb is therefore:

1
2
3
0x00000000FFFF0000000000000000000000000000000000000000000000000000 /
0x00000000000404CB000000000000000000000000000000000000000000000000
= 16307.420938523983 (Bitcoin clients, bdiff)

And:

1
2
3
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /
0x00000000000404CB000000000000000000000000000000000000000000000000
= 16307.669773817162 (pool difficulty, pdiff)


隔離驗證

To create a P2SH-P2WPKH address:

  1. Calculate the RIPEMD160 of the SHA256 of a public key (keyhash). Despite the keyhash formula is same as P2PKH, reuse of keyhash should be avoided for better privacy and prevention of accidental use of uncompressed key
  2. The P2SH redeemScript is always 22 bytes. It starts with a OP_0, followed by a canonical push of the keyhash (i.e. 0x0014{20-byte keyhash})
  3. Same as any other P2SH, the scriptPubKey is OP_HASH160 hash160(redeemScript) OP_EQUAL, and the address is the corresponding P2SH address with prefix 3.

Transaction Serialization

  • A segwit-compatible wallet MUST support the original transaction format, as nVersion|txins|txouts|nLockTime.
  • A segwit-compatible wallet MUST also support the new serialization format, as nVersion|marker|flag|txins|txouts|witness|nLockTime

P2WSH nested in BIP16 P2SH

題:
https://blockchain.info/tx-index/302164887/6
解:https://blockchain.info/tx/be27a1e94cdf529792a72cc36f716f813a86ad82501f4c30da0728cf00038b8f

1
2
hash160('002092c2380972ae5a244e814d18571502c64f5eef5ba99f1084cc5cd9191b754351'.decode('hex'))
'192aef744b6a8e1148481e08e4e4d53b41253a8b'
1
2
hashlib.sha256(binascii.unhexlify('5221020a4e014780b7d283e90cb76c5871a421e92fb1be026d4ded8d3a0a8153f60aef2103c87482d074068571e91b764cecfa076cff1535eadf1aca9209287700b234ba6252ae')).digest().encode('hex')
'92c2380972ae5a244e814d18571502c64f5eef5ba99f1084cc5cd9191b754351'

P2WPKH nested in BIP16 P2SH

題:
https://blockchain.info/tx-index/308673052/1
解:
https://blockchain.info/tx-index/308678074

1
2
hash160('0014be1e6466eb39799e885842ed85217594cd3bee18'.decode('hex'))
'd9e0414c842ebbc50748bb0becdd5f20e0a06f38'

1
2
hash160('02af03e4cd20a4dca33d4e3a9480c0469b91405404690075684b5986878d106aca'.decode('hex'))
'be1e6466eb39799e885842ed85217594cd3bee18'
1
2
scriptaddr('0014be1e6466eb39799e885842ed85217594cd3bee18')
'3MZ3Cgn8Fkvg64j5Yy4feYWy3LSoiHaGvB'
1
2
b58check_to_hex('3MZ3Cgn8Fkvg64j5Yy4feYWy3LSoiHaGvB')
'd9e0414c842ebbc50748bb0becdd5f20e0a06f38'

P2WSH

題:
https://blockchain.info/tx-index/308702492/1
解:
https://blockchain.info/tx-index/308706903

1
addr: bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej

地址請參考BIP173

1
2
hashlib.sha256(binascii.unhexlify('52210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae')).digest().encode('hex')
'701a8d401c84fb13e6baf169d59684e17abd9fa216c8cc5b9fc63d622ff8c58d'

最後更新: 2018年02月06日 11:22

原始連結: https://apjiyi.github.io/2018/02/05/Bitcoin-script/