UNPKG

@owstack/bch-lib

Version:

A Javascript library to build bitcoin cash and blockchain-based applications.

186 lines (169 loc) 4.68 kB
'use strict'; var owsCommon = require('@owstack/ows-common'); var BN = owsCommon.BN; var Buffer = owsCommon.deps.Buffer; var BufferUtil = owsCommon.buffer; var BufferWriter = owsCommon.encoding.BufferWriter; var errors = owsCommon.errors; var JSUtil = owsCommon.util.js; var Script = require('../script'); var lodash = owsCommon.deps.lodash; var $ = owsCommon.util.preconditions; var MAX_SAFE_INTEGER = 0x1fffffffffffff; function Output(args) { if (!(this instanceof Output)) { return new Output(args); } if (lodash.isObject(args)) { this.satoshis = args.satoshis; if (BufferUtil.isBuffer(args.script)) { this._scriptBuffer = args.script; } else { var script; if (lodash.isString(args.script) && JSUtil.isHexa(args.script)) { script = new Buffer(args.script, 'hex'); } else { script = args.script; } this.setScript(script); } } else { throw new TypeError('Unrecognized argument for Output'); } } Object.defineProperty(Output.prototype, 'script', { configurable: false, enumerable: true, get: function() { if (this._script) { return this._script; } else { this.setScriptFromBuffer(this._scriptBuffer); return this._script; } } }); Object.defineProperty(Output.prototype, 'satoshis', { configurable: false, enumerable: true, get: function() { return this._satoshis; }, set: function(num) { if (num instanceof BN) { this._satoshisBN = num; this._satoshis = num.toNumber(); } else if (lodash.isString(num)) { this._satoshis = parseInt(num); this._satoshisBN = BN.fromNumber(this._satoshis); } else { $.checkArgument( JSUtil.isNaturalNumber(num), 'Output satoshis is not a natural number' ); this._satoshisBN = BN.fromNumber(num); this._satoshis = num; } $.checkState( JSUtil.isNaturalNumber(this._satoshis), 'Output satoshis is not a natural number' ); } }); Output.prototype.invalidSatoshis = function() { if (this._satoshis > MAX_SAFE_INTEGER) { return 'transaction txout satoshis greater than max safe integer'; } if (this._satoshis !== this._satoshisBN.toNumber()) { return 'transaction txout satoshis has corrupted value'; } if (this._satoshis < 0) { return 'transaction txout negative'; } return false; }; Object.defineProperty(Output.prototype, 'satoshisBN', { configurable: false, enumerable: true, get: function() { return this._satoshisBN; }, set: function(num) { this._satoshisBN = num; this._satoshis = num.toNumber(); $.checkState( JSUtil.isNaturalNumber(this._satoshis), 'Output satoshis is not a natural number' ); } }); Output.prototype.toObject = Output.prototype.toJSON = function toObject() { var obj = { satoshis: this.satoshis }; obj.script = this._scriptBuffer.toString('hex'); return obj; }; Output.fromObject = function(data) { return new Output(data); }; Output.prototype.setScriptFromBuffer = function(buffer) { this._scriptBuffer = buffer; try { this._script = Script.fromBuffer(this._scriptBuffer); this._script._isOutput = true; } catch(e) { if (e instanceof errors.Script.InvalidBuffer) { this._script = null; } else { throw e; } } }; Output.prototype.setScript = function(script) { if (script instanceof Script) { this._scriptBuffer = script.toBuffer(); this._script = script; this._script._isOutput = true; } else if (lodash.isString(script)) { this._script = Script.fromString(script); this._scriptBuffer = this._script.toBuffer(); this._script._isOutput = true; } else if (BufferUtil.isBuffer(script)) { this.setScriptFromBuffer(script); } else { throw new TypeError('Invalid argument type: script'); } return this; }; Output.prototype.inspect = function() { var scriptStr; if (this.script) { scriptStr = this.script.inspect(); } else { scriptStr = this._scriptBuffer.toString('hex'); } return '<Output (' + this.satoshis + ' satoshis) ' + scriptStr + '>'; }; Output.fromBufferReader = function(br) { var obj = {}; obj.satoshis = br.readUInt64LEBN(); var size = br.readVarintNum(); if (size !== 0) { obj.script = br.read(size); } else { obj.script = new Buffer([]); } return new Output(obj); }; Output.prototype.toBufferWriter = function(writer) { if (!writer) { writer = new BufferWriter(); } writer.writeUInt64LEBN(this._satoshisBN); var script = this._scriptBuffer; writer.writeVarintNum(script.length); writer.write(script); return writer; }; module.exports = Output;