Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

NEO网络协议

宠着祖宗
92 0 0
网络协议
5 U. q* M  [2 W* q- |在网络结构上,NEO 采用点对点网络结构,并使用 TCP 协议进行通讯。
3 }0 B" n5 M" r  F网络中存在两种节点类型,分别是普通节点和共识节点。普通节点可以广播、接收和转发交易、区块等,而共识节点可以创建区块。, n) @  E5 }: b& J% V. k$ i
NEO 的网络协议规范与比特币的协议大致类似,但在区块、交易等的数据结构上有很大的不同。
* Y6 `# C4 H. w/ C5 O约定" R9 L, [. j& k0 C5 ^. k8 m
字节序
* A3 m6 I# s' m3 O# l; ?; yNEO 系统中所有的整数类型都是采用小端序 (Little Endian) 编码,只有 IP 地址和端口号采用大端序 (Big Endian) 编码。7 \# X$ X/ r+ c5 D& N
散列
. y' t; L/ f% h6 g9 o; |$ _; Z1 qNEO 系统中会用到 2 种不同的散列函数:SHA256 和 RIPEMD160。前者用于生成较长的散列值,而后者用于生成较短的散列值。通常生成一个对象的散列值时,会运用两次散列函数,例如要生成区块或交易的散列时,会计算两次 SHA256;生成合约地址时,会先计算脚本的 SHA256 散列,然后再计算上一个散列的 RIPEMD160 散列。- M+ m$ F& u# ^% a! U
此外,区块中还会用到一种散列树 (Merkle Tree) 的结构,它将每一笔交易的散列两两相接后再计算一次散列,并重复以上过程直到只剩下一个根散列 (Merkle Root)。
+ [& ^. c5 R2 q8 l' @变长类型
* D5 R) I) ]  ovarint:变长整数,可以根据表达的值进行编码以节省空间。3 v% o) n( Y; C2 `
长度格式
0xffffffff90xff + uint64
, f  \! W! M- D+ R9 ~5 r4 v4 d5 L
varstr:变长字符串,由一个变长整数后接字符串构成。字符串采用 UTF8 编码。
3 }1 K4 K+ E) H2 Z5 U& H/ {, B
尺寸字段数据类型说明
?lengthvarint字符串的长度,以字节为单位
lengthstringuint8[length]字符串本身
5 {1 A# c) I: p* E1 p- M: i
array:数组,由一个变长整数后接元素序列构成。
  ?' v. ~8 M9 w定点数6 }& \7 x/ n  w2 D
NEO 系统中的金额、价格等数据,统一采用 64 位定点数,小数部分精确到 10-8,可表示的范围是:[-263/108, +263/108)
: H* E+ w, |4 I" m  k数据结构
& D% F+ P; I$ ^. q; I区块链
# F9 g& r8 {/ i区块链是一种逻辑结构,它以单向链表的形式将区块串联起来,用于存放全网的交易、资产等数据。
" }! b! |# K. X. K! l3 E区块6 D$ G$ j' D" C; u% c* P' |
尺寸字段数据类型说明
4Versionuint32区块版本,目前为 0
32PrevBlockuint256前一个区块的散列值
32MerkleRootuint256交易列表的根散列
4Timestampuint32时间戳
4Indexuint32区块高度(区块索引) = 区块数量 - 1
8ConsensusDatauint64共识数据(共识节点生成的伪随机数)
20NextConsensusuint160下一个区块的记账合约的散列值
1-uint8固定为 1
?Scriptscript用于验证该区块的脚本
?*?Transactionstx[]交易列表

" P7 n! N4 O5 d( I) w2 @8 @& f' p在计算区块散列时,并不会把整个区块都计算在内,而是只计算区块头的前 7 个字段:Version, PrevBlock, MerkleRoot, Timestamp, Height, Nonce, NextMiner。由于 MerkleRoot 已经包含了所有交易的散列值,因此修改交易也会改变区块的散列值。$ Z( |( t0 N" i
区块头的数据结构如下:5 H) }8 d& t& n& A
尺寸字段数据类型说明
4Versionuint32区块版本,目前为 0
32PrevBlockuint256前一个区块的散列值
32MerkleRootuint256交易列表的根散列
4Timestampuint32时间戳
4Indexuint32区块高度(区块索引) = 区块数量 - 1
8ConsensusDatauint64共识数据(共识节点生成的伪随机数)
20NextConsensusuint160下一个区块的记账合约的散列值
1-uint8固定为 1
?Scriptscript用于验证该区块的脚本
1-uint8固定为 0
' [* r" S7 j5 E* y
每个区块的时间戳必须晚于前一个区块的时间戳,一般两个区块的时间戳相差 15 秒左右,但是也允许出现不精确的情况。区块的高度值必须恰好等于前一个区块的高度值加一。
& v! o+ Y7 e$ H2 a交易
  F/ g; M3 O, V& b
