Hello , 我是09

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

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

币种介绍

新经币的单位为:1000000

新经币创世区块时间:1427558785,交易数据中时间戳参数需要减去创世时间戳

私钥的生成:可视化是要和公钥的方式直接转十六进制就可以。

公钥的生成:计算公钥采用的是ED25519,生成length为32的公钥。

签名算法:ED25519

交易类型

本文只介绍新经币交易,马赛克交易不做分析。

交易类型对应的Type列表如下:

XEM_TRANSACTION_TYPE_TRANSFER                0x0101
XEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER     0x0801
XEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION  0x1001
XEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE      0x1002
XEM_TRANSACTION_TYPE_MULTISIG                0x1004
XEM_TRANSACTION_TYPE_PROVISION_NAMESPACE     0x2001
XEM_TRANSACTION_TYPE_MOSAIC_CREATION         0x4001
XEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE    0x4002
XEM_NETWORK_MAINNET 0x68
XEM_NETWORK_TESTNET 0x98
XEM_NETWORK_MIJIN   0x60

交易中的Version字段获取方式

def _get_version(network, mosaics=None) -> int:
    if mosaics:                        // 如果是马赛克交易,计算version和普通交易略有区别
        return network << 24 | 2
    return network << 24 | 1

交易数据解析

完整的待广播交易数据

{
  "signature" : "1d863d55ecddcdf0c004345063eb99f6135b41938bc1b8f9a062141854f182df3094e46b07898edb459d522a2ebc617660f87093112ca05ac91f8dbe126dd40d",
  "data" : "0101000001000068a7b6870820000000a2a00cc85d5307c83475393938559d7224d2bd6a8f732c3efcb426f79695d34550c30000000000007fc58708280000004e415848514d474b474b444d555256415a444a4836344d554d4854514e5548574432495346475651e803000000000000110000000100000009000000313233616263333231"
}

我们先来解析data

01010000            // Type    交易类型
01000068            // Version
a7b68708            // TimeStamp
20000000            // 公钥长度
a2a00cc85d5307c83475393938559d7224d2bd6a8f732c3efcb426f79695d345    // 公钥
50c3000000000000    // 手续费
7fc58708            // Deadline过期时间戳
28000000            // 接收地址长度
4e415848514d474b474b444d555256415a444a4836344d554d4854514e5548574432495346475651    // 接收地址
e803000000000000    // 金额 
11000000            // 备注的总长度
01000000            // 备注是否加密
09000000            // 备注长度
313233616263333231  // 备注内容

这里有几个地方需要注意

1. Type、Version、TimeStamp、Publickey_len、Deadline、Receive_addr_len、payload_all_len、payload_Crypto、payload_len 均为Uint32类型,4个Byte。
2. Fee、Amount均为Uint64,8个Byte。
3. Type字段代表交易类型,官方有定义,不同的交易类型对应不同的数据,参考文章开始的前提内容。
4. Version 是通过固定的算法得到的,主网的type 0x68 << 24 | 1    马赛克的transfer交易计算方式为 0x68 << 24 | 2。
5. TimeStamp和Deadline需要用获取  当前时间戳 - 新经币创世区块时间戳 - 时区时间差,Deadline则需要再减去交易过期时间
举例:
time_stamp = 1570699556
timeStamp = [NSString stringWithFormat:@"%d",[time_stamp intValue] - NEM_TIMESTAMP_VALUE - 28800];
deadline = [NSString stringWithFormat:@"%d",[time_stamp intValue] - NEM_TIMESTAMP_VALUE - 25000];
获取到这两字段内容后,需要将十进制数据转换为十六进制,最后再进行大小端转换。
6. 公钥长度、接收地址长度、peyload总长度与payload长度都是统一转十六进制后,最后进行小端转换。
7. 接收地址长度和接收地址:这个有点意思,首先将接收地址的每一个字符转换为对应的ASCII对应的十六进制编码,然后再计算编码后的长度,接收地址直接拼接ASCII转码后的数据。
8. 手续费和转账金额都为金额转十六进制后,进行小端转换。
9. 备注的总长度计算方法为 备注的长度 + NSInteger.size / Byte.size + NSInteger.size / Byte.size
10. 备注是否加密:1为不加密,2为加密
11. 备注内容比较简单,就是单纯的将备注内容进行ASCII码十进制转换,转换后直接拼接即可!

签名

data:
0101000001000068a7b6870820000000a2a00cc85d5307c83475393938559d7224d2bd6a8f732c3efcb426f79695d34550c30000000000007fc58708280000004e415848514d474b474b444d555256415a444a4836344d554d4854514e5548574432495346475651e803000000000000110000000100000009000000313233616263333231

签名实际上就是对以上data内容(待签名交易数据)进行签名
(1)签名所用到的私钥与公钥,都需要将每一个字符转ASCII对应的十六进制编码,转换前私钥与公钥都应该只有32个Byte,转换后都为64个Byte。
(2)签名算法方法内部得到私钥后,先进行大小端转换后,做哈希3-512操作也就是SHA3_512,然后在拼接交易数据,然后在整体进行SHA3_512操作等等。
(3)签名用到的是ED25519
(4)签名结果长度为64个Byte
例:1d863d55ecddcdf0c004345063eb99f6135b41938bc1b8f9a062141854f182df3094e46b07898edb459d522a2ebc617660f87093112ca05ac91f8dbe126dd40d
(5)签名后,将数据拼接为我举例的格式,然后直接广播即可!