UNPKG

4.27 kBJavaScriptView Raw
1'use strict';
2
3var _ = require('lodash');
4var BN = require('../crypto/bn');
5var buffer = require('buffer');
6var bufferUtil = require('../util/buffer');
7var JSUtil = require('../util/js');
8var BufferWriter = require('../encoding/bufferwriter');
9var Script = require('../script');
10var $ = require('../util/preconditions');
11var errors = require('../errors');
12
13var MAX_SAFE_INTEGER = 0x1fffffffffffff;
14
15function Output(args) {
16 if (!(this instanceof Output)) {
17 return new Output(args);
18 }
19 if (_.isObject(args)) {
20 this.satoshis = args.satoshis;
21 if (bufferUtil.isBuffer(args.script)) {
22 this._scriptBuffer = args.script;
23 } else {
24 var script;
25 if (_.isString(args.script) && JSUtil.isHexa(args.script)) {
26 script = Buffer.from(args.script, 'hex');
27 } else {
28 script = args.script;
29 }
30 this.setScript(script);
31 }
32 } else {
33 throw new TypeError('Unrecognized argument for Output');
34 }
35}
36
37Object.defineProperty(Output.prototype, 'script', {
38 configurable: false,
39 enumerable: true,
40 get: function() {
41 if (this._script) {
42 return this._script;
43 } else {
44 this.setScriptFromBuffer(this._scriptBuffer);
45 return this._script;
46 }
47
48 }
49});
50
51Object.defineProperty(Output.prototype, 'satoshis', {
52 configurable: false,
53 enumerable: true,
54 get: function() {
55 return this._satoshis;
56 },
57 set: function(num) {
58 if (num instanceof BN) {
59 this._satoshisBN = num;
60 this._satoshis = num.toNumber();
61 } else if (_.isString(num)) {
62 this._satoshis = parseInt(num);
63 this._satoshisBN = BN.fromNumber(this._satoshis);
64 } else {
65 $.checkArgument(
66 JSUtil.isNaturalNumber(num),
67 'Output satoshis is not a natural number'
68 );
69 this._satoshisBN = BN.fromNumber(num);
70 this._satoshis = num;
71 }
72 $.checkState(
73 JSUtil.isNaturalNumber(this._satoshis),
74 'Output satoshis is not a natural number'
75 );
76 }
77});
78
79Output.prototype.invalidSatoshis = function() {
80 if (this._satoshis > MAX_SAFE_INTEGER) {
81 return 'transaction txout satoshis greater than max safe integer';
82 }
83 if (this._satoshis !== this._satoshisBN.toNumber()) {
84 return 'transaction txout satoshis has corrupted value';
85 }
86 if (this._satoshis < 0) {
87 return 'transaction txout negative';
88 }
89 return false;
90};
91
92Output.prototype.toObject = Output.prototype.toJSON = function toObject() {
93 var obj = {
94 satoshis: this.satoshis
95 };
96 obj.script = this._scriptBuffer.toString('hex');
97 return obj;
98};
99
100Output.fromObject = function(data) {
101 return new Output(data);
102};
103
104Output.prototype.setScriptFromBuffer = function(buffer) {
105 this._scriptBuffer = buffer;
106 try {
107 this._script = Script.fromBuffer(this._scriptBuffer);
108 this._script._isOutput = true;
109 } catch(e) {
110 if (e instanceof errors.Script.InvalidBuffer) {
111 this._script = null;
112 } else {
113 throw e;
114 }
115 }
116};
117
118Output.prototype.setScript = function(script) {
119 if (script instanceof Script) {
120 this._scriptBuffer = script.toBuffer();
121 this._script = script;
122 this._script._isOutput = true;
123 } else if (_.isString(script)) {
124 this._script = Script.fromString(script);
125 this._scriptBuffer = this._script.toBuffer();
126 this._script._isOutput = true;
127 } else if (bufferUtil.isBuffer(script)) {
128 this.setScriptFromBuffer(script);
129 } else {
130 throw new TypeError('Invalid argument type: script');
131 }
132 return this;
133};
134
135Output.prototype.inspect = function() {
136 var scriptStr;
137 if (this.script) {
138 scriptStr = this.script.inspect();
139 } else {
140 scriptStr = this._scriptBuffer.toString('hex');
141 }
142 return '<Output (' + this.satoshis + ' sats) ' + scriptStr + '>';
143};
144
145Output.fromBufferReader = function(br) {
146 var obj = {};
147 obj.satoshis = br.readUInt64LEBN();
148 var size = br.readVarintNum();
149 if (size !== 0) {
150 obj.script = br.read(size);
151 } else {
152 obj.script = Buffer.from([]);
153 }
154 return new Output(obj);
155};
156
157Output.prototype.toBufferWriter = function(writer) {
158 if (!writer) {
159 writer = new BufferWriter();
160 }
161 writer.writeUInt64LEBN(this._satoshisBN);
162 var script = this._scriptBuffer;
163 writer.writeVarintNum(script.length);
164 writer.write(script);
165 return writer;
166};
167
168module.exports = Output;