尺寸字段数据类型说明
1Typeuint8交易类型
1Versionuint8交易版本,目前为 0
?--特定于交易类型的数据
?*?Attributestx_attr[]该交易所具备的额外特性
34*?Inputstx_in[]输入
60*?Outputstx_out[]输出
?*?Scriptsscript[]用于验证该交易的脚本列表
# {2 e6 t4 b7 ^9 n5 L9 K9 W
NEO 系统中的一切事务都以交易为单位进行记录。交易有以下几种类型:
! b8 q' N; S" ^
名称系统费用说明
0x00MinerTransaction0用于分配字节费的交易
0x01IssueTransaction500|0用于分发资产的交易
0x02ClaimTransaction0用于分配 NeoGas 的交易
0x20EnrollmentTransaction1000(已弃用) 用于报名成为共识候选人的特殊交易
0x40RegisterTransaction10000|0(已弃用) 用于资产登记的交易
0x80ContractTransaction0合约交易,这是最常用的一种交易
0xd0PublishTransaction500*n(已弃用)智能合约发布的特殊交易
0xd1InvocationTransaction0调用智能合约的特殊交易

3 d: n$ D# J  s* G$ L9 Z) I每一种类型的交易除了具有交易的公共字段之外,还会具有自己的专属字段。关于不同类型交易的专属字段,下文会有详细说明。
" \3 o3 K5 \! YMinerTransaction* _( ?, b  \( W8 E  g
尺寸字段数据类型说明
---交易的公共字段
4Nonceuint32随机数
---交易的公共字段
* d/ N+ N) H" T2 V
每一个区块的第一笔交易必然是 MinerTransaction。它用于将当前区块中所有的交易手续费奖励给记账人。
' Z+ j3 {8 t* w2 c/ X; O交易中的随机数用于防止出现散列冲突。
2 s; ^6 H2 r) [4 r8 l# |5 XIssueTransaction# I+ D5 O' ]% H
资产发行交易没有额外的特殊字段。5 X& ^6 w! ?2 U+ d8 \
资产管理员可以通过资产发行交易,将已经登记过的资产在 NEO 区块链上制造出来,并发送到任意地址。
0 }% m1 ?! _, p特别的,如果发行的资产是 NEO,那么这笔交易将可以免费发送。9 I9 Z2 K3 T1 F9 G3 Y
ClaimTransaction
! x; o+ [5 Y9 a7 f
尺寸字段数据类型说明
---交易的公共字段
34*?Claimstx_in[]用于分配的 NEO
---交易的公共字段

% V8 a  P5 e+ ^& H7 dEnrollmentTransaction
3 S& {1 l1 `5 N  ^' D% @9 Y- F6 d5 s! b. R& ~, R  _
[!Warning]
# V5 i$ W3 S* h3 n, ^% E' N已弃用,已被智能合约的 Neo.Blockchain.RegisterValidator 所替代。% k4 o  L9 J: J. Z  f
- F+ Q; C, ~- r7 [- ~( c
查看 替代的 .NET 智能合约框架
, f# l* p- a# q6 d! C查看 替代智能合约 API 3 T' T/ v0 o% _) M$ g
RegisterTransaction6 Q8 }! _3 i' t) E3 t) m

5 i+ l% W+ \0 l. P[!Warning]
5 b) u7 U7 A- D3 t% B已弃用,已被智能合约的 Neo.Blockchain.CreateAsset 所替代。& z: T2 Y6 [: B. U; u) @2 g( B

/ {0 u0 p0 S; S4 h. ]" ?1 O查看 替代的 .NET 智能合约框架, [  F& s# Y1 }9 V; Y
查看 替代智能合约 API ! ?5 d% f' B+ o' B) h& [% N6 ]
ContractTransaction
2 g! I4 D# z0 P" [5 l7 v& m3 W合约交易没有任何特殊的地方。
0 }% x( g3 h% d9 OPublishTransaction2 E( O* ?1 `; }7 f5 \1 k  ]

/ }" U: F3 V+ y+ B# ]* x( ~# b[!Warning]
' d) I  Y( j2 e( {- u3 W7 h已弃用,已被智能合约的 Neo.Blockchain.CreateContract 所替代。7 c* u" i3 s  y5 D9 p
! r; m( S  T, G
查看 替代的 .NET 智能合约框架! m4 Y9 a. [8 y: \* W. R
查看 替代智能合约 API
/ b9 |. o  Y, Z; b- M; e" F- vInvocationTransaction3 J8 m7 G  t2 J. ]0 s: s
尺寸字段数据类型说明
---交易的公共字段
?Scriptuint8[]所调用的智能合约的脚本
8Gasint64运行所调用的智能合约需要的费用
---交易的公共字段

" ]' J# v2 q6 o) r* T1 q交易特性# e) I) c4 @+ B  `6 M1 b2 k
尺寸字段数据类型说明
1Usageuint8用途
0|1lengthuint8数据长度(特定情况下会省略)
lengthDatauint8[length]特定于用途的外部数据

0 V% d! W# ]/ T* {7 b5 w有时候交易中会需要包含一些供外部使用的数据,这些数据将统一被放置在交易特性字段中。
% j( \* S+ H9 V2 K8 `: M每个交易特性可以有不同的用途:* `" x& q& i" o3 h9 v0 |
名称说明
0x00ContractHash外部合同的散列值
0x02-0x03ECDH02-ECDH03用于 ECDH 密钥交换的公钥
0x20Script用于对交易进行额外的验证
0x30Vote用于投票选出记账人
0x81DescriptionUrl外部介绍信息地址
0x90Description简短的介绍信息
0xa1-0xafHash1-Hash15用于存放自定义的散列值
0xf0-0xffRemark-Remark15备注

. S6 [. S# F' {3 h3 |0 f8 L对于 ContractHash,ECDH 系列,Vote,Hash 系列,数据长度固定为 32 字节,length 字段省略;1 p$ n1 E. V* d
对于 Script,数据长度固定为 20 字节,存放地址;' i$ ], O2 S" \$ T3 [
对于 DescriptionUrl,必须明确给出数据长度,且长度不能超过 255 字节;& O2 e4 ?5 a4 o- x3 Y
对于 Description 和 Remark 系列,必须明确给出数据长度, 且长度不能超过 65535 字节。
, }, F% O% K* c2 R4 k+ T交易输入
  m8 m$ g3 i: a7 A0 B6 y
尺寸字段数据类型说明
32PrevHashuint256引用交易的散列值
2PrevIndexuint16引用交易输出的索引

8 ?1 I5 g4 }( Y; J% k8 q交易输出
: T3 I4 J9 c" E
尺寸字段数据类型说明
32AssetIduint256资产编号
8Valueint64金额
20ScriptHashuint160收款地址
: l2 a* x7 X4 N. c8 A
每个交易中最多只能包含 65536 个输出。
  {7 k! O, z3 q0 D; B7 t( X验证脚本' Z. n" j" k, s$ _& a
尺寸字段数据类型说明
?StackScriptuint8[]栈脚本代码
?RedeemScriptuint8[]合约脚本代码
; s5 E5 R' ]8 u- }# U
栈脚本中只能包含压栈操作指令,用于向合约脚本传递参数(如签名等)。脚本解释器会先执行栈脚本代码,然后执行合约脚本代码。9 H6 z! \) ^4 m# |" U
在一笔交易中,合约脚本代码的散列值必须与交易输出中的一致,这是验证的一部分。关于脚本执行的过程,后文会详细阐述。
" Q4 S. G3 L* d; E2 w  B5 w网络消息7 `2 }* D$ F" b
所有的网络消息都通过以下消息结构来发送:8 ~% \- I+ B5 Z; _
尺寸字段数据类型说明
4Magicuint32协议标识号
12Commandchar[12]命令
4lengthuint32Payload 的长度
4Checksumuint32校验和
lengthPayloaduint8[length]消息内容
4 m, Q4 r$ D. c
已定义的 Magic 值:
1 V% u5 G& D6 B6 Y
说明
0x00746e41正式网
0x74746e41测试网
- \+ e( x5 G/ T# |. n9 k' c$ g& J
Command 采用 utf8 编码,长度为 12 字节,多余部分用 0 填充。* e  o2 m4 L; C! w" l
Checksum 是 Payload 两次 SHA256 散列后的前 4 个字节。
/ P8 X/ g  v# e7 J' E2 ?/ m7 ]Payload 根据不同的命令有不同的详细格式,见下文。# Q. [, |4 ^; ~& M3 f# [
version  E* e. q, s9 a) W! w& G$ d
尺寸字段数据类型说明
4Versionuint32协议版本,目前为 0
8Servicesuint64节点提供的服务,目前为 1
4Timestampuint32当前时间
2Portuint16监听的端口,如果不监听则为 0
4Nonceuint32用于区分相同公网 IP 的节点
?UserAgentvarstr客户端标识
4StartHeightuint32区块链高度
1Relaybool是否接收并转发

1 H4 w8 a( T4 |  j$ O- I一个节点收到连接请求时,它立即宣告其版本。在通信双方都得到对方版本之前,不会有其他通信。6 r" S3 E! ?1 g/ s' \
verack
5 ^: O' g1 z- |1 T- ]5 C' @节点收到 version 消息后,立刻回复一个 verack 作为应答。& L8 Q! X* L6 R% t3 m
此消息没有 payload。! U0 y$ w- o+ P; h$ [+ a3 U! b
getaddr
8 `$ d; @% A# }' t向一个节点请求一批新的活动节点,以增加自身的连接数。
& }( v; L# L6 v. N2 e$ V2 y1 D此消息没有 payload。
& @5 c& l$ I: l0 ?; caddr
2 \4 w( m( ]1 B" q9 K
尺寸字段数据类型说明
30*?AddressListnet_addr[]网络上其他节点的地址
* Y/ J4 h! w) O
节点收到 getaddr 消息后,返回一个 addr 消息作为应答,提供网络上已知节点的信息。) \( ~7 U+ a# r* Z* r  ^
getheaders
# `& T6 G+ A. C& j2 {9 W3 M
尺寸字段数据类型说明
32*?HashStartuint256[]节点已知的最新 block 散列
32HashStopuint256请求的最后一个 block 的散列

! ]4 P9 y$ F+ a5 ~/ r0 l向一个节点请求包含编号 HashStart 到 HashStop 的至多 2000 个 block 的 header 包。要获取之后的 block 散列,需要重新发送 getheaders 消息。这个消息用于快速下载不包含相关交易的 blockchain。
4 C; x0 V/ j9 y' lheaders
/ u6 g" Y  ?# A9 P" e
尺寸字段数据类型说明
?*?Headersheader[]区块头

% x- K4 c0 g$ `. J1 _$ y& X节点收到 getheaders 消息后,返回一个 headers 消息作为应答,提供请求的区块头。5 C% a+ B/ ^' R, S, d
getblocks9 i0 t! V3 e2 C1 f1 y/ K
尺寸字段数据类型说明
32*?HashStartuint256[]节点已知的最新 block 散列
32HashStopuint256请求的最后一个 block 的散列
$ o6 ?/ e: S( U* Q
向一个节点请求包含编号从 HashStart 到 HashStop 的 block 列表的 inv 消息。若 HashStart 到 HashStop 的 block 数超过 500,则在 500 处截止。欲获取后面的 block 散列,需要重新发送 getblocks 消息。; |. D$ ^$ |6 d8 x- a0 L
inv
+ m) ]% D& `; B' ^* t, `9 f( ?
尺寸字段数据类型说明
1Typeuint8清单类型
32*?Hashesuint256[]清单
# f; V) b. R. c3 w% M
节点通过此消息可以广播它拥有的对象信息。这个消息可以主动发送,也可以用于应答 getbloks 消息。
3 e) u  D. N$ M' T清单类型有以下几种:! a3 r2 j! h. l' R
名称说明
0x01TX交易
0x02Block区块
0xe0Consensus共识数据
6 W4 v# s" D. c% ?$ G9 V
getdata
1 Z( \8 ^. j$ [- }) u& J
尺寸字段数据类型说明
1Typeuint8清单类型
32*?Hashesuint256[]清单
2 s3 c5 B7 ^, A
向一个节点请求指定的对象,它通常在接收到 inv 包并滤去已知元素后发送。
2 z! f2 i! P2 [7 y9 [block
( P- w3 l9 ?3 A
尺寸字段数据类型说明
?Blockblock区块
3 e$ t$ g6 g6 e8 _: U4 g5 s
向一个节点发送一个区块,用于响应请求数据的 getdata 消息。4 \6 H9 E2 ]3 B5 l0 @3 Q7 D, [  m
tx2 [* B+ Y& h$ U
尺寸字段数据类型说明
?Transactiontx交易
, w4 [: s  T; y: a! x- {
向一个节点发送一笔交易,用于响应请求数据的 getdata 消息。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

宠着祖宗 小学生
  • 粉丝

    0

  • 关注

    0

  • 主题

    1