XRP-瑞波币-交易解析

以下内容为作者本人吐血总结,如有错误、或有问题欢迎请留言讨论,谢谢!


交易前提

  • 瑞博币的单位为:1000000
  • 发送金额不能小于0.01,否则会返回本地签名认证失败。
  • 新的瑞波币地址必须转入20个Xrp才可以激活账户。
  • 交易后地址余额必须大于20,否则交易无法被确认,会被节点直接打回。

交易特点

  • 瑞波币交易数据采用TV格式(tag、value)
  • 编号来源,和定义规则如下
  • Tag的计算是由类型以及领域对应的编码计算得到的。
#define XRP_FIELD_TYPE_INT16    @"1"         
#define XRP_FIELD_TYPE_INT32    @"2"
#define XRP_FIELD_TYPE_AMOUNT   @"6"
#define XRP_FIELD_TYPE_VL       @"7"
#define XRP_FIELD_TYPE_ACCOUNT  @"8"

交易数据中的每一个参数在对应的领域中都有自己的编码,当前是在交易领域
普通瑞博币转账交易参数编码如下:

@"account":             @{@"type": XRP_FIELD_TYPE_ACCOUNT,   @"key": @(1)},
@"type":                @{@"type": XRP_FIELD_TYPE_INT16,     @"key": @(2)},
@"flags":               @{@"type": XRP_FIELD_TYPE_INT32,     @"key": @(2)},
@"sequence":            @{@"type": XRP_FIELD_TYPE_INT32,     @"key": @(4)},
@"amount":              @{@"type": XRP_FIELD_TYPE_AMOUNT,    @"key": @(1)},
@"fee":                 @{@"type": XRP_FIELD_TYPE_AMOUNT,    @"key": @(8)},
@"signingPubKey":       @{@"type": XRP_FIELD_TYPE_VL,        @"key": @(3)},
@"txnSignature":        @{@"type": XRP_FIELD_TYPE_VL,        @"key": @(4)},
@"destination":         @{@"type": XRP_FIELD_TYPE_ACCOUNT,   @"key": @(3)},
@"lastLedgerSequence":  @{@"type": XRP_FIELD_TYPE_INT32,     @"key": @(27)}

OC代码计算Tag的方式如下

- (void)write_typeWithTransactionData:(NSMutableData *)transaction sourceDicr:(NSDictionary *)sourceDicr
{
    if ([sourceDicr[@"key"] intValue] <= 0xf) {
        int mark = ([sourceDicr[@"type"] intValue] << 4) | [sourceDicr[@"key"] intValue];
        [transaction appendInt8:mark];
    }else{
        [transaction appendInt8:[sourceDicr[@"type"] intValue] << 4];
        [transaction appendInt8:[sourceDicr[@"key"] intValue]];
    }
}

重点参数含义

LastLedgerSequence,它是所有事务的可选参数。

  • 因为部分情况下,手续费给的过低,可能很久很久没有被确认,又无任何消息响应,如果这笔交易添加了该参数,那么到一定的区块高度时,如果交易还没有被确认,那么交易会被撤回,用户可以重新发送自己当前的金额。
  • LastLedgerSequence代表瑞波币区块链一共处理了多少笔交易,我们传入构建交易的这个参数必须要大于这个最新的交易值,如果大于1000,那么在最新的1000笔交易之内必须要完成这笔交易,如果这笔交易在1000之内没有被确认,那么直接按失败处理。不会让用户等过久。

交易详情

交易场景:
交易类型:Payment
发起地址 = rfXSBUpv9Yr41q5qFGRo9LJi1Jbe1wNEFe
接收地址 = rHXKdQhjXUtotW3yaofmu3YyuSZ2FXfxFC
手续费 = 0.01
转账金额 = 0.01
备注 = ""            // 这里作者备注给的空字符串
对应完整待签名交易数据
5354580012000022800000002400000007201b0000000b614000000000002710684000000000002710732103e7dfa41a3e7f626c5c0d1a2d8c0b1ac3baf6039bef1d1996993dc8f9dc816d3c811447923fc967fed6a696ec0cd3e2ae852901a9e8698314b53e0a778749318b634d1ed7c25667bb2b2412a3

解析交易数据

53545800  // 签名信息标记(0x53545800L),
12        // TransactionType标记 payment为“0000”是uint16类型, 对应的Key等于2  而2小于0xf, 所以计算方式为 1 << 4 | key(key为1) 等于12    1<<4 = 10000(二进制) 转换为10进制等于16   16 | 2 等于18, 18转换为16进制等于12.
0000      // TransactionType  当前是Payment
22        // Flags 标记
80000000  // Flags  2147483648的十六进制形式展现
24        // Sequence 标记
00000007  // Sequence
20        // lastLedgerSequence  type << 4   因为lastLedgerSequence 对应key为27,而27大于0xf,所以先拼接 type << 4 在拼接 key  type << 4 = 32十六进制为20  key = 27 十六进制为1b
1b        // lastLedgerSequence  key27 = 1b
026F2922  // 最新总交易确认数 + 1000  转十六进制
61                  // Fee 标记
4000000000002710    // Fee
68                  // Amount 标记
4000000000002710    // Amount
73                  // PublicKey 标记
21                  // PublicKey len
03e7dfa41a3e7f626c5c0d1a2d8c0b1ac3baf6039bef1d1996993dc8f9dc816d3c    // PublicKey
81                  // Account 标记
14                  // Account len
47923fc967fed6a696ec0cd3e2ae852901a9e869    // Account (就是公钥Hash160)
83                  // Recipient 标记
14                  // Recipient len
b53e0a778749318b634d1ed7c25667bb2b2412a3    // Recipient (就是公钥Hash160)

待广播交易数据解析

  • 完整待广播的十六进制交易数据
12000022800000002400000007201B026F2922614000000000002710684000000000002
710732103E7DFA41A3E7F626C5C0D1A2D8C0B1AC3BAF6039BEF1D1996993DC8F9DC816
D3C744630440220725C375C8332302013F3E3B29C668400FB799A8D8315CFBF8C7E09B
D2000FA3902207800E6E06E1A5719B3B0970C10C49FCFDEBFFEB3067209BB0B5619E5D
BFBC8A2811447923FC967FED6A696EC0CD3E2AE852901A9E8698314B53E0A778749318
B634D1ED7C25667BB2B2412A3
  • 十六进制交易数据解析
12          // TransactionType 标记
0000        // TransactionType  当前是Payment
22          // Flags 标记
80000000    // Flags  2147483648的十六进制形式展现
24          // Sequence 标记
00000007    // Sequence
20          // lastLedgerSequence  type << 4
1b          // lastLedgerSequence  key
026F2922    // 最新总交易确认数 + 1000  转十六进制
61          // Fee 标记
4000000000002710    // Fee
68                  // Amount 标记
4000000000002710    // Amount
73                  // PublicKey 标记
21                  // PublicKey len
03e7dfa41a3e7f626c5c0d1a2d8c0b1ac3baf6039bef1d1996993dc8f9dc816d3c    // PublicKey
74                  // Sign info 标记
46                  // Sign info len
3044
02203beee4ff172a0dc9d0c5582d5d44bcee1cc7f2a5a2bc98729909ecfeb4cbefda
022056b3cdd7a142b043335dc351e016b81cf249663fb4e2224b0e6ca58723937f40    // Sign info 
81                  // Account 标记
14                  // Account len
47923fc967fed6a696ec0cd3e2ae852901a9e869    // Account (就是公钥Hash160)
83                  // Recipient 标记
14                  // Recipient len
b53e0a778749318b634d1ed7c25667bb2b2412a3    // Recipient (就是公钥Hash160)

广播交易

  • 广播成功,节点会返回一下内容
{
    result =     {
        "engine_result" = tesSUCCESS;
        "engine_result_code" = 0;
        "engine_result_message" = "The transaction was applied. Only final in a validated ledger.";
        status = success;
        "tx_blob" = 120000228000000024000000026140000000000186A0684000000000002710732103E7DFA41A3E7F626C5C0D1A2D8C0B1AC3BAF6039BEF1D1996993DC8F9DC816D3C7447304502210095E65663549C2217FA6DCDD69703B2931E90469066476B386BF2E25E3E9ED03902200229E79FB9586E6498519C83242C04A85D5CC347F81576EDE16CCA8B82D13A2E811447923FC967FED6A696EC0CD3E2AE852901A9E8698314B53E0A778749318B634D1ED7C25667BB2B2412A3;
        "tx_json" =         {
            Account = rfXSBUpv9Yr41q5qFGRo9LJi1Jbe1wNEFe;
            Amount = 100000;
            Destination = rHXKdQhjXUtotW3yaofmu3YyuSZ2FXfxFC;
            Fee = 10000;
            Flags = 2147483648;
            Sequence = 2;
            SigningPubKey = 03E7DFA41A3E7F626C5C0D1A2D8C0B1AC3BAF6039BEF1D1996993DC8F9DC816D3C;
            TransactionType = Payment;
            TxnSignature = 304502210095E65663549C2217FA6DCDD69703B2931E90469066476B386BF2E25E3E9ED03902200229E79FB9586E6498519C83242C04A85D5CC347F81576EDE16CCA8B82D13A2E;
            hash = A675E3C64F7F93A97CA9E1BE93265C230A5D848594960605B7E684A688D39B87;
        };
    };
}
  • 广播失败,节点有可能会返回一下内容:
{
    result =     {
        "engine_result" = "tefMAX_LEDGER";   // ter,tef和tem 都为提交成功,但是是失败的 “tefMAX_LEDGER”。(它也可能因“tefALREADY”或“tefPAST_SEQ”而失败。)
        "engine_result_code" = "-187";
        "engine_result_message" = "Ledger sequence too high.";
        status = success;
        "tx_blob" = 12000022800000002400000007201B0000000B614000000000002710684000000000002710732103E7DFA41A3E7F626C5C0D1A2D8C0B1AC3BAF6039BEF1D1996993DC8F9DC816D3C7446304402203BEEE4FF172A0DC9D0C5582D5D44BCEE1CC7F2A5A2BC98729909ECFEB4CBEFDA022056B3CDD7A142B043335DC351E016B81CF249663FB4E2224B0E6CA58723937F40811447923FC967FED6A696EC0CD3E2AE852901A9E8698314B53E0A778749318B634D1ED7C25667BB2B2412A3;
        "tx_json" =         {
            Account = rfXSBUpv9Yr41q5qFGRo9LJi1Jbe1wNEFe;
            Amount = 10000;
            Destination = rHXKdQhjXUtotW3yaofmu3YyuSZ2FXfxFC;
            Fee = 10000;
            Flags = 2147483648;
            LastLedgerSequence = 11;
            Sequence = 7;
            SigningPubKey = 03E7DFA41A3E7F626C5C0D1A2D8C0B1AC3BAF6039BEF1D1996993DC8F9DC816D3C;
            TransactionType = Payment;
            TxnSignature = 304402203BEEE4FF172A0DC9D0C5582D5D44BCEE1CC7F2A5A2BC98729909ECFEB4CBEFDA022056B3CDD7A142B043335DC351E016B81CF249663FB4E2224B0E6CA58723937F40;
            hash = 5DA0D0479087438F32C49709788ECAD3B5904DB119E5E4130BD2AF3ED5044900;
        };
    };
}

@end

你可能感兴趣的:(XRP-瑞波币-交易解析)