1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const bytebuffer_1 = __importDefault(require("bytebuffer"));
|
7 | const enums_1 = require("../enums");
|
8 | const errors_1 = require("../errors");
|
9 | const identities_1 = require("../identities");
|
10 | const managers_1 = require("../managers");
|
11 | const utils_1 = require("../utils");
|
12 | const types_1 = require("./types");
|
13 |
|
14 | class Deserializer {
|
15 | deserialize(serialized) {
|
16 | const data = {};
|
17 | const buffer = this.getByteBuffer(serialized);
|
18 | this.deserializeCommon(data, buffer);
|
19 | const instance = types_1.TransactionTypeFactory.create(data);
|
20 | this.deserializeVendorField(instance, buffer);
|
21 |
|
22 | instance.deserialize(buffer);
|
23 | this.deserializeSignatures(data, buffer);
|
24 | if (data.version === 1) {
|
25 | this.applyV1Compatibility(data);
|
26 | }
|
27 | else if (data.version === 2 && managers_1.configManager.getMilestone().aip11) {
|
28 |
|
29 | }
|
30 | else {
|
31 | throw new errors_1.TransactionVersionError(data.version);
|
32 | }
|
33 | instance.serialized = buffer.flip().toBuffer();
|
34 | return instance;
|
35 | }
|
36 | deserializeCommon(transaction, buf) {
|
37 | buf.skip(1);
|
38 | transaction.version = buf.readUint8();
|
39 | transaction.network = buf.readUint8();
|
40 | transaction.type = buf.readUint8();
|
41 | transaction.timestamp = buf.readUint32();
|
42 | transaction.senderPublicKey = buf.readBytes(33).toString("hex");
|
43 | transaction.fee = utils_1.BigNumber.make(buf.readUint64().toString());
|
44 | transaction.amount = utils_1.BigNumber.ZERO;
|
45 | }
|
46 | deserializeVendorField(transaction, buf) {
|
47 | const vendorFieldLength = buf.readUint8();
|
48 | if (vendorFieldLength > 0) {
|
49 | if (transaction.hasVendorField()) {
|
50 | transaction.data.vendorFieldHex = buf.readBytes(vendorFieldLength).toString("hex");
|
51 | }
|
52 | else {
|
53 | buf.skip(vendorFieldLength);
|
54 | }
|
55 | }
|
56 | }
|
57 | deserializeSignatures(transaction, buf) {
|
58 | if (transaction.version === 1) {
|
59 | this.deserializeECDSA(transaction, buf);
|
60 | }
|
61 | else if (transaction.version === 2) {
|
62 | this.deserializeSchnorr(transaction, buf);
|
63 | }
|
64 | }
|
65 | deserializeECDSA(transaction, buf) {
|
66 | const currentSignatureLength = () => {
|
67 | buf.mark();
|
68 | const lengthHex = buf
|
69 | .skip(1)
|
70 | .readBytes(1)
|
71 | .toString("hex");
|
72 | buf.reset();
|
73 | return parseInt(lengthHex, 16) + 2;
|
74 | };
|
75 |
|
76 | if (buf.remaining()) {
|
77 | const signatureLength = currentSignatureLength();
|
78 | transaction.signature = buf.readBytes(signatureLength).toString("hex");
|
79 | }
|
80 | const beginningMultiSignature = () => {
|
81 | buf.mark();
|
82 | const marker = buf.readUint8();
|
83 | buf.reset();
|
84 | return marker === 255;
|
85 | };
|
86 |
|
87 | if (buf.remaining() && !beginningMultiSignature()) {
|
88 | const secondSignatureLength = currentSignatureLength();
|
89 | transaction.secondSignature = buf.readBytes(secondSignatureLength).toString("hex");
|
90 | }
|
91 |
|
92 | if (buf.remaining() && beginningMultiSignature()) {
|
93 | buf.skip(1);
|
94 | const multiSignature = buf.readBytes(buf.limit - buf.offset).toString("hex");
|
95 | transaction.signatures = [multiSignature];
|
96 | }
|
97 | if (buf.remaining()) {
|
98 | throw new errors_1.MalformedTransactionBytesError();
|
99 | }
|
100 | }
|
101 | deserializeSchnorr(transaction, buf) {
|
102 | const canReadNonMultiSignature = () => {
|
103 | return buf.remaining() && (buf.remaining() % 64 === 0 || buf.remaining() % 65 !== 0);
|
104 | };
|
105 | if (canReadNonMultiSignature()) {
|
106 | transaction.signature = buf.readBytes(64).toString("hex");
|
107 | }
|
108 | if (canReadNonMultiSignature()) {
|
109 | transaction.secondSignature = buf.readBytes(64).toString("hex");
|
110 | }
|
111 | if (buf.remaining()) {
|
112 | if (buf.remaining() % 65 === 0) {
|
113 | transaction.signatures = [];
|
114 | const count = buf.remaining() / 65;
|
115 | for (let i = 0; i < count; i++) {
|
116 | const multiSignaturePart = buf.readBytes(65).toString("hex");
|
117 | transaction.signatures.push(multiSignaturePart);
|
118 | }
|
119 | }
|
120 | else {
|
121 | throw new errors_1.MalformedTransactionBytesError();
|
122 | }
|
123 | }
|
124 | }
|
125 |
|
126 | applyV1Compatibility(transaction) {
|
127 | transaction.secondSignature = transaction.secondSignature || transaction.signSignature;
|
128 | if (transaction.type === enums_1.TransactionTypes.Vote) {
|
129 | transaction.recipientId = identities_1.Address.fromPublicKey(transaction.senderPublicKey, transaction.network);
|
130 | }
|
131 | else if (transaction.type === enums_1.TransactionTypes.MultiSignature) {
|
132 | transaction.asset.multiSignatureLegacy.keysgroup = transaction.asset.multiSignatureLegacy.keysgroup.map(k => k.startsWith("+") ? k : `+${k}`);
|
133 | }
|
134 | if (transaction.vendorFieldHex) {
|
135 | transaction.vendorField = Buffer.from(transaction.vendorFieldHex, "hex").toString("utf8");
|
136 | }
|
137 | }
|
138 | getByteBuffer(serialized) {
|
139 | if (!(serialized instanceof Buffer)) {
|
140 | serialized = Buffer.from(serialized, "hex");
|
141 | }
|
142 | const buffer = new bytebuffer_1.default(serialized.length, true);
|
143 | buffer.append(serialized);
|
144 | buffer.reset();
|
145 | return buffer;
|
146 | }
|
147 | }
|
148 | exports.deserializer = new Deserializer();
|
149 |
|
\ | No newline at end of file |