The Chinese (Simplified) wiki is no longer maintained and is in read-only mode. Information contained within may be inaccurate or outdated. Please go to the English wiki for more up to date information.
从英文自动翻译:中文(简体)维基不再维护,处于只读模式。其中包含的信息可能不准确或过时。请前往英文维基获取更多最新信息。
协议说明
来源:
本文档中用到的类名称来自C99标准
Common standards
Hashs (散列)
通常情况下,bitcoin在计算散列时会计算2次。大多数情况下,使用SHA-256散列,RIPEMD-160会用于生成较短的散列(例如生成比特币地址的时候)。
对字符串"hello"进行二次-SHA-256散列计算的例子:
hello 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 (第一轮 sha-256) 9595c9df90075148eb06860365df33584b75bff782a510c6cd4883a419833d50 (第二轮 sha-256)
生成比特币地址时(RIPEMD-160)会得到:
hello 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 (第一轮 使用 sha-256) b6a9c8c230722b7c748331a8b450f05566dc7d0f (第二轮 使用 ripemd-160)
Merkle Trees (Merkle树)
Merkle树是散列的二叉树。在bitcoin中,Merkle树使用SHA-256算法,是这样生成的:
sha256(a) sha256(b) sha256(c) sha256(sha256(a)+sha256(b)) sha256(sha256(c)+sha256(c)) sha256(sha256(sha256(a)+sha256(b))+sha256(sha256(c)+sha256(c)))
每轮都将上一轮的结果两两相接后计算,若最后剩余单个元素则复制后计算。
Signatures (签名)
Bitcoin使用椭圆曲线数字签名算法(ECDSA)对交易进行签名
ECDSA 使用了 http://www.secg.org/collateral/sec2_final.pdf 中的secp256k1曲线
公钥(in scripts) 以 04 <x> <y>的形式给出,x和y是表示曲线上点的坐标的32字节字符串。签名使用DER 编码 将 r 和 s 写入一个字节流中(因为这是OpenSSL的默认输出).
Transaction Verification
参看: OP_CHECKSIG
The first transaction of a block is usually the generating transaction, which do not include any "in" transaction, and generate bitcoins (from fees for example) usually received by whoever solved the block containing this transaction. Such transactions are called a "coinbase transaction" and are accepted by bitcoin clients without any need to execute scripts, provided there is only one per block.
If a transaction is not a coinbase, it references previous transaction hashes as input, and the index of the other transaction's output used as input for this transaction. The script from the in part of this transaction is executed. Then the script from the out part of the referenced transaction is executed. It is considered valid if the top element of the stack is true.
地址
比特币地址(Bitcoin Address)是ECDSA公钥(public key)的散列,它是这样计算出来的:
Version = 1 个字节 0 ; 在测试网络上, 这个值是 1 个字节 111 Key hash = Version 与 RIPEMD-160(SHA-256(public key)) 相接 Checksum = SHA-256(SHA-256(Key hash))的前4个字节 Bitcoin Address = Base58Encode(Key hash 与 Checksum 相接)
Base58编码是专门编写的,(与通用版本)有一些区别。
Common structures
Almost all integers are encoded in little endian. Only IP or port number are encoded big endian.
Message structure (消息结构)
字段尺寸 | 描述 | 数据类型 | 说明 |
---|---|---|---|
4 | magic | uint32_t | 用于识别消息的来源网络,当流状态位置时,它还用于寻找下一条消息 |
12 | command | char[12] | 识别包内容的ASCII字串,用NULL字符补满,(使用非NULL字符填充会被拒绝) |
4 | length | uint32_t | paylod的字节数 |
4 | checksum | uint32_t | sha256(sha256(payload)) 的前4个字节(不包含在version 或 verack 中) |
? | payload | uchar[] | 实际数据 |
version和verack消息不包含checksum,payload的起始位置提前4个字节
已知的magic值:
网络 | Magic 值 |
---|---|
main | F9BEB4D9 |
testnet | FABFB5DA |
Variable length integer (变长整数)
整数可以根据表达的值进行编码以节省空间。变长整数总是在可变长度数据类型的数组/向量之前出现。
值 | 存储长度 | 格式 |
---|---|---|
< 0xfd | 1 | uint8_t |
<= 0xffff | 3 | 0xfd + uint16_t |
<= 0xffffffff | 5 | 0xfe + uint32_t |
- | 9 | 0xff + uint64_t |
Variable length string (变长字符串)
一个变长整数后接字符串构成变长字符串。
字段尺寸 | 描述 | 数据类型 | 说明 |
---|---|---|---|
? | length | var_int | 字符串长度 |
? | string | char[] | 字符串本身(可为空) |
Network address (网络地址)
需要网络地址时会用到这个结构。这个协议支持IPv6,但需要注意目前官方客户端仅支持IPv6网络
字段尺寸 | 描述 | 数据类型 | 说明 |
---|---|---|---|
8 | services | uint64_t | 与version中所列的service(s)相同 |
16 | IPv6/4 | char[16] | Ipv6地址,以网络字节顺序存储。官方客户端仅支持IPv4,仅读取最后4个字节以获取IPv4地址。IPv4地址以16字节的IPv4映射位址格式写入结构。(12字节 00 00 00 00 00 00 00 00 00 00 FF FF, 后跟4 字节IPv4地址) |
2 | port | uint16_t | 端口号,以网络字节顺序存储。 |
一个网络地址结构的十六进制转储示例
0000 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0010 00 00 FF FF 0A 00 00 01 20 8D ........ . Network address: 01 00 00 00 00 00 00 00 - 1 (NODE_NETWORK? see services listed under version command) 00 00 00 00 00 00 00 00 00 00 FF FF 0A 00 00 01 - IPv6: ::ffff:10.0.0.1 or IPv4: 10.0.0.1 20 8D - 端口 8333
Inventory Vectors (清单向量)
Inventory vectors 用于告知其他节点本节点拥有的对象或请求的数据
Inventory vectors 由以下数据格式构成
Field Size | Description | Data type | Comments |
---|---|---|---|
4 | type | uint32_t | 对象类型标识 |
32 | hash | char[32] | 对象散列值 |
目前对象类型标识已经定义如下3个值
值 | 名称 | 说明 |
---|---|---|
0 | ERROR | 数据可忽略 |
1 | MSG_TX | 散列是关于交易的 |
2 | MSG_BLOCK | 散列是关于数据块的 |
其他数据类型值被保留以便用于将来的实现
Block Headers (Block头部)
回应getheaders消息时,将Block头部放入一个headers packet并发送。
Field Size | Description | Data type | Comments |
---|---|---|---|
4 | version | uint32_t | Block版本信息,基于创建该block的软件版本 |
32 | prev_block | char[32] | 该block前一block的散列 |
32 | merkle_root | char[32] | 与该block相关的全部交易之散列(Merkle树) |
4 | timestamp | uint32_t | 记录block创建时间的时间戳 |
4 | bits | uint32_t | 创建block的计算难度 |
4 | nonce | uint32_t | |
1 | txn_count | uint8_t | 交易数,这个值总是0 |
Message types
version (版本)
一个节点收到连接请求时,它立即宣告其版本。在通信双方都得到对方版本之前,不会有其他通信
结构:
Field Size | Description | Data type | Comments |
---|---|---|---|
4 | version | uint32_t | 节点使用的协议版本标识 |
8 | services | uint64_t | 该连接允许的特性(bitfield) |
8 | timestamp | uint64_t | 以秒计算的标准UNIX时间戳 |
26 | addr_me | net_addr | 生成此消息的节点的网络地址 |
version >= 106 | |||
26 | addr_you | net_addr | 接收此消息的节点的网络地址 |
8 | nonce | uint64_t | 节点的随机id,用于侦测这个连接 |
? | sub_version_num | var_str | 辅助版本信息 |
version >= 209 | |||
4 | start_height | uint32_t | 发送节点接收到的最新block |
如果包发送者的版本>=209,而包版本被接受,则需要发送一个"verack"包。
services目前定义如下:
Value | Name | Description |
---|---|---|
1 | NODE_NETWORK | 这个节点不仅接受headers请求,还可以接受完整block请求 |
一个version消息的十六进制转储示例(请注意version消息头没有校验和)
0000 F9 BE B4 D9 76 65 72 73 69 6F 6E 00 00 00 00 00 ....version..... 0010 55 00 00 00 9C 7C 00 00 01 00 00 00 00 00 00 00 U....|.......... 0020 E6 15 10 4D 00 00 00 00 01 00 00 00 00 00 00 00 ...M............ 0030 00 00 00 00 00 00 00 00 00 00 FF FF 0A 00 00 01 ................ 0040 DA F6 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0050 00 00 00 00 FF FF 0A 00 00 02 20 8D DD 9D 20 2C .......... ... , 0060 3A B4 57 13 00 55 81 01 00 :.W..U... Message header: F9 BE B4 D9 - 主网络 magic 字节 76 65 72 73 69 6F 6E 00 00 00 00 00 - "version" 命令 55 00 00 00 - Payload 长度为 85 字节 - version 消息中没有校验和 Version message: 9C 7C 00 00 - 31900 (版本 0.3.19) 01 00 00 00 00 00 00 00 - 1 (NODE_NETWORK services) E6 15 10 4D 00 00 00 00 - Mon Dec 20 21:50:14 EST 2010 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 0A 00 00 01 DA F6 - 发送者地址信息 - 见 Network Address 一节 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 0A 00 00 02 20 8D - 接收者地址信息 - 见 Network Address 一节 DD 9D 20 2C 3A B4 57 13 - 节点的随机唯一 ID 00 - "" 子版本字串 (字串长度为0) 55 81 01 00 - 发送节点拥有的最新block是 #98645
verack
The verack message is sent in reply to version for clients >= 209. This message consists of only a message header with the command string "verack".
Hexdump of the verack message:
0000 F9 BE B4 D9 76 65 72 61 63 6B 00 00 00 00 00 00 ....verack...... 0010 00 00 00 00 .... Message header: F9 BE B4 D9 - Main network magic bytes 76 65 72 61 63 6B 00 00 00 00 00 00 - "verack" command 00 00 00 00 - Payload is 0 bytes long
addr
Provide information on known nodes of the network. Non-advertised nodes should be forgotten after typically 3 hours
Payload (maximum payload length: 1000 bytes):
Field Size | Description | Data type | Comments |
---|---|---|---|
1+ | count | var_int | Number of address entries |
30x? | addr_list | (uint32_t + net_addr)[] | Address of other nodes on the network. version < 209 will only read the first one |
Note: Starting version 31402, addresses are prefixed with a timestamp. If no timestamp is present, the addresses should not be relayed to other peers, unless it is indeed confirmed they are up.
Hexdump example of addr message:
0000 F9 BE B4 D9 61 64 64 72 00 00 00 00 00 00 00 00 ....addr........ 0010 1F 00 00 00 7F 85 39 C2 01 E2 15 10 4D 01 00 00 ......9.....M... 0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF ................ 0030 FF 0A 00 00 01 20 8D .D(.. . Message Header: F9 BE B4 D9 - Main network magic bytes 61 64 64 72 00 00 00 00 00 00 00 00 - "addr" 1F 00 00 00 - payload is 31 bytes long 7F 85 39 C2 - checksum of payload Payload: 01 - 1 address in this message Address: E2 15 10 4D - Mon Dec 20 21:50:10 EST 2010 (only when version is >= 31402) 01 00 00 00 00 00 00 00 - 1 (NODE_NETWORK service - see version message) 00 00 00 00 00 00 00 00 00 00 FF FF 0A 00 00 01 - IPv4: 10.0.0.1, IPv6: ::ffff:10.0.0.1 (IPv4-mapped IPv6 address) 20 8D - port 8333
inv
Allows a node to advertise its knowledge of one or more objects. It can be received unsolicited, or in reply to getblocks.
Payload (maximum payload length: 50000 bytes):
Field Size | Description | Data type | Comments |
---|---|---|---|
? | count | var_int | Number of inventory entries |
36x? | inventory | inv_vect[] | Inventory vectors |
getdata
getdata is used in response to inv, to retrieve the content of a specific object, and is usually sent after receiving an inv packet, after filtering known elements.
Payload (maximum payload length: 50000 bytes):
Field Size | Description | Data type | Comments |
---|---|---|---|
? | count | var_int | Number of inventory entries |
36x? | inventory | inv_vect[] | Inventory vectors |
getblocks
Return an inv packet containing the list of blocks starting at hash_start, up to hash_stop or 500 blocks, whichever comes first. To receive the next blocks hashes, one needs to issue getblocks again with the last known hash.
Payload:
Field Size | Description | Data type | Comments |
---|---|---|---|
1+ | start count | var_int | number of hash_start entries |
32+ | hash_start | char[32] | hash of the last known block of the emitting node |
32 | hash_stop | char[32] | hash of the last desired block. Set to zero to get as many blocks as possible (500) |
getheaders
Return a headers packet containing the headers for blocks starting at hash_start, up to hash_stop or 2000 blocks, whichever comes first. To receive the next blocks hashes, one needs to issue getheaders again with the last known hash. The getheaders command is used by thin clients to quickly download the blockchain where the contents of the transactions would be irrelevant (because they are not ours).
Payload:
Field Size | Description | Data type | Comments |
---|---|---|---|
1+ | start count | var_int | number of hash_start entries |
32+ | hash_start | char[32] | hash of the last known block of the emitting node |
32 | hash_stop | char[32] | hash of the last desired block. Set to zero to get as many blocks as possible (2000) |
tx
tx describes a bitcoin transaction, in reply to getdata
Field Size | Description | Data type | Comments |
---|---|---|---|
4 | version | uint32_t | Transaction data format version |
1+ | tx_in count | var_int | Number of Transaction inputs |
41+ | tx_in | tx_in[] | A list of 1 or more transaction inputs or sources for coins |
1+ | tx_out count | var_int | Number of Transaction outputs |
8+ | tx_out | tx_out[] | A list of 1 or more transaction outputs or destinations for coins |
4 | lock_time | uint32_t | The block number or timestamp at which this transaction is locked, or 0 if the transaction is always locked. A non-locked transaction must not be included in blocks, and it can be modified by broadcasting a new version before the time has expired (replacement is currently disabled in Bitcoin, however, so this is useless). |
TxIn consists of the following fields:
Field Size | Description | Data type | Comments |
---|---|---|---|
36 | previous_output | outpoint | The previous output transaction reference, as an OutPoint structure |
1+ | script length | var_int | The length of the signature script |
? | signature script | uchar[] | Computational Script for confirming transaction authorization |
4 | sequence | uint32_t | Transaction version as defined by the sender. Intended for "replacement" of transactions when information is updated before inclusion into a block. |
The OutPoint structure consists of the following fields:
Field Size | Description | Data type | Comments |
---|---|---|---|
32 | hash | char[32] | The hash of the referenced transaction. |
4 | index | uint32_t | The index of the specific output in the transaction. The first output is 0, etc. |
The Script structure consists of a series of pieces of information and operations related to the value of the transaction.
(Structure to be expanded in the future… see script.h and script.cpp for more information)
The TxOut structure consists of the following fields:
Field Size | Description | Data type | Comments |
---|---|---|---|
8 | value | uint64_t | Transaction Value |
1+ | pk_script length | var_int | Length of the pk_script |
? | pk_script | uchar[] | Usually contains the public key as a Bitcoin script setting up conditions to claim this output. |
Example tx message:
000000 F9 BE B4 D9 74 78 00 00 00 00 00 00 00 00 00 00 ....tx.......... 000010 02 01 00 00 E2 93 CD BE 01 00 00 00 01 6D BD DB .............m.. 000020 08 5B 1D 8A F7 51 84 F0 BC 01 FA D5 8D 12 66 E9 .[...Q........f. 000030 B6 3B 50 88 19 90 E4 B4 0D 6A EE 36 29 00 00 00 .;P......j.6)... 000040 00 8B 48 30 45 02 21 00 F3 58 1E 19 72 AE 8A C7 ..H0E.!..X..r... 000050 C7 36 7A 7A 25 3B C1 13 52 23 AD B9 A4 68 BB 3A .6zz%;..R#...h.: 000060 59 23 3F 45 BC 57 83 80 02 20 59 AF 01 CA 17 D0 Y#?E.W... Y..... 000070 0E 41 83 7A 1D 58 E9 7A A3 1B AE 58 4E DE C2 8D .A.z.X.z...XN... 000080 35 BD 96 92 36 90 91 3B AE 9A 01 41 04 9C 02 BF 5...6..;...A.... 000090 C9 7E F2 36 CE 6D 8F E5 D9 40 13 C7 21 E9 15 98 .~.6.m...@..!... 0000A0 2A CD 2B 12 B6 5D 9B 7D 59 E2 0A 84 20 05 F8 FC *.+..].}Y... ... 0000B0 4E 02 53 2E 87 3D 37 B9 6F 09 D6 D4 51 1A DA 8F N.S..=7.o...Q... 0000C0 14 04 2F 46 61 4A 4C 70 C0 F1 4B EF F5 FF FF FF ../FaJLp..K..... 0000D0 FF 02 40 4B 4C 00 00 00 00 00 19 76 A9 14 1A A0 ..@KL......v.... 0000E0 CD 1C BE A6 E7 45 8A 7A BA D5 12 A9 D9 EA 1A FB .....E.z........ 0000F0 22 5E 88 AC 80 FA E9 C7 00 00 00 00 19 76 A9 14 "^...........v.. 000100 0E AB 5B EA 43 6A 04 84 CF AB 12 48 5E FD A0 B7 ..[.Cj.....H^... 000110 8B 4E CC 52 88 AC 00 00 00 00 .N.R...... Message header: F9 BE B4 D9 - main network magic bytes 74 78 00 00 00 00 00 00 00 00 00 00 - "tx" command 02 01 00 00 - payload is 258 bytes long E2 93 CD BE - checksum of payload Transaction: 01 00 00 00 - version Inputs: 01 - number of transaction inputs Input 1: 6D BD DB 08 5B 1D 8A F7 51 84 F0 BC 01 FA D5 8D - previous output (outpoint) 12 66 E9 B6 3B 50 88 19 90 E4 B4 0D 6A EE 36 29 00 00 00 00 8B - script is 139 bytes long 48 30 45 02 21 00 F3 58 1E 19 72 AE 8A C7 C7 36 - signature script (scriptSig) 7A 7A 25 3B C1 13 52 23 AD B9 A4 68 BB 3A 59 23 3F 45 BC 57 83 80 02 20 59 AF 01 CA 17 D0 0E 41 83 7A 1D 58 E9 7A A3 1B AE 58 4E DE C2 8D 35 BD 96 92 36 90 91 3B AE 9A 01 41 04 9C 02 BF C9 7E F2 36 CE 6D 8F E5 D9 40 13 C7 21 E9 15 98 2A CD 2B 12 B6 5D 9B 7D 59 E2 0A 84 20 05 F8 FC 4E 02 53 2E 87 3D 37 B9 6F 09 D6 D4 51 1A DA 8F 14 04 2F 46 61 4A 4C 70 C0 F1 4B EF F5 FF FF FF FF - sequence Outputs: 02 - 2 Output Transactions Output 1: 40 4B 4C 00 00 00 00 00 - 0.05 BTC (5000000) 19 - pk_script is 25 bytes long 76 A9 14 1A A0 CD 1C BE A6 E7 45 8A 7A BA D5 12 - pk_script A9 D9 EA 1A FB 22 5E 88 AC Output 2: 80 FA E9 C7 00 00 00 00 - 33.54 BTC (3354000000) 19 - pk_script is 25 bytes long 76 A9 14 0E AB 5B EA 43 6A 04 84 CF AB 12 48 5E - pk_script FD A0 B7 8B 4E CC 52 88 AC Locktime: 00 00 00 00 - lock time
block
The block message is sent in response to a getdata message which requests transaction information from a block hash.
Field Size | Description | Data type | Comments |
---|---|---|---|
4 | version | uint32_t | Block version information, based upon the software version creating this block |
32 | prev_block | char[32] | The hash value of the previous block this particular block references |
32 | merkle_root | char[32] | The reference to a Merkle tree collection which is a hash of all transactions related to this block |
4 | timestamp | uint32_t | A timestamp recording when this block was created (Limited to 2106!) |
4 | bits | uint32_t | The calculated difficulty target being used for this block |
4 | nonce | uint32_t | The nonce used to generate this block… to allow variations of the header and compute different hashes |
? | txn_count | var_int | Number of transaction entries |
? | txns | tx[] | Block transactions, in format of "tx" command |
The SHA256 hash that identifies each block (and which must have a run of 0 bits) is calculated from the first 6 fields of this structure (version, prev_block, merkle_root, timestamp, bits, nonce, and standard SHA256 padding, making two 64-byte chunks in all) and not from the complete block. To calculate the hash, only two chunks need to be processed by the SHA256 algorithm. Since the nonce field is in the second chunk, the first chunk stays constant during mining and therefore only the second chunk needs to be processed. However, a Bitcoin hash is the hash of the hash, so two SHA256 rounds are needed for each mining iteration.
headers
The headers packet returns block headers in response to a getheaders packet.
Payload:
Field Size | Description | Data type | Comments |
---|---|---|---|
? | count | var_int | Number of block headers |
77x? | headers | block_header[] | Block headers |
getaddr
The getaddr message sends a request to a node asking for information about known active peers to help with identifying potential nodes in the network. The response to receiving this message is to transmit an addr message with one or more peers from a database of known active peers. The typical presumption is that a node is likely to be active if it has been sending a message within the last three hours.
No additional data is transmitted with this message.
checkorder
This message is used for IP Transactions, to ask the peer if it accepts such transactions and allow it to look at the content of the order.
It contains a CWalletTx object
Payload:
Field Size | Description | Data type | Comments |
---|---|---|---|
Fields from CMerkleTx | |||
? | hashBlock | ||
? | vMerkleBranch | ||
? | nIndex | ||
Fields from CWalletTx | |||
? | vtxPrev | ||
? | mapValue | ||
? | vOrderForm | ||
? | fTimeReceivedIsTxTime | ||
? | nTimeReceived | ||
? | fFromMe | ||
? | fSpent |
submitorder
Confirms an order has been submitted.
Payload:
Field Size | Description | Data type | Comments |
---|---|---|---|
32 | hash | char[32] | Hash of the transaction |
? | wallet_entry | CWalletTx | Same payload as checkorder |
reply
Generic reply for IP Transactions
Payload:
Field Size | Description | Data type | Comments |
---|---|---|---|
4 | reply | uint32_t | reply code |
Possible values:
Value | Name | Description |
---|---|---|
0 | SUCCESS | The IP Transaction can proceed (checkorder), or has been accepted (submitorder) |
1 | WALLET_ERROR | AcceptWalletTransaction() failed |
2 | DENIED | IP Transactions are not accepted by this node |
ping
The ping message is sent primarily to confirm that the TCP/IP connection is still valid. An error in transmission is presumed to be a closed connection and the address is removed as a current peer. No reply is expected as a result of this message being sent nor any sort of action expected on the part of a client when it is used.
alert
An alert is sent between nodes to send a general notification message throughout the network. If the alert can be confirmed with the signature as having come from the the core development group of the Bitcoin software, the message is suggested to be displayed for end-users. Attempts to perform transactions, particularly automated transactions through the client, are suggested to be halted. The text in the Message string should be relayed to log files and any user interfaces.
Payload:
Field Size | Description | Data type | Comments |
---|---|---|---|
? | message | var_str | System message which is coded to convey some information to all nodes in the network |
? | signature | var_str | A signature which can be confirmed with a public key verifying that it is Satoshi (the originator of Bitcoins) who has "authorized" or created the message |
The signature is to be compared to this ECDSA public key:
04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284 (hash) 1AGRxqDa5WjUKBwHB9XYEjmkv1ucoUUy1s
Source: [1]
Scripting
See script.