UNPKG

9.18 kBJavaScriptView Raw
1"use strict";
2/* tslint:disable:no-shadowed-variable */
3var __importDefault = (this && this.__importDefault) || function (mod) {
4 return (mod && mod.__esModule) ? mod : { "default": mod };
5};
6Object.defineProperty(exports, "__esModule", { value: true });
7const bs58check_1 = __importDefault(require("bs58check"));
8const bytebuffer_1 = __importDefault(require("bytebuffer"));
9const __1 = require("..");
10const enums_1 = require("../enums");
11const errors_1 = require("../errors");
12const identities_1 = require("../identities");
13const managers_1 = require("../managers");
14const types_1 = require("./types");
15// Reference: https://github.com/ArkEcosystem/AIPs/blob/master/AIPS/aip-11.md
16class Serializer {
17 static getBytes(transaction, options) {
18 const version = transaction.version || 1;
19 if (version === 1) {
20 return this.getBytesV1(transaction, options);
21 }
22 else if (version === 2 && managers_1.configManager.getMilestone().aip11) {
23 return this.getBytesV2(transaction, options);
24 }
25 else {
26 throw new errors_1.TransactionVersionError(version);
27 }
28 }
29 /**
30 * Serializes the given transaction according to AIP11.
31 */
32 static serialize(transaction, options = {}) {
33 const buffer = new bytebuffer_1.default(512, true);
34 this.serializeCommon(transaction.data, buffer);
35 this.serializeVendorField(transaction, buffer);
36 const typeBuffer = transaction.serialize(options).flip();
37 buffer.append(typeBuffer);
38 this.serializeSignatures(transaction.data, buffer, options);
39 const flippedBuffer = buffer.flip().toBuffer();
40 transaction.serialized = flippedBuffer;
41 return flippedBuffer;
42 }
43 /**
44 * Serializes the given transaction prior to AIP11 (legacy).
45 */
46 static getBytesV1(transaction, options = {}) {
47 let assetSize = 0;
48 let assetBytes;
49 switch (transaction.type) {
50 case enums_1.TransactionTypes.SecondSignature: {
51 const { signature } = transaction.asset;
52 const bb = new bytebuffer_1.default(33, true);
53 const publicKeyBuffer = Buffer.from(signature.publicKey, "hex");
54 for (const byte of publicKeyBuffer) {
55 bb.writeByte(byte);
56 }
57 bb.flip();
58 assetBytes = new Uint8Array(bb.toArrayBuffer());
59 assetSize = assetBytes.length;
60 break;
61 }
62 case enums_1.TransactionTypes.DelegateRegistration: {
63 assetBytes = Buffer.from(transaction.asset.delegate.username, "utf8");
64 assetSize = assetBytes.length;
65 break;
66 }
67 case enums_1.TransactionTypes.Vote: {
68 if (transaction.asset.votes) {
69 assetBytes = Buffer.from(transaction.asset.votes.join(""), "utf8");
70 assetSize = assetBytes.length;
71 }
72 break;
73 }
74 case enums_1.TransactionTypes.MultiSignature: {
75 const keysgroupBuffer = Buffer.from(transaction.asset.multiSignatureLegacy.keysgroup.join(""), "utf8");
76 const bb = new bytebuffer_1.default(1 + 1 + keysgroupBuffer.length, true);
77 bb.writeByte(transaction.asset.multiSignatureLegacy.min);
78 bb.writeByte(transaction.asset.multiSignatureLegacy.lifetime);
79 for (const byte of keysgroupBuffer) {
80 bb.writeByte(byte);
81 }
82 bb.flip();
83 assetBytes = bb.toBuffer();
84 assetSize = assetBytes.length;
85 break;
86 }
87 }
88 const bb = new bytebuffer_1.default(1 + 4 + 32 + 8 + 8 + 21 + 64 + 64 + 64 + assetSize, true);
89 bb.writeByte(transaction.type);
90 bb.writeInt(transaction.timestamp);
91 const senderPublicKeyBuffer = Buffer.from(transaction.senderPublicKey, "hex");
92 for (const byte of senderPublicKeyBuffer) {
93 bb.writeByte(byte);
94 }
95 // Apply fix for broken type 1 and 4 transactions, which were
96 // erroneously calculated with a recipient id.
97 const { transactionIdFixTable } = managers_1.configManager.get("exceptions");
98 const isBrokenTransaction = transactionIdFixTable && Object.values(transactionIdFixTable).includes(transaction.id);
99 if (isBrokenTransaction || (transaction.recipientId && transaction.type !== 1 && transaction.type !== 4)) {
100 const recipientId = transaction.recipientId || identities_1.Address.fromPublicKey(transaction.senderPublicKey, transaction.network);
101 const recipient = bs58check_1.default.decode(recipientId);
102 for (const byte of recipient) {
103 bb.writeByte(byte);
104 }
105 }
106 else {
107 for (let i = 0; i < 21; i++) {
108 bb.writeByte(0);
109 }
110 }
111 if (transaction.vendorFieldHex) {
112 const vf = Buffer.from(transaction.vendorFieldHex, "hex");
113 const fillstart = vf.length;
114 for (let i = 0; i < fillstart; i++) {
115 bb.writeByte(vf[i]);
116 }
117 for (let i = fillstart; i < 64; i++) {
118 bb.writeByte(0);
119 }
120 }
121 else if (transaction.vendorField) {
122 const vf = Buffer.from(transaction.vendorField);
123 const fillstart = vf.length;
124 for (let i = 0; i < fillstart; i++) {
125 bb.writeByte(vf[i]);
126 }
127 for (let i = fillstart; i < 64; i++) {
128 bb.writeByte(0);
129 }
130 }
131 else {
132 for (let i = 0; i < 64; i++) {
133 bb.writeByte(0);
134 }
135 }
136 bb.writeInt64(+transaction.amount.toFixed());
137 bb.writeInt64(+transaction.fee.toFixed());
138 if (assetSize > 0) {
139 for (let i = 0; i < assetSize; i++) {
140 bb.writeByte(assetBytes[i]);
141 }
142 }
143 if (!options.excludeSignature && transaction.signature) {
144 const signatureBuffer = Buffer.from(transaction.signature, "hex");
145 for (const byte of signatureBuffer) {
146 bb.writeByte(byte);
147 }
148 }
149 if (!options.excludeSecondSignature && transaction.secondSignature) {
150 const signSignatureBuffer = Buffer.from(transaction.secondSignature, "hex");
151 for (const byte of signSignatureBuffer) {
152 bb.writeByte(byte);
153 }
154 }
155 bb.flip();
156 const arrayBuffer = new Uint8Array(bb.toArrayBuffer());
157 const buffer = [];
158 for (let i = 0; i < arrayBuffer.length; i++) {
159 buffer[i] = arrayBuffer[i];
160 }
161 return Buffer.from(buffer);
162 }
163 static getBytesV2(transaction, options = {}) {
164 return this.serialize(types_1.TransactionTypeFactory.create(transaction), options);
165 }
166 static serializeCommon(transaction, buffer) {
167 buffer.writeByte(0xff); // fill, to disambiguate from v1
168 buffer.writeByte(transaction.version || 0x01); // version
169 buffer.writeByte(transaction.network || managers_1.configManager.get("network.pubKeyHash")); // ark = 0x17, devnet = 0x30
170 buffer.writeByte(transaction.type);
171 buffer.writeUint32(transaction.timestamp);
172 buffer.append(transaction.senderPublicKey, "hex");
173 buffer.writeUint64(+transaction.fee);
174 }
175 static serializeVendorField(transaction, buffer) {
176 if (transaction.hasVendorField()) {
177 const { data } = transaction;
178 if (data.vendorField) {
179 const vf = Buffer.from(data.vendorField, "utf8");
180 buffer.writeByte(vf.length);
181 buffer.append(vf);
182 }
183 else if (data.vendorFieldHex) {
184 buffer.writeByte(data.vendorFieldHex.length / 2);
185 buffer.append(data.vendorFieldHex, "hex");
186 }
187 else {
188 buffer.writeByte(0x00);
189 }
190 }
191 else {
192 buffer.writeByte(0x00);
193 }
194 }
195 static serializeSignatures(transaction, buffer, options = {}) {
196 if (transaction.signature && !options.excludeSignature) {
197 buffer.append(transaction.signature, "hex");
198 }
199 const secondSignature = transaction.secondSignature || transaction.signSignature;
200 if (secondSignature && !options.excludeSecondSignature) {
201 buffer.append(secondSignature, "hex");
202 }
203 if (transaction.signatures) {
204 if (transaction.version === 1 && __1.Utils.isException(transaction)) {
205 buffer.append("ff", "hex"); // 0xff separator to signal start of multi-signature transactions
206 buffer.append(transaction.signatures.join(""), "hex");
207 }
208 else if (!options.excludeMultiSignature) {
209 buffer.append(transaction.signatures.join(""), "hex");
210 }
211 }
212 }
213}
214exports.Serializer = Serializer;
215//# sourceMappingURL=serializer.js.map
\No newline at end of file