-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathoutput.js
130 lines (105 loc) · 3.16 KB
/
output.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* Copyright (c) 2018-present, Leap DAO (leapdao.org)
*
* This source code is licensed under the GNU Affero General Public License,
* version 3, found in the LICENSE file in the root directory of this source
* tree.
*/
import assert from 'assert';
import Util from './util';
// 32 bytes - value, 20 bytes - address, 2 bytes color
export const OUT_LENGTH = 54;
// 32 - data, + normal output like above
export const NST_OUT_LENGTH = OUT_LENGTH + 32;
export const MAX_COLOR = 2 ** 16;
const valueHex = value => BigInt(value).toString(16);
export default class Output {
constructor(valueOrObject, address, color, data) {
if (typeof valueOrObject === 'object') {
Util.ensureSafeValue(valueOrObject.value);
this.value = BigInt(valueOrObject.value);
this.color = valueOrObject.color || 0;
this.address = valueOrObject.address;
if (this.isNST()) {
this.data = valueOrObject.data;
}
} else {
Util.ensureSafeValue(valueOrObject);
this.value = BigInt(valueOrObject);
this.address = address;
this.color = color || 0;
if (this.isNST()) {
this.data = data;
}
}
if (!this.isNFT() && !this.isNST() && this.value < 1n) {
throw new Error('Output value is < 1');
}
if (this.color < 0 || this.color > MAX_COLOR) {
throw new Error(`Color out of range (0–${MAX_COLOR})`);
}
if (this.isNST() && !Util.isBytes32(this.data)) {
throw new Error('data is not a 32 bytes hex string');
}
}
isNFT() {
return Util.isNFT(this.color);
}
isNST() {
return Util.isNST(this.color);
}
/* eslint-disable class-methods-use-this */
getSize() {
// transfer output
return this.isNST() ? NST_OUT_LENGTH : OUT_LENGTH;
}
/* eslint-enable class-methods-use-this */
toJSON() {
const rsp = {
address: this.address,
value: this.value.toString(10),
color: this.color,
};
if (this.isNST()) {
rsp.data = this.data;
}
return rsp;
}
/**
* Instantiate output from json object.
* @param {Object} json
* @returns {Outpoint}
*/
static fromJSON(json) {
assert(json, 'Output data is required.');
return new Output(json);
}
/**
* Instantiate output from serialized data.
* @param {Buffer} data
* @param {offset} offset to read from in buffer
* @returns {Output}
*/
static fromRaw(buf, offset = 0) {
const color = buf.readUInt16BE(offset + 32);
const valueString = Util.toHexString(buf.slice(offset, offset + 32));
const value = BigInt(valueString);
const address = Util.toHexString(buf.slice(offset + 34, offset + 54));
let data;
if (Util.isNST(color)) {
data = Util.toHexString(buf.slice(offset + 54, offset + 54 + 32));
}
// transfer output
return new Output(value, address, color, data);
}
toRaw() {
const dataBuf = Buffer.alloc(this.getSize());
dataBuf.write(valueHex(this.value).padStart(64, '0'), 0, 32, 'hex');
dataBuf.writeUInt16BE(this.color, 32);
dataBuf.write(this.address.replace('0x', ''), 34, 'hex');
if (this.isNST()) {
dataBuf.write(this.data.replace('0x', ''), 54, 'hex');
}
return dataBuf;
}
}