Hello , 我是09

此篇内容为我2018~2020年在【库神】工作时,对部分重要知识做的学习总结

随着比特币冲破10万美金,行业又再次兴起,希望相关从业者可以学习到你需要的内容

介绍

私钥

Secp256k1,和比特系列一样

公钥

Secp256k1,和比特系列一样

构建交易

(1)所有数据采用RLP编码,RLP编码规定数据(字符串或列表)的长度的长度不得大于8字节。因为超过8字节后,一个字节的前缀就不能存储了,大致RLP的规则是清除掉数据签名的站位0,然后对数据进行大端存储,详细内容可以百度RLP。

(2)所有构建的交易数据,转十六进制后,需要进行去除站位用到的0。

(3)RLP编码,针对String类型的编码规范如下:

数据长度为 1 :如果字符串的长度是1个字节,并且它的值在[0x00, 0x7f],所以不需要添加前缀,因为大于0x7f的话就是大于127,那么在阿斯克码表中长度就无法用一个字符来表示了,

数据长度0~55:其RLP编码是前缀跟上(拼接)字符串本身,前缀的值是0x80加上字符串,字符串的最大长度是55,因此前缀的最大值是0x80+55=0xb7,取值范围是[0x80, 0xb7]

数据长度 > 55:前缀的值是0xb7加上字符串长度的二进制形式的字节长度,因此前缀的最大值是0xb7+8=0xbf,因此在本规则下前缀的取值范围是[0xb8, 0xbf]

RLP编码,针对列表List,iOS中为Array类型:

数据长度为0~55:前缀的值是0xc0加上列表的总长度。在本规则下前缀的取值范围是[0xc0, 0xf7]。

数据长度 > 55:前缀的值是0xf7加上列表总长度的长度。编码的第一个字节的取值范围是[0xf8, 0xff]

e8			// 0xC0 + 整体交易数据的len 我的交易数据长度为40,那么192 + 40 = 232 所以为e8
80			// nonce len + 0x80 (我测试这一笔nonce为0,所以十六进制为80)
85			// gasprice len + 0x80 + 5
02540be400	// gasprice
83			// gaslimit len + 0x80 + 3
013880		// gaslimit
94			// to addr len + 0x80V+ 20
fb69e9a99762a5e30dda7f677722b8c3bd4d3414	// to addr
86			// Amount  len + 0x80
5af3107a4000	// Amount

签名

(1)采用Secp256k1

(2)对数据采用采用SHA3_256操作。

(3)签名过后,需要将签名的数据对应r、s、v分开来分别操作。

(4)v需要加等于27.

(5)签名后得到的数据:

aa41c9ba059210fa658640ca9f312a30c18781ea85f4d6b03984407e43c579f35337604cd48ee1cfdfeed742f53559be77311b004fa8424d7de8e400af5f8215

(6)对于签名数据需要拆分,并拼接到交易数据中

1b		// sign V  (V = 27)	27的数据length为1, 当数据长度为1的时候,计算长度的时候不需要
a0		// Signr len + 0x80
aa41c9ba059210fa658640ca9f312a30c18781ea85f4d6b03984407e43c579f3	// Signr
a0		// SignS len + 0x80
5337604cd48ee1cfdfeed742f53559be77311b004fa8424d7de8e400af5f8215	// SingS

五、完整待广播交易数据

f86b808502540be4008301388094fb69e9a99762a5e30dda7f677722b8c3bd4d3414865af3107a4000801ba0aa41c9ba059210fa658640ca9f312a30c18781ea85f4d6b03984407e43c579f3a05337604cd48ee1cfdfeed742f53559be77311b004fa8424d7de8e400af5f8215

f8		// 0xf7 + 整个数据的len “6b” 所占的字节len   就变成了 0xf7 + 1 = 0xf8
6b		// 整个交易数据的长度 包括签名
80		// nonce len + 0x80 (我测试这一笔nonce为0,所以十六进制为80)
85		// gasprice len + 0x80
02540be400	// gasprice
83		// gaslimit len + 0x80
013880		// gaslimit
94		// to addr len + 0x80
fb69e9a99762a5e30dda7f677722b8c3bd4d3414	// to addr
86		// Amount len + 0x80
5af3107a4000	// Amount
80		// 备注,因为没有备注所以长度为0x80 + 0 = 0x80		
1b		// sign V  (V = 27)		27的数据length为1, 当数据长度为1的时候,计算长度的时候不需要    hby + 27 + 1
a0		// Signr len + 0x80
aa41c9ba059210fa658640ca9f312a30c18781ea85f4d6b03984407e43c579f3	// Signr
a0		// SignS len + 0x80
5337604cd48ee1cfdfeed742f53559be77311b004fa8424d7de8e400af5f8215	// SingS

总结

(1)在对交易签名、没有签名的时候,拼接整体数据的头部信息是不一样的!

(2)所有数据,都需要删除站位的0。

(3)签名后需要将r、s分开处理。

(4)v单独处理

RLP编码规则

RLP编码的重点是给原始数据前面添加若干字节的前缀,而且这个前缀是和数据的长度相关的,并且是递归的。

RLP编码中的长度是数据的实际存储空间的字节大小,去掉首位0的正整数,用大端模式表示的二进制格式表示。

RLP编码规定数据(字符串或列表)的长度的长度不得大于8字节。因为超过8字节后,一个字节的前缀就不能存储了。

如果字符串的长度是1个字节,并且它的值在[0x00, 0x7f] 范围之间,那么其RLP编码就是字符串本身。即前缀为空,用前缀代表字符串本身;

否则,如果一个字符串的长度是0-55字节,其RLP编码是前缀跟上(拼接)字符串本身,前缀的值是0x80加上字符串的长度。由于在该规则下,字符串的最大长度是55,因此前缀的最大值是0x80+55=0xb7,所以在本规则下前缀(第一个字节)的取值范围是[0x80, 0xb7];

如果字符串的长度大于55个字节,其RLP编码是前缀跟上字符串的长度再跟上字符串本身。前缀的值是0xb7加上字符串长度的二进制形式的字节长度(即字符串长度的存储长度)。即用额外的空间存储字符串的长度,而前缀中只存字符串的长度的长度。例如一个长度是1024的字符串,字符串长度的二进制形式是\x04\x00,因此字符串长度的长度是2个字节,所以前缀应该是0xb7+2=0xb9,由此得到该字符串的RLP编码是\xb9\x04\x00再跟上字符串本身。因为字符串长度的长度最少需要1个字节存储,因此前缀的最小值是0xb7+1=0xb8;又由于长度的最大值是8个字节,因此前缀的最大值是0xb7+8=0xbf,因此在本规则下前缀的取值范围是[0xb8, 0xbf];

以上3个规则是针对字符串的,接下来的两个规则针对列表的。由于列表的任意嵌套的,因此列表的编码是递归的,先编码最里层列表,再逐步往外层列表编码。如果一个列表的总长度(payload,列表的所有项经过编码后拼接在一起的字节大小)是0-55字节,其RLP编码是前缀依次跟上列表中各项的RLP编码。前缀的值是0xc0加上列表的总长度。在本规则下前缀的取值范围是[0xc0, 0xf7]。本规则与规则2类似;

如果一个列表的总长度大于55字节,它的RLP编码是前缀跟上列表的长度再依次跟上列表中各元素项的RLP编码。前缀的值是0xf7加上列表总长度的长度。编码的第一个字节的取值范围是[0xf8, 0xff]。本规则与规则3类似;

问题

v : 代表什么意思

为什么不需要From addr

签名数据里面为什么没有公钥

RLP的优势

KFC6979

Private到keystore的导入导出