Jingtum Serializer 井通区块链系统中有两类对象, 一类是交易对象TRANSACTION_TYPE,以下简写为TXT,一类是账本对象LEDGER_ENTRY_TYPE,以下简写为LET。系统中所有交易为TXT,通过交易修改井通账本中的LET。 每个TXT和LET由一个个字段构成,同时不同的TXT具有部分共同的字段,每个字段包括字段名称,以及字段标记,即是可选的还是必备的。LET同理。每个TXT和LET及其字段具有英文字母表示,而且每个字母在所有交易中基本是重复的,需要提供一个映射方式将字段名称进行编码,减少提交的交易数据大小,此过程称为序列化,同时也需要将序列化的数据反序列化,给用户提供完整的TXT或者LET信息。 // 数据类型编码 var TYPES_MAP = [ void(0), // Common 'Int16', // 1 'Int32', // 2 'Int64', // 3 'Hash128', // 4 'Hash256', // 5 'Amount', // 6 'VL', // 7 'Account', // 8 // 9-13 reserved void(0), // 9 void(0), // 10 void(0), // 11 void(0), // 12 void(0), // 13 'Object', // 14 'Array', // 15 // Uncommon 'Int8', // 16 'Hash160', // 17 'PathSet', // 18 'Vector256' // 19 // 字段类型编码,第一个数字是数字,第二个数字是同一类型下面的编码 var FIELDS_MAP = { // Common types 1: { // Int16 1: 'LedgerEntryType', 2: 'TransactionType' }, 2: { // Int32 2: 'Flags', 3: 'SourceTag', 4: 'Sequence', 5: 'PreviousTxnLgrSeq', 6: 'LedgerSequence', 7: 'CloseTime', 8: 'ParentCloseTime', 9: 'SigningTime', 10: 'Expiration', 11: 'TransferRate', 12: 'WalletSize', 13: 'OwnerCount', 14: 'DestinationTag', // Skip 15 16: 'HighQualityIn', 17: 'HighQualityOut', 18: 'LowQualityIn', 19: 'LowQualityOut', 20: 'QualityIn', 21: 'QualityOut', 22: 'StampEscrow', 23: 'BondAmount', 24: 'LoadFee', 25: 'OfferSequence', 26: 'FirstLedgerSequence', 27: 'LastLedgerSequence', 28: 'TransactionIndex', 29: 'OperationLimit', 30: 'ReferenceFeeUnits', 31: 'ReserveBase', 32: 'ReserveIncrement', 33: 'SetFlag', 34: 'ClearFlag' }, 3: { // Int64 1: 'IndexNext', 2: 'IndexPrevious', 3: 'BookNode', 4: 'OwnerNode', 5: 'BaseFee', 6: 'ExchangeRate', 7: 'LowNode', 8: 'HighNode' }, 4: { // Hash128 1: 'EmailHash' }, 5: { // Hash256 1: 'LedgerHash', 2: 'ParentHash', 3: 'TransactionHash', 4: 'AccountHash', 5: 'PreviousTxnID', 6: 'LedgerIndex', 7: 'WalletLocator', 8: 'RootIndex', 9: 'AccountTxnID', 16: 'BookDirectory', 17: 'InvoiceID', 18: 'Nickname', 19: 'Amendment', 20: 'TicketID' }, 6: { // Amount 1: 'Amount', 2: 'Balance', 3: 'LimitAmount', 4: 'TakerPays', 5: 'TakerGets', 6: 'LowLimit', 7: 'HighLimit', 8: 'Fee', 9: 'SendMax', 16: 'MinimumOffer', 17: 'JingtumEscrow', 18: 'DeliveredAmount' }, 7: { // VL 1: 'PublicKey', 2: 'MessageKey', 3: 'SigningPubKey', 4: 'TxnSignature', 5: 'Generator', 6: 'Signature', 7: 'Domain', 8: 'FundCode', 9: 'RemoveCode', 10: 'ExpireCode', 11: 'CreateCode', 12: 'MemoType', 13: 'MemoData', 14: 'MemoFormat' }, 8: { // Account 1: 'Account', 2: 'Owner', 3: 'Destination', 4: 'Issuer', 7: 'Target', 8: 'RegularKey' }, 14: { // Object 1: void(0), //end of Object 2: 'TransactionMetaData', 3: 'CreatedNode', 4: 'DeletedNode', 5: 'ModifiedNode', 6: 'PreviousFields', 7: 'FinalFields', 8: 'NewFields', 9: 'TemplateEntry', 10: 'Memo' }, 15: { // Array 1: void(0), //end of Array 2: 'SigningAccounts', 3: 'TxnSignatures', 4: 'Signatures', 5: 'Template', 6: 'Necessary', 7: 'Sufficient', 8: 'AffectedNodes', 9: 'Memos' }, // Uncommon types 16: { // Int8 1: 'CloseResolution', 2: 'TemplateEntryType', 3: 'TransactionResult' }, 17: { // Hash160 1: 'TakerPaysCurrency', 2: 'TakerPaysIssuer', 3: 'TakerGetsCurrency', 4: 'TakerGetsIssuer' }, 18: { // PathSet 1: 'Paths' }, 19: { // Vector256 1: 'Indexes', 2: 'Hashes', 3: 'Amendments' } } // 反向字段类型编码以及字段编码 var INVERSE_FIELDS_MAP = { LedgerEntryType: [1, 1], TransactionType: [1, 2], Flags: [2, 2], SourceTag: [2, 3], Sequence: [2, 4], PreviousTxnLgrSeq: [2, 5], LedgerSequence: [2, 6], CloseTime: [2, 7], ParentCloseTime: [2, 8], SigningTime: [2, 9], Expiration: [2, 10], TransferRate: [2, 11], WalletSize: [2, 12], OwnerCount: [2, 13], DestinationTag: [2, 14], HighQualityIn: [2, 16], HighQualityOut: [2, 17], LowQualityIn: [2, 18], LowQualityOut: [2, 19], QualityIn: [2, 20], QualityOut: [2, 21], StampEscrow: [2, 22], BondAmount: [2, 23], LoadFee: [2, 24], OfferSequence: [2, 25], FirstLedgerSequence: [2, 26], LastLedgerSequence: [2, 27], TransactionIndex: [2, 28], OperationLimit: [2, 29], ReferenceFeeUnits: [2, 30], ReserveBase: [2, 31], ReserveIncrement: [2, 32], SetFlag: [2, 33], ClearFlag: [2, 34], IndexNext: [3, 1], IndexPrevious: [3, 2], BookNode: [3, 3], OwnerNode: [3, 4], BaseFee: [3, 5], ExchangeRate: [3, 6], LowNode: [3, 7], HighNode: [3, 8], EmailHash: [4, 1], LedgerHash: [5, 1], ParentHash: [5, 2], TransactionHash: [5, 3], AccountHash: [5, 4], PreviousTxnID: [5, 5], LedgerIndex: [5, 6], WalletLocator: [5, 7], RootIndex: [5, 8], AccountTxnID: [5, 9], BookDirectory: [5, 16], InvoiceID: [5, 17], Nickname: [5, 18], Amendment: [5, 19], TicketID: [5, 20], Amount: [6, 1], Balance: [6, 2], LimitAmount: [6, 3], TakerPays: [6, 4], TakerGets: [6, 5], LowLimit: [6, 6], HighLimit: [6, 7], Fee: [6, 8], SendMax: [6, 9], MinimumOffer: [6, 16], JingtumEscrow: [6, 17], DeliveredAmount: [6, 18], PublicKey: [7, 1], MessageKey: [7, 2], SigningPubKey: [7, 3], TxnSignature: [7, 4], Generator: [7, 5], Signature: [7, 6], Domain: [7, 7], FundCode: [7, 8], RemoveCode: [7, 9], ExpireCode: [7, 10], CreateCode: [7, 11], MemoType: [7, 12], MemoData: [7, 13], MemoFormat: [7, 14], Account: [8, 1], Owner: [8, 2], Destination: [8, 3], Issuer: [8, 4], Target: [8, 7], RegularKey: [8, 8], undefined: [15, 1], TransactionMetaData: [14, 2], CreatedNode: [14, 3], DeletedNode: [14, 4], ModifiedNode: [14, 5], PreviousFields: [14, 6], FinalFields: [14, 7], NewFields: [14, 8], TemplateEntry: [14, 9], Memo: [14, 10], SigningAccounts: [15, 2], TxnSignatures: [15, 3], Signatures: [15, 4], Template: [15, 5], Necessary: [15, 6], Sufficient: [15, 7], AffectedNodes: [15, 8], Memos: [15, 9], CloseResolution: [16, 1], TemplateEntryType: [16, 2], TransactionResult: [16, 3], TakerPaysCurrency: [17, 1], TakerPaysIssuer: [17, 2], TakerGetsCurrency: [17, 3], TakerGetsIssuer: [17, 4], Paths: [18, 1], Indexes: [19, 1], Hashes: [19, 2], Amendments: [19, 3] } // 字段标志 var REQUIRED = 0, OPTIONAL = 1, DEFAULT = 2; // 交易必备字段 var base = [ ['TransactionType', REQUIRED], ['Flags', OPTIONAL], ['SourceTag', OPTIONAL], ['LastLedgerSequence', OPTIONAL], ['Account', REQUIRED], ['Sequence', OPTIONAL], ['Fee', REQUIRED], ['OperationLimit', OPTIONAL], ['SigningPubKey', OPTIONAL], ['TxnSignature', OPTIONAL] // 各个交易类型的内容,其中第一个[]中的内容是交易类型编码 var TRANSACTION_TYPES = { AccountSet: [3].concat(base, [ ['EmailHash', OPTIONAL], ['WalletLocator', OPTIONAL], ['WalletSize', OPTIONAL], ['MessageKey', OPTIONAL], ['Domain', OPTIONAL], ['TransferRate', OPTIONAL] ]), TrustSet: [20].concat(base, [ ['LimitAmount', OPTIONAL], ['QualityIn', OPTIONAL], ['QualityOut', OPTIONAL] ]), OfferCreate: [7].concat(base, [ ['TakerPays', REQUIRED], ['TakerGets', REQUIRED], ['Expiration', OPTIONAL] ]), OfferCancel: [8].concat(base, [ ['OfferSequence', REQUIRED] ]), SetRegularKey: [5].concat(base, [ ['RegularKey', REQUIRED] ]), Payment: [0].concat(base, [ ['Destination', REQUIRED], ['Amount', REQUIRED], ['SendMax', OPTIONAL], ['Paths', DEFAULT], ['InvoiceID', OPTIONAL], ['DestinationTag', OPTIONAL] ]), Contract: [9].concat(base, [ ['Expiration', REQUIRED], ['BondAmount', REQUIRED], ['StampEscrow', REQUIRED], ['JingtumEscrow', REQUIRED], ['CreateCode', OPTIONAL], ['FundCode', OPTIONAL], ['RemoveCode', OPTIONAL], ['ExpireCode', OPTIONAL] ]), RemoveContract: [10].concat(base, [ ['Target', REQUIRED] ]), EnableFeature: [100].concat(base, [ ['Feature', REQUIRED] ]), SetFee: [101].concat(base, [ ['Features', REQUIRED], ['BaseFee', REQUIRED], ['ReferenceFeeUnits', REQUIRED], ['ReserveBase', REQUIRED], ['ReserveIncrement', REQUIRED] ]) } // 账本项目必备字段 var sleBase = [ ['LedgerIndex', OPTIONAL], ['LedgerEntryType', REQUIRED], ['Flags', REQUIRED] // 各个账本项目内容 var LEDGER_ENTRY_TYPES = { AccountRoot: [97].concat(sleBase, [ ['Sequence', REQUIRED], ['PreviousTxnLgrSeq', REQUIRED], ['TransferRate', OPTIONAL], ['WalletSize', OPTIONAL], ['OwnerCount', REQUIRED], ['EmailHash', OPTIONAL], ['PreviousTxnID', REQUIRED], ['AccountTxnID', OPTIONAL], ['WalletLocator', OPTIONAL], ['Balance', REQUIRED], ['MessageKey', OPTIONAL], ['Domain', OPTIONAL], ['Account', REQUIRED], ['RegularKey', OPTIONAL]]), Contract: [99].concat(sleBase, [ ['PreviousTxnLgrSeq', REQUIRED], ['Expiration', REQUIRED], ['BondAmount', REQUIRED], ['PreviousTxnID', REQUIRED], ['Balance', REQUIRED], ['FundCode', OPTIONAL], ['RemoveCode', OPTIONAL], ['ExpireCode', OPTIONAL], ['CreateCode', OPTIONAL], ['Account', REQUIRED], ['Owner', REQUIRED], ['Issuer', REQUIRED]]), DirectoryNode: [100].concat(sleBase, [ ['IndexNext', OPTIONAL], ['IndexPrevious', OPTIONAL], ['ExchangeRate', OPTIONAL], ['RootIndex', REQUIRED], ['Owner', OPTIONAL], ['TakerPaysCurrency', OPTIONAL], ['TakerPaysIssuer', OPTIONAL], ['TakerGetsCurrency', OPTIONAL], ['TakerGetsIssuer', OPTIONAL], ['Indexes', REQUIRED]]), EnabledFeatures: [102].concat(sleBase, [ ['Features', REQUIRED]]), FeeSettings: [115].concat(sleBase, [ ['ReferenceFeeUnits', REQUIRED], ['ReserveBase', REQUIRED], ['ReserveIncrement', REQUIRED], ['BaseFee', REQUIRED], ['LedgerIndex', OPTIONAL]]), GeneratorMap: [103].concat(sleBase, [ ['Generator', REQUIRED]]), LedgerHashes: [104].concat(sleBase, [ ['LedgerEntryType', REQUIRED], ['Flags', REQUIRED], ['FirstLedgerSequence', OPTIONAL], ['LastLedgerSequence', OPTIONAL], ['LedgerIndex', OPTIONAL], ['Hashes', REQUIRED]]), Nickname: [110].concat(sleBase, [ ['LedgerEntryType', REQUIRED], ['Flags', REQUIRED], ['LedgerIndex', OPTIONAL], ['MinimumOffer', OPTIONAL], ['Account', REQUIRED]]), Offer: [111].concat(sleBase, [ ['LedgerEntryType', REQUIRED], ['Flags', REQUIRED], ['Sequence', REQUIRED], ['PreviousTxnLgrSeq', REQUIRED], ['Expiration', OPTIONAL], ['BookNode', REQUIRED], ['OwnerNode', REQUIRED], ['PreviousTxnID', REQUIRED], ['LedgerIndex', OPTIONAL], ['BookDirectory', REQUIRED], ['TakerPays', REQUIRED], ['TakerGets', REQUIRED], ['Account', REQUIRED]]), SkywellState: [114].concat(sleBase, [ ['LedgerEntryType', REQUIRED], ['Flags', REQUIRED], ['PreviousTxnLgrSeq', REQUIRED], ['HighQualityIn', OPTIONAL], ['HighQualityOut', OPTIONAL], ['LowQualityIn', OPTIONAL], ['LowQualityOut', OPTIONAL], ['LowNode', OPTIONAL], ['HighNode', OPTIONAL], ['PreviousTxnID', REQUIRED], ['LedgerIndex', OPTIONAL], ['Balance', REQUIRED], ['LowLimit', REQUIRED], ['HighLimit', REQUIRED]]) } 为了进行序列化,系统对所有用到的字段进行编码,也包括对各个TXT和LET进行编码。 例子: 账号: account = { address: "jB7rxgh43ncbTX4WeMoeadiGMfmfqY2xLZ", secret: "sn37nYrQ6KPJvTFmaBYokS3FjXUWd" } 支付交易: tx = { "Account": account.address, "Amount": { value: "0.000001", currency: "CNY", issuer: "jBciDE8Q3uJjf111VeiUNM775AMKHEbBLS" }, "Fee" : "0.00001", "Flags" : 0, "Sequence" : 10, "TransactionType" : "Payment" }
下面描述序列化过程: 1、获得交易发起账号的公钥,并将公钥附加到tx里面; tx = { "Account": account.address, "Amount": { value: "0.000001", currency: "CNY", issuer: "jBciDE8Q3uJjf111VeiUNM775AMKHEbBLS" }, "Fee" : "0.00001", "Flags" : 0, "Sequence" : 10, "TransactionType" : "Payment", "SigningPubKey": "02FE64E0C20F0058F22F3742EDC15F49F318C04F88B130742C68BAF3B1C89FD167" } 2、将所有交易字段进行排序,其中小写字母的字段不参与 var keys = ["Account", "Amount", "Fee", "Flags", "Sequence", "TransactionType", "SigningPubKey"] 3、针对每个字段进行序列化操作 var so = Serializer; so添加各个字段序列化的内容,需要实现各个字段类型的序列化方法。 每个字段序列化过程为: 1) 获得类型编码、字段编码,并将二者组合成一个Int8的数据,首先序列化到序列化对象中; 2) 根据每种不同的字段类型,序列化对应的值到序列化对象中。
|