比特币协议

当前位置:首页 > 币圈百科 > 比特币协议

比特币协议

2023-01-09币圈百科263

比特币协议

本文翻译自比特币维基:https://en.bitcoin.it/wiki/Protocol_specification,参考维基中的信息:http://wiki.8btc.com/doc-view-70.htm

译者:申屠,深圳大学国防科学技术ATR重点实验室博士,新浪微博@我看比特币

注:本文可随意转发,请留下译者的信息,如果您认为本文对您有用,请将其捐赠给译者,捐赠地址:1 fav xbp 2 KMT 98 p 3 tjjx 2 MQ?比特币在中国家喻户晓,但技术研究一直没有有效开展。大部分人都是在知道和了解的层面。目前很多比特圈的人都不太了解比特币能做什么。一个重要原因是比特币的核心资料大部分是英文的,很少有人能在冥想中读懂这么复杂的英文资料。我博士论文的研究方向是比特币。在研究其英文技术的同时,我打算翻译一些重要的资料,让更多的业内人士对比特币有更好的了解。

?本文研究比特币协议,包括哈希、MERKLE树生成、签名、交易验证、地址等通用标准。以及通用数据结构,包括消息、变长整数、变长字符串、网络地址、清单向量、块头等。还详细介绍了20多条比特币报文的数据结构和使用场景,对比特币协议是很好的参考。

Text

1通用标准

1.1 Hash(哈希)

通常情况下,比特币会计算两次哈希。在大多数情况下,使用SHA-256哈希,RIPEMD-160将用于生成较短的哈希(例如,在生成比特币地址时)。

字符串“hello”的秒-SHA-256哈希计算示例:

Hello 2 cf 24 db 5 FB 0 a 30 e 26 e 83 B2 AC 5 e 9 e 29 e 161 E5 C1 fa 7425 e 73043362938 b 995 c9df 90075148 EB 0680365 df 33584 b 75FF 782 a 510 c6cd 4883 a 419834如果叶子数是奇数,我们要计算最后一片叶子的SHA-256两次,以满足偶数叶子节点的要求:

计算过程:首先根据块中事务的两个HASH256值,然后根据HASH值排序,生成最低层;第二层的每个元素是两个连续的散列值;重复这个过程,直到某一层只有一个哈希值,就是Merkle根。举例:假设有a、b、c三笔交易,生成过程如下:

D1=达什(a) D2=达什(b) D3=达什(c) D4=达什(c)??#只有3个元素,是奇数,要重新计算最后一个元素吗?(译者出版社,按照上面的说明,这里应该有排序,可能省略,待确认)?d5=达什(d1串联d2)d6=达什(d3串联d4)?D7=dhash(d5 concat d6)

这里d hash(a)=sha 256(sha 256(a))

D7是上述三个事务的Merkle根。

注:块浏览器中显示的Merkle树的哈希值是一点点位序(译者按:即高位跟在后面,计算机中一个数的表示)。对于某些实现和计算,应该在哈希计算前逐位求逆,哈希计算后再求逆。

1.3签名

比特币使用椭圆曲线数字签名算法(ECDSA)对交易进行签名。

ECDSA在http://www.secg.org/collateral/sec2_final.pdf.使用secp256k1曲线

公钥(脚本中)以04的形式给出,其中x和y是32字节的大头序数整数,代表上述曲线的点坐标;或者压缩形式,如果y是偶数,就是002,如果y是奇数,就是003。

Signature使用DER编码将R和S写入字节流(因为这是OpenSSL的默认输出)。

1.4交易验证(交易认证)

交易是用于记录比特币所有权从一个地址转移到另一个地址的加密签名。 交易有输入(即以前的收费交易的输出资金)和输出(用于定义比特币的新主人,可以被未来的交易引用为输入)。

每个输入必须有一个加密数字签名,用于从以前的交易中解锁资金。只有拥有正确私钥的人才能创建合法签名,这确保了资金只能由所有者使用。

每个输出定义了哪个地址(或其他标准,请参见文章“比特币脚本”)是资金的接收方。

在一笔交易中,所有输入资金的总和必须等于或大于所有输出资金的总和。如果投入超过产出,超出的部分就是传输费。谁挖到包含这个交易的区块,谁就有这个费用。一个称为coinbase事务的特殊事务没有输入,由矿工创建。每个区块都有一个新创建的比特币回报(例如:在前210,000个区块中,每个区块包含50个比特币)。每个块的第一个事务是一个coinbase事务,很少有例外。比特币基地交易允许这些比特币归其收款人(矿工)所有,也用于表示本区块其他交易的交易费收款人。比特币基地交易可以指定接收方是一个比特币地址,或者像其他交易一样,可以由多个地址接收。比特币基地交易包括的产出量等于每个区块的开采收益加上该区块的所有交易成本。

0块的coinbase交易花不完,可能是客户端实现的巧合(译者出版社:或者故意为之,详见译者蔡《比特币区块链与挖掘原理》翻译)。如果有些节点接受消费交易,而有些节点不接受,就可能出现分叉。

大部分比特币输出需要ECDSA私钥来兑换传输的比特币。实际存储输入输出的记录不是私钥,而是脚本。比特币使用解释性脚本系统来定义输出标准是否符合。有了这个脚本系统,可以形成更复杂的操作。例如,需要两个ECDSA签名的输出,或者一个2/3多重签名方案。一个比特币地址的输出是一个典型的输出,它实际上以脚本的形式包含了需要单个ECDSA签名的信息(参见OP_CHECKSIG)。为了在将来解锁资金,必须提供一个输出脚本。当事务要在另一个事务的输入中使用时,输入必须满足原始输出脚本的要求。

1.5 Addresses

比特币地址是ECDSA公钥的哈希,计算方法如下:

Version=1字节(0);在测试网络中,该值为1字节(111)密钥哈希=连接到RIPEMD-160的版本(SHA-256(公钥))。校验和=SHA-256 (SHA-256 (keyhash))。比特币地址=Base58Encode(连接校验和的密钥哈希)

base50。特别是,所有带前导零的字节都被转换成一个零。

2一般结构

大部分整数用小头编码,只有IP地址或端口号用大头编码。

2.1 Message

字段大小

描述

数据类型

`描述

4

magic

uint3它还用于查找下一条消息

12

Command

char[12]

ASCII字符串标识包的内容,用空字符填充, (用非空字符填充NULL be被拒绝)

4

length

uint 32 _ t

字节有效负载

4

uint 32

有效负载

uchar []

实际数据

版本和verack消息不包含校验和, 有效载荷的起始位置比定义的幻值提前4个字节

network

幻值

sending form

main

0x d 9 B4 bef 9

F9 beb4 d 9[fab5 da

testnet 3

0x 0709110 b

0b 11 09 07

name coin

0x Fe 4 bef 9

F9 be 4 bfe[x 较长的数字以小标题顺序编码。

存储长度

格式

0x FD

1

uint 8 _ t

=0x ffff

3[

9

0x ff uint 64 _ t

指的是中本聪的比特币客户端代码(Bitcoin-qt)中的“CompactSize”。现代的比特币-qt也有CVarint类,它比CompactSize更压缩(但不兼容),CVarint类不是协议的一部分。

2.3变长字符串

变长字符串由一个变长整数和一个字符串组成。

字段大小

描述

数据类型

描述

length

var _ int

string 蓑衣网小编2022 length

string

char[]

string本身(可以为空)

2.4网络地址

需要网络地址时使用该结构。该协议和数据结构支持IPv6,但需要注意的是,目前官方客户端只支持IPv4网络,网络地址在版本消息中,而不是以时间戳开头。

字段大小

描述

数据类型

描述

4

time

uint 32

time(版本=3144与版本消息具有相同数据类型

16

IPV6/4蓑衣网小编2022

char[16]

网络字节顺序。原客户端只支持IPv4,只读取扣除最多的4个字节获取IPv4地址。但是IPv4地址是16字节的IPv4映射IPv6地址

(12字节

0000 00 00 00 00 FF,后面是4字节的IPv4地址)。

2

port

uint16 _ t?01 00 00 00 00 00 00 00?00 00 00 00 00 00 00 00?.0010?00 00 FF FF 0A 00 00?20 8D???.网络地址:01 00 00 00 00 00 00 00 00 00???-1 (NODE_NETWORK:请看version命令的服务列表)00 00 00 00 00 00 FF 00 00 01-IPv6:* ffff:10 . 0 . 0 . 1还是IPv4: 10.0.0.1 20 8D??????-Port 8333

2.5 Inventory Vectors

Inventory Vectors用于通知其他节点本节点拥有的对象或请求的数据,以下数据格式构成

字段大小

描述

数据类型

描述

4

类型

uint32 _ t

对象。目前有以下三个值

value

name

description

0

error

data可以忽略

1

msg _ Other data type值留作将来实现

2.6 block headers

响应getheaders消息时,将块头放入一个数据包中发送,

字段大小

描述

数据类型

描述

4

版本

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

用于生成block的临时数据

1

txn_count

var_int

交易数,这个值总是0

3消息类型

3.1 version

当一个节点收到连接请求时,它立即宣告其版本。远程节点会以自己的版本响应,在通信双方都得到对方版本之前,不会有其他通信。

结构:

字段尺寸

描述

数据类型

说明

4

version

int32_t

节点使用的协议版本标识

8

services

uint64_t

该连接允许的特性(bitfield)

8

timestamp

int64_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

int32_t

发送节点接收到的最新block

1

relay

bool

远程节点是否应该宣告转发的交易,

看BIP 0037,从版本 >= 70001

如果版本数据包被接受,回送一个“verack”包。

services目前定义如下:

名称

说明

1

NODE_NETWORK

节点不仅接受headers请求,还可以接受完整block请求

一个version消息示例(这个例子中缺少检验和和user-agent)

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??????????????????????????????????????????? -魔术数: main 网络?76 65 72 73 69 6F 6E 00 00 00 00 00??????????????????? -命令: "version" ?55 00 00 00??????????????????????????????????????????? -负载长度为 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

有一个(60002)协议版本客户端向本地节点声明它自己的版本。

新的协议版本已经包括了检验和,这点来自比特币客户端,当连接到另一个本地客户端时,注意到当源和目的地址不可路由时,它根本不填入地址信息。

?

0000?? f9 be b4 d9 76 65 72 73 69 6f 6e 00 00 00 00 00? ....version.....0010?? 64 00 00 00 35 8d 49 32 62 ea 00 00 01 00 00 00? d...5.I2b.......0020?? 00 00 00 00 11 b2 d0 50 00 00 00 00 01 00 00 00? .......P........0030?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff? ................0040?? 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00? ................0050?? 00 00 00 00 00 00 00 00 ff ff 00 00 00 00 00 00? ................0060?? 3b 2e b3 5d 8c e6 17 65 0f 2f 53 61 74 6f 73 68 ?;..]...e./Satosh0070?? 69 3a 30 2e 37 2e 32 2f c0 3e 03 00????????????? i:0.7.2/.>..?Message Header: F9 BE B4 D9????????????????????????????????????????? - 主网络魔术数 76 65 72 73 69 6F 6E 00 00 00 00 00????????????????? - "version" 命令 64 00 00 00????????????????????????????????????????? - 数据负载100字节 3B 64 8D 5A????????????????????????????????????????? -数据负载校验和?Version message: 62 EA 00 00????????????????????????????????????? - 60002 (协议版本 60002) 01 00 00 00 00 00 00 00????????????????????????? - 1 (NODE_NETWORK services) 11 B2 D0 50 00 00 00 00????????????????????????? - Tue Dec 18 10:12:33 PST 2012 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 00 00 00 00 00 00 – 接收地址信息 –参看网络地址 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 00 00 00 00 00 00 – 发送地址信息 -参看网络地址 3B 2E B3 5D 8C E6 17 65???????????????????????????? - 节点 ID 0F 2F 53 61 74 6F 73 68 69 3A 30 2E 37 2E 32 2F???? - "/Satoshi:0.7.2/" 字版本字符串(15字节长) C0 3E 03 00???????????????????????????  ?? - 发送节点的最后区块号 #212672

3.2 verack

应答version消息时发送verack消息。这个消息仅包含一个command为“verack”的消息头

verack消息示例:

0000?? F9 BE B4 D9 76 65 72 61? 63 6B 00 00 00 00 00 00?? ....verack......0010?? 00 00 00 00 5D F6 E0 E2??????????????????????????? ........?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 long5D F6 E0 E2????????????????????????? - Checksum

3.3 addr

提供网络上已知节点的信息。一般来说3小时不进行宣告的节点会被网络遗忘。

数据负载:

字段尺寸

描述

数据类型

说明

1+

count

var_int

地址数,最多1000

30x?

addr_list

(uint32_t+ net_addr)[]

网络上其他节点的地址,版本低于209时仅读取第一条,uint32_t是时间戳

注意:从31402版本开始,地址前都会附加一个时间戳。如果没有这个时间戳,除非它被确认有效,否则这个地址不会发送到其他节点

addr消息示例

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?????????????????????????????? ..... .?Message Header: F9 BE B4 D9?????????????????????? ??????????????- magic :main 网络 61 64 64 72? 00 00 00 00 00 00 00 00??????????? - "addr" 1F 00 00 00???????????????????????????????????? - payload 长度31字节 7F 85 39 C2???????????????????????????????????? - payload 校验和?Payload: 01???????????????????????? ?????????????????????- count?: 1 消息中有1条地址?Address: E2 15 10 4D???????????????????????????????????? - Mon Dec 20 21:50:10 EST 2010 (版本 >= 31402时) 01 00 00 00 00 00 00 00???????????????????????? - 1 (NODE_NETWORK service - 见 [[#version]]) 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?????????????????????????????????????????? - 端口 8333

3.4 inv

节点通过此消息可以宣告它拥有的对象信息。这个消息可以主动发送,也可以用于应答getblocks消息

数据负载 (最大长度 1.8M, 或者50000 个数据项):

字段尺寸

描述

数据类型

说明

??

count

var_int

清单(inventory)数量

36x?

inventory

inv_vect[]

清单(inventory)数据

3.5 getdata

getdata用于应答inv消息来获取指定对象,它通常在接收到inv包,并且过滤掉已知元素后发送。可用于获得交易,但当且仅当他们在内存池或转发集合中-为了避免某些节点开始依赖具有全部交易索引的节点(现代节点不会),所以任意访问块链中的交易是不允许的,

数据负载 (最大长度 1.8M, 或者50000 个数据项):

字段尺寸

描述

数据类型

说明

??

count

var_int

清单(inventory)数量

36x?

inventory

inv_vect[]

清单(inventory)数据

3.6 notfound

??? Notfound是对getdata消息的回应,如果要求的数据项不能被转发则发送该信息。例如:要求的交易未在内存池或转发集合中。

字段尺寸

描述

数据类型

说明

??

count

var_int

清单(inventory)数量

36x?

inventory

inv_vect[]

清单(inventory)数据

3.7 getblocks

返回一个包含区块列表的inv数据包,区块定位对象中最新的区块HASH之后的区块,到hast_stop或最多500个区块(看哪个数值先达到)。

节点以区块出现在消息中的顺序处理定位区块,如果一个区块HASH在节点的主块链中出现过,则它之前的区块将通过inv消息返回,剩余的定位区块被忽略,而不管要求的500块限制是否已经达到。

要获取下一个区块HASH,需要以一个新的区块定位对象重新发送getblocks消息,要记住,如果区块定位对象包含一个在无效支链上的HASH时,一些客户端(特别是中本聪客户端)将提供无效区块。

数据负载:

大小

描述

类型

说明

4

版本

uint32_t

协议版本

1+

HASH个数

var_int

区块定位HASH个数

32+

区块定位HASH

char[32]

区块定位HASH,最新的区块(开始时比较密集,后面比较稀疏)

32

hash_stop

char[32]

最后一个期望的区块,如果希望得到越多越好的区块数(超过500),则设为0

?????? 如果要创建区块定位HASH,持续把区块HASH推入堆栈,直到回到创世块,每推入10个HASH,每个循环的步长加倍。示例程序如下所示:

// From libbitcoin which is under AGPLstd::vector block_locator_indices(int top_depth){??? // Start at max_depth??? std::vector indices;??? // Push last 10 indices first??? size_t step = 1, start = 0;??? for (int i = top_depth; i > 0; i -= step, ++start)??? {??????? if (start >= 10)??????????? step *= 2;??????? indices.push_back(i);? ??}??? indices.push_back(0);??? return indices;}

注意:发送更少的已知HASH甚至只有一个,是允许的。然而,区块定位对象的目的是在调用者的主链上检测错误分支。如果该节点检测到你已经从主链上分离,将会发送比你的最新已经区块更早的区块HASH,因而你如果只发送了你的最新已经HASH,而它已经从主链上分叉,则该节点会从区块1开始发。

3.8 getheaders

返回一个包含区块头列表的inv数据包,区块定位对象中最新的区块HASH之后的区块头,到hast_stop或最多2000个区块头(看哪个数值先达到)。

要获取下一个区块头,需要以一个新的区块定位对象重新发送getheaders消息,瘦客户端不可能下载所有的区块内容,因而它们使用消息getheaders来快速下载区块头。

要记住,如果区块定位对象包含一个在无效支链上的区块头时,一些客户端(特别是中本聪客户端)将提供无效区块头。

数据负载:

大小

描述

类型

说明

4

版本

uint32_t

协议版本

1+

HASH个数

var_int

区块定位HASH个数

32+

区块定位HASH

char[32]

区块定位HASH,最新的区块头(开始时比较密集,后面比较稀疏)

32

hash_stop

char[32]

最后一个期望的区块头,如果希望得到越多越好的区块数(超过500),则设为0

?????? 该数据结构中的区块定位对象,与getblocks一样的生成规则。

3.9 tx

tx消息描述一笔比特币交易,用于应答getdata消息

字段尺寸

描述

数据类型

说明

4

version

uint32_t

交易数据格式版本

1+

tx_incount

var_int

交易的输入数

41+

tx_in

tx_in[]

交易输入或比特币来源列表

1+

tx_outcount

var_int

交易的输出数

8+

tx_out

tx_out[]

交易输出或比特币去向列表

4

lock_time

uint32_t

交易的锁定期限或区块数目。

如果为0则交易一直被锁定;小于5亿是指区块号;大于等于5亿是指UNIX时间戳。

如果所有的txin输入都已经终结(0xffffffff)的序列号,这时lock_time任意。否则该交易将到lock_time之后才会被包含到区块中,看NLockTime。

tx_in的构成:

字段尺寸

描述

数据类型

说明

36

previous_output

outpoint

对前一输出的引用

1+

scriptlength

var_int

signaturescript 的长度

??

signaturescript

uchar[]

用于确认交易授权的计算脚本

4

sequence

uint32_t

发送者定义的交易版本,用于在交易被写入block之前更改交易

OutPoint结构的构成:

字段尺寸

描述

数据类型

说明

32

hash

char[32]

引用的交易的哈希

4

index

uint32_t

指定输出的索引,第一笔输出的索引是0,以此类推

script由一系列与交易相关的信息和操作组成详情请参考”比特币脚本”或源代码script.h 和 script.cpp。

tx_out的构成:

字段尺寸

描述

数据类型

说明

8

value

uint64_t

交易的比特币数量(单位是0.00000001)

1+

pk_scriptlength

var_int

pk_script的长度

??

pk_script

uchar[]

通常包含公钥,作为赎回本输出的比特币脚本的创建条件。

tx消息示例:

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?????????????????????? ????????????????- magic: main 网络 74 78 00 00 00 00 00 00 00 00 00 00?????????????? - command:"tx" command 02 01 00 00?????????????????????????????????????? - payload 长度: 258字节 E2 93 CD BE?????????????????????????????????????? - payload 校验和?Transaction: 01 00 00 00?????????????????????????????????????? - version?Inputs: 01??????????????????????????????????????????????? - 交易的输入数:1?Input 1: 6D BD DB 08 5B 1D 8A F7? 51 84 F0 BC 01 FA D5 8D? - 前一输出(outpoint) 12 66 E9 B6 3B 50 88 19? 90 E4 B4 0D 6A EE 36 29 00 00 00 00? 8B??????????????????????????????????????????????? - script 长度:139字节? 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 233F 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 042F 46 61 4A 4C 70 C0 F1? 4B EF F5? FF FF FF FF?????????????????????????????????????? - sequence?Outputs: 02??????????????????????????????????????????????? - 交易的输出数:2?Output 1: 40 4B 4C 00 00 00 00 00?????????????????????????? - 0.05 BTC (5000000) 19??????????????????????????????????????????????? - pk_script 长度:25字节? 76 A9 14 1A A0 CD 1C BE? A6 E7 45 8A 7A BA D5 12? - pk_scriptA9 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 长度:25字节? 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

3.10 block

block消息用于响应getdata消息

字段尺寸

描述

数据类型

说明

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

用于生成这一block的nonce值

??

txn_count

var_int

交易数量

??

txns

tx[]

交易,以tx格式存储

用于识别每个区块的SHA256哈希使用这个结构的前6个字段计算(version, prev_block, merkle_root, timestamp, bits, nonce, 后接标准 SHA256 填充, 共2个64字节块)而非整个block。SHA256算法计算哈希只需要处理2个64字节块。由于nonce字段在第二个数据块里,在挖矿过程中,第一个数据块保持不变。因此只需要处理第二个数据块。但是比特币区块哈希是二次哈希,每个开采循环需要2轮SHA256计算(具体详细请看译者的“比特币块链和挖矿原理”)。

3.11 headers

headers消息返回区块头以应答getheaders

Payload:

字段尺寸

描述

数据类型

说明

??

count

var_int

block头数量

81x?

headers

block_header[]

block头

?????? 注意,该数据包中的区块头包含交易count(一个var_int,因而每个区块头可能超过81字节),与发给矿工的区块头不同。

3.12 getaddr

getaddr消息向一个节点发送获取已知活动节点的请求,以发现网络节点。回应这个消息的方法是发送addr消息,包含一个或多个节点信息。活动节点的一般假设是3小时内发送过消息。

这个消息没有附加数据。

3.13 mempool

?????? Mempool消息向节点发送请求,询问已经通过验证但没有确认的交易信息。收到此消息,可返回inv消息,包含在节点mempool中的所有交易HASH列表。

?????? Mempool定义在BIP 35,从BIP 37开始,只能符合过滤条件的交易会被应答。

3.14 checkorder

此消息用于IP Transactions,因为IP交易已经被取消,该消息不再使用。

3.15 submitorder

此消息用于IP Transactions,因为IP交易已经被取消,该消息不再使用。

3.16 reply

此消息用于IP Transactions,因为IP交易已经被取消,该消息不再使用。

3.17 ping

ping消息主要用于确认TCP/IP连接的可用性。传输错误被假定为已经关闭的连接,并且IP地址已经变为当前的节点。

数据负载:

字段尺寸

描述

数据类型

说明

8

nonce

uint64_t

随机数

3.18 pong

Pong消息用于回应ping消息,在当前的协议版本,pong用ping的nonce回应。

数据负载:

字段尺寸

描述

数据类型

说明

8

nonce

uint64_t

来自ping的随机数

3.19 reject

当消息被拒绝时就发送Reject消息。

数据负载:

字段尺寸

描述

数据类型

说明

1+

message

var_str

消息类型

1

ccode

char

拒绝消息的原因码

1+

reason

var_str

拒绝消息的文本原因

Ccode码

名称

描述

0x01

REJECT_MALFORMED

 

0x10

REJECT_INVALID

 

0x11

REJECT_OBSOLETE

 

0x12

REJECT_DUPLICATE

 

0x40

REJECT_NONSTANDARD

 

0x41

REJECT_DUST

 

0x42

REJECT_INSUFFICIENTFEE

 

0x43

REJECT_CHECKPOINT

 

3.20 filterload, filteradd, filterclear, merkleblock

这些命令与在连接的Bloom过滤相关,定义在BIP 37中。

3.21 alert

alert消息用于在节点间发送通知使其传遍整个网络。如果签名验证这个alert来自Bitcoin的核心开发组,建议将这条消息显示给终端用户。建议停止交易,尤其是客户端间的自动交易更应该停止。消息文字应当记入记录文件并传到每个用户。

数据负载:

字段尺寸

描述

数据类型

说明

??

payload

uchar[]

保存的alert数据

??

signature

uchar[]

可由公钥验证Satoshi授权或创建了此信息的签名

签名将用下面的ECDSA公钥做比对:

04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284(hash) 1AGRxqDa5WjUKBwHB9XYEjmkv1ucoUUy1s

Payload序列化为uchar[],以保证使用不兼容的alert格式的不同版本也能在网络中转发alert消息,当前的alert数据格式为:

字段尺寸

描述

数据类型

说明

4

Version

int32_t

Alert的格式版本

8

RelayUntil

int64_t

时间戳,在这个时间之后应该停止转发alert

8

Expiration

int64_t

时间戳,在这个时间之后应该不起作用,应该被忽略

4

ID

int32_t

alert的唯一ID号

4

Cancel

int32_t

ID号小于或等于该数字的alerts应该被取消,删除并且以后不再接收。

??

setCancel

set

在该集合中的所有alert的ID应该被取消,删除并且以后不再接收。

4

MinVer

int32_t

本alert仅应用于版本大于或等于这个小版本,其他小版本应该转发。

4

MaxVer

int32_t

本alert仅应用于版本大于或等于这个大版本,其他大版本应该转发。

??

setSubVer

set

如果该集合包含元素,则只有子版本在本集合中的节点受到影响,其他版本的节点应该转发。

4

Priority

int32_t

与其他alerts相比的相对优先级

??

Comment

string

不用显示的alert说明。

??

StatusBar

string

应该显示的alert说明。

??

Reserved

string

保留

注意:上面表格中的set是变长整数,后面跟着给定类型(int32_t或变长字符串)项目数量。

Alert例子(没有消息头)

73010000003766404f00000000b305434f00000000f2030000f1030000001027000048ee00000064000000004653656520626974636f696e2e6f72672f666562323020696620796f7520686176652074726f75626c6520636f6e6e656374696e67206166746572203230204665627275617279004730450221008389df45f0703f39ec8c1cc42c13810ffcae14995bb648340219e353b63b53eb022009ec65e1c1aaeec1fd334c6b684bde2b3f573060d5b70c3a46723326e4e8a4f1?Version: 1RelayUntil: 1329620535Expiration: 1329792435ID: 1010Cancel: 1009setCancel: MinVer: 10000MaxVer: 61000setSubVer: Priority: 100Comment: StatusBar: "See bitcoin.org/feb20 if you have trouble connecting after 20 February"Reserved:

?

比特币协议 | 分享给朋友: