|
|
@ -110,13 +110,12 @@ Transaction.prototype._getHash = function() { |
|
|
|
* |
|
|
|
* @param {Object|boolean=} unsafe if true, skip all tests. if it's an object, |
|
|
|
* it's expected to contain a set of flags to skip certain tests: |
|
|
|
* <ul> |
|
|
|
* <li><tt>disableAll</tt>: disable all checks</li> |
|
|
|
* <li><tt>disableSmallFees</tt>: disable checking for fees that are too small</li> |
|
|
|
* <li><tt>disableLargeFees</tt>: disable checking for fees that are too large</li> |
|
|
|
* <li><tt>disableNotFullySigned</tt>: disable checking if all inputs are fully signed</li> |
|
|
|
* <li><tt>disableDustOutputs</tt>: disable checking if there are no outputs that are dust amounts</li> |
|
|
|
* </ul> |
|
|
|
* * `disableAll`: disable all checks |
|
|
|
* * `disableSmallFees`: disable checking for fees that are too small |
|
|
|
* * `disableLargeFees`: disable checking for fees that are too large |
|
|
|
* * `disableNotFullySigned`: disable checking if all inputs are fully signed |
|
|
|
* * `disableDustOutputs`: disable checking if there are no outputs that are dust amounts |
|
|
|
* * `disableMoreOutputThanInput`: disable checking if the transaction spends more bitcoins than the sum of the input amounts |
|
|
|
* @return {string} |
|
|
|
*/ |
|
|
|
Transaction.prototype.serialize = function(unsafe) { |
|
|
@ -136,15 +135,33 @@ Transaction.prototype.uncheckedSerialize = Transaction.prototype.toString = func |
|
|
|
* (decoderawtransaction, sendrawtransaction) |
|
|
|
* |
|
|
|
* @param {Object} opts allows to skip certain tests: |
|
|
|
* <ul> |
|
|
|
* <li><tt>disableSmallFees</tt>: disable checking for fees that are too small</li> |
|
|
|
* <li><tt>disableLargeFees</tt>: disable checking for fees that are too large</li> |
|
|
|
* <li><tt>disableIsFullySigned</tt>: disable checking if all inputs are fully signed</li> |
|
|
|
* <li><tt>disableDustOutputs</tt>: disable checking if there are no outputs that are dust amounts</li> |
|
|
|
* </ul> |
|
|
|
* * `disableSmallFees`: disable checking for fees that are too small |
|
|
|
* * `disableLargeFees`: disable checking for fees that are too large |
|
|
|
* * `disableIsFullySigned`: disable checking if all inputs are fully signed |
|
|
|
* * `disableDustOutputs`: disable checking if there are no outputs that are dust amounts |
|
|
|
* * `disableMoreOutputThanInput`: disable checking if the transaction spends more bitcoins than the sum of the input amounts |
|
|
|
* @return {string} |
|
|
|
*/ |
|
|
|
Transaction.prototype.checkedSerialize = function(opts) { |
|
|
|
var serializationError = this.getSerializationError(opts); |
|
|
|
if (serializationError) { |
|
|
|
throw serializationError; |
|
|
|
} |
|
|
|
return this.uncheckedSerialize(); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Retrieve a possible error that could appear when trying to serialize and broadcast this transaction |
|
|
|
* |
|
|
|
* @param {Object} opts allows to skip certain tests: |
|
|
|
* * `disableSmallFees`: disable checking for fees that are too small |
|
|
|
* * `disableLargeFees`: disable checking for fees that are too large |
|
|
|
* * `disableIsFullySigned`: disable checking if all inputs are fully signed |
|
|
|
* * `disableDustOutputs`: disable checking if there are no outputs that are dust amounts |
|
|
|
* * `disableMoreOutputThanInput`: disable checking if the transaction spends more bitcoins than the sum of the input amounts |
|
|
|
* @return {bitcore.Error} |
|
|
|
*/ |
|
|
|
Transaction.prototype.getSerializationError = function(opts) { |
|
|
|
opts = opts || {}; |
|
|
|
var missingChange = this._missingChange(); |
|
|
|
var feeIsTooLarge = this._isFeeTooLarge(); |
|
|
@ -154,20 +171,22 @@ Transaction.prototype.checkedSerialize = function(opts) { |
|
|
|
|
|
|
|
if (!opts.disableLargeFees && feeIsTooLarge) { |
|
|
|
if (missingChange) { |
|
|
|
throw new errors.Transaction.ChangeAddressMissing('Fee is too large and no change address was provided'); |
|
|
|
return new errors.Transaction.ChangeAddressMissing('Fee is too large and no change address was provided'); |
|
|
|
} |
|
|
|
throw new errors.Transaction.FeeError(feeIsTooLarge); |
|
|
|
return new errors.Transaction.FeeError(feeIsTooLarge); |
|
|
|
} |
|
|
|
if (!opts.disableSmallFees && feeIsTooSmall) { |
|
|
|
throw new errors.Transaction.FeeError(feeIsTooSmall); |
|
|
|
return new errors.Transaction.FeeError(feeIsTooSmall); |
|
|
|
} |
|
|
|
if (!opts.disableDustOutputs && this._hasDustOutputs()) { |
|
|
|
throw new errors.Transaction.DustOutputs(); |
|
|
|
return new errors.Transaction.DustOutputs(); |
|
|
|
} |
|
|
|
if (!opts.disableIsFullySigned && !isFullySigned) { |
|
|
|
throw new errors.Transaction.MissingSignatures(); |
|
|
|
return new errors.Transaction.MissingSignatures(); |
|
|
|
} |
|
|
|
if (!opts.disableMoreOutputThanInput && this._getUnspentValue < 0) { |
|
|
|
return new errors.Transaction.InvalidOutputAmountSum(); |
|
|
|
} |
|
|
|
return this.uncheckedSerialize(); |
|
|
|
}; |
|
|
|
|
|
|
|
Transaction.FEE_SECURITY_MARGIN = 15; |
|
|
|