Transaction对象由字段集合构成
字段又含有两个部分组成:
公共字段:交易类型,发起交易的帐号
特殊字段:特定于交易类型的相关信息的字段集合
交易对象的两种表示方法:JSON对象、二进制对象
在JSON中表示为"TransactionType":"Payment", 而采用二进制表示时,
Name是由一个数值对<Type, Code>表示, Value则是一个16位的数值.
交易类的每一个字段都是键值对 pair
字段信息:
Transaction类型
货币类型
货币类型有三个部分组成:
1.货币代码:160bits的整形表示 全0 表示原生货币SDA
2.货币发行商帐号
3.货币值 采用科学计数法
字段序列化
为了签名的二进制形式有序 唯一需要对字段进行排序 也就是进行字段序列化
Name由 <Type,Code>两个整数表示
1.先对字段名Name序列化,序列化是两个数值的编码
2.对字段值Value序列化,取决于字段类型
3. 对于特殊类型 STI_OBJECT STI_ARRAY字段需要添加结束标记
货币类型序列化
NotNative 0为原生货币 1为非原生货币
NotNegative 货币value符号为 0正1负
Offset 科学计数法中的值
Value 科学计数法
对于非原生货币 也就是NotNative为1的时候 需要就爱上货币代码和发行商帐号信息 160bits
变长字节数组序列化
1.编码数组长度
2.将数组中的L字节按顺序依次存储
256bits 整型数组序列化
1.计算数组的字节数 SIZE 并且按照变长字节数组长度的方式编码SIZE
2.顺序地遍历数组 序列化表示每个整形的32字节数组
路经集合序列化
…
以上是对字段的序列化……
交易对象序列化
对于整个对象的序列化不是简单的序列化它所包含的字段 为了保证一致性 我们还要保证交易对象序列化内容的确定性;所以要保证对象字段的序列化顺序,具体做法:
根据字段Name构造一个用于排序的32位整型的Key = (type << 16) | Code
对象可能嵌套 也就是说一个对象字段包含的是另一个对象
签名流程
为了检验交易的合法性,必须由交易发起人对交易对象进行数字签名,一个完成的签名是一个闭环过程,不仅仅涉及发起交易的人,还要由处理交易的人对签名进行校验,验证合法性,整个流程如下:
1.交易发起人,提取Transaction对象中的签名数据进行序列化,结果记为5
2.选择交易签名的算法A,目前底层支持两种签名算法secop256k1 ed25519 默认前者
3.将S作为输入。选择交易发起帐号所对应的签名密钥 交给签名算法A 获得签名结果R
4.将签名结果R作为字段TxnSignature 增加到 Transaction对象中 Name为<STI_VL,14>
5.将验证签名的公钥,作为字段SigningPubKey增加到Transaction对象中
6.序列化Transaction对象,通过其结果构造交易请求 发送到底层SDChain
7.SDChain 反序列化获得的交易对象,从中获取交易发起人帐号信息Account和签名验证公钥SigningPubKey确认后者是否属于前者的签名验证公钥,如果是,则执行步骤8否则判定为交易不合法
8.底层从Transaction对象中获取签名数据进行序列化 获得输出S*
9.根据签名公钥SigningPubKey 获得签名算法A*
10.从Transaction对象中获取TxnSignature字段的值R* 并结合S* A*和SigningPubKey验证签名合法性
Transaction对象签名数据
交易签名数据是从Transaction对象字段集合中提取的用于签名的字段子集,具体的组成取决于交易类型,但无论这个子集是什么,其处理于交易对象序列胡一样,对于这个自己的字段根据字段Key进行增序排序,然后根据此顺序依次序列化获得签名数据 各个交易类型的签名字段及
签名算法
无论选择什么签名算法,签名基本思想都是一样的
1.根据输入的种子Seed(一个足够大的随机数) 生成密钥对 保存SecKey公开PubKey
2.用SecKey加密数据 生成签名
3.用PubKey从签名中解密数据 验证与原数据是否一致
目前, 底层支持两种签名算法Secp256K1和Ed25519, 用户可在使用时自行选择, 为了让底层区分或理解上层应用选择的那种签名算法, 我们在编码公钥时, (可以理解为)会加上算法类型前缀: 对于Secp256K1的公钥, 其第一个字节是0x02或0x03; 对于Ed25519的公钥, 其第一个字节是0xED. 另外, 两个算法的私钥长度都是32字节, 公钥的长度是33字节.
Seed的生成
为了防止密钥对被破解 Seed应该是一个足够大的随机数 128bits整型,但在实际应用时有的时候也需要根据一个给定输入的Passphrase产生 底层支持的四种Seed获取方式
1.用户直接给出 通常以十六进制存储
2.用户输入Passphrase 使用SHA512计算出hash值 取前128bits作为Seed
3.用户输入一个引文短语 由12个英文单词构成 然后转化成128bits的Key 反序后作为Seed
4.根据一个加密安全的伪随机数产生器产生一个128bits随机数作为Seed
观察一个sign功能 他的第一个参数是私钥 也就是账户发起者的私钥 然后是json格式的数据包 是否进行离线签名的选项