refactor: address, amount, uri, errors.
This commit is contained in:
parent
84fce9aad4
commit
4c557744a2
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var assert = require('assert');
|
||||||
var AsyncObject = require('../utils/async');
|
var AsyncObject = require('../utils/async');
|
||||||
var Network = require('../protocol/network');
|
var Network = require('../protocol/network');
|
||||||
var Logger = require('../node/logger');
|
var Logger = require('../node/logger');
|
||||||
@ -19,11 +20,10 @@ var LRU = require('../utils/lru');
|
|||||||
var ChainEntry = require('./chainentry');
|
var ChainEntry = require('./chainentry');
|
||||||
var CoinView = require('../coins/coinview');
|
var CoinView = require('../coins/coinview');
|
||||||
var Script = require('../script/script');
|
var Script = require('../script/script');
|
||||||
var assert = require('assert');
|
var errors = require('../protocol/errors');
|
||||||
var errors = require('../btc/errors');
|
var co = require('../utils/co');
|
||||||
var VerifyError = errors.VerifyError;
|
var VerifyError = errors.VerifyError;
|
||||||
var VerifyResult = errors.VerifyResult;
|
var VerifyResult = errors.VerifyResult;
|
||||||
var co = require('../utils/co');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a blockchain.
|
* Represents a blockchain.
|
||||||
@ -1027,6 +1027,7 @@ Chain.prototype._reset = co(function* reset(block, silent) {
|
|||||||
this.synced = this.isFull(true);
|
this.synced = this.isFull(true);
|
||||||
|
|
||||||
state = yield this.getDeploymentState();
|
state = yield this.getDeploymentState();
|
||||||
|
|
||||||
this.setDeploymentState(state);
|
this.setDeploymentState(state);
|
||||||
|
|
||||||
this.emit('tip', tip);
|
this.emit('tip', tip);
|
||||||
|
|||||||
@ -10,8 +10,12 @@ var assert = require('assert');
|
|||||||
var util = require('../utils/util');
|
var util = require('../utils/util');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Amount
|
* Represents a bitcoin amount (satoshis internally).
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @param {(String|Number)?} value
|
||||||
|
* @param {String?} unit
|
||||||
|
* @param {Boolean?} num
|
||||||
|
* @property {Amount} value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Amount(value, unit, num) {
|
function Amount(value, unit, num) {
|
||||||
@ -24,6 +28,15 @@ function Amount(value, unit, num) {
|
|||||||
this.fromOptions(value, unit, num);
|
this.fromOptions(value, unit, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from options.
|
||||||
|
* @private
|
||||||
|
* @param {(String|Number)?} value
|
||||||
|
* @param {String?} unit
|
||||||
|
* @param {Boolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.fromOptions = function fromOptions(value, unit, num) {
|
Amount.prototype.fromOptions = function fromOptions(value, unit, num) {
|
||||||
if (typeof unit === 'string')
|
if (typeof unit === 'string')
|
||||||
return this.from(unit, value, num);
|
return this.from(unit, value, num);
|
||||||
@ -34,10 +47,21 @@ Amount.prototype.fromOptions = function fromOptions(value, unit, num) {
|
|||||||
return this.fromBTC(value);
|
return this.fromBTC(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get satoshi value.
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.toValue = function toValue() {
|
Amount.prototype.toValue = function toValue() {
|
||||||
return this.value;
|
return this.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get satoshi string or value.
|
||||||
|
* @param {Boolean?} num
|
||||||
|
* @returns {String|Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.toSatoshis = function toSatoshis(num) {
|
Amount.prototype.toSatoshis = function toSatoshis(num) {
|
||||||
if (num)
|
if (num)
|
||||||
return this.value;
|
return this.value;
|
||||||
@ -45,18 +69,44 @@ Amount.prototype.toSatoshis = function toSatoshis(num) {
|
|||||||
return this.value.toString(10);
|
return this.value.toString(10);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bits string or value.
|
||||||
|
* @param {Boolean?} num
|
||||||
|
* @returns {String|Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.toBits = function toBits(num) {
|
Amount.prototype.toBits = function toBits(num) {
|
||||||
return Amount.serialize(this.value, 2, num);
|
return Amount.serialize(this.value, 2, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get mbtc string or value.
|
||||||
|
* @param {Boolean?} num
|
||||||
|
* @returns {String|Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.toMBTC = function toMBTC(num) {
|
Amount.prototype.toMBTC = function toMBTC(num) {
|
||||||
return Amount.serialize(this.value, 5, num);
|
return Amount.serialize(this.value, 5, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get btc string or value.
|
||||||
|
* @param {Boolean?} num
|
||||||
|
* @returns {String|Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.toBTC = function toBTC(num) {
|
Amount.prototype.toBTC = function toBTC(num) {
|
||||||
return Amount.serialize(this.value, 8, num);
|
return Amount.serialize(this.value, 8, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get unit string or value.
|
||||||
|
* @param {String} unit - Can be `sat`,
|
||||||
|
* `ubtc`, `bits`, `mbtc`, or `btc`.
|
||||||
|
* @param {Boolean?} num
|
||||||
|
* @returns {String|Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.to = function to(unit, num) {
|
Amount.prototype.to = function to(unit, num) {
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case 'sat':
|
case 'sat':
|
||||||
@ -72,36 +122,89 @@ Amount.prototype.to = function to(unit, num) {
|
|||||||
throw new Error('Unknown unit "' + unit + '".');
|
throw new Error('Unknown unit "' + unit + '".');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert amount to bitcoin string.
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.toString = function toString() {
|
Amount.prototype.toString = function toString() {
|
||||||
return this.toBTC();
|
return this.toBTC();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from value.
|
||||||
|
* @private
|
||||||
|
* @param {Amount} value
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.fromValue = function fromValue(value) {
|
Amount.prototype.fromValue = function fromValue(value) {
|
||||||
assert(util.isInt53(value), 'Value must be an int64.');
|
assert(util.isInt53(value), 'Value must be an int64.');
|
||||||
this.value = value;
|
this.value = value;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from satoshis.
|
||||||
|
* @private
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.fromSatoshis = function fromSatoshis(value, num) {
|
Amount.prototype.fromSatoshis = function fromSatoshis(value, num) {
|
||||||
this.value = Amount.parse(value, 0, num);
|
this.value = Amount.parse(value, 0, num);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from bits.
|
||||||
|
* @private
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.fromBits = function fromBits(value, num) {
|
Amount.prototype.fromBits = function fromBits(value, num) {
|
||||||
this.value = Amount.parse(value, 2, num);
|
this.value = Amount.parse(value, 2, num);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from mbtc.
|
||||||
|
* @private
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.fromMBTC = function fromMBTC(value, num) {
|
Amount.prototype.fromMBTC = function fromMBTC(value, num) {
|
||||||
this.value = Amount.parse(value, 5, num);
|
this.value = Amount.parse(value, 5, num);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from btc.
|
||||||
|
* @private
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.fromBTC = function fromBTC(value, num) {
|
Amount.prototype.fromBTC = function fromBTC(value, num) {
|
||||||
this.value = Amount.parse(value, 8, num);
|
this.value = Amount.parse(value, 8, num);
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from unit.
|
||||||
|
* @private
|
||||||
|
* @param {String} unit
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.from = function from(unit, value, num) {
|
Amount.prototype.from = function from(unit, value, num) {
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case 'sat':
|
case 'sat':
|
||||||
@ -117,34 +220,90 @@ Amount.prototype.from = function from(unit, value, num) {
|
|||||||
throw new Error('Unknown unit "' + unit + '".');
|
throw new Error('Unknown unit "' + unit + '".');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate amount from options.
|
||||||
|
* @param {(String|Number)?} value
|
||||||
|
* @param {String?} unit
|
||||||
|
* @param {Boolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.fromOptions = function fromOptions(value, unit, num) {
|
Amount.fromOptions = function fromOptions(value, unit, num) {
|
||||||
return new Amount().fromOptions(value);
|
return new Amount().fromOptions(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate amount from value.
|
||||||
|
* @private
|
||||||
|
* @param {Amount} value
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.fromValue = function fromValue(value) {
|
Amount.fromValue = function fromValue(value) {
|
||||||
return new Amount().fromValue(value);
|
return new Amount().fromValue(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate amount from satoshis.
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.fromSatoshis = function fromSatoshis(value, num) {
|
Amount.fromSatoshis = function fromSatoshis(value, num) {
|
||||||
return new Amount().fromSatoshis(value, num);
|
return new Amount().fromSatoshis(value, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate amount from bits.
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.fromBits = function fromBits(value, num) {
|
Amount.fromBits = function fromBits(value, num) {
|
||||||
return new Amount().fromBits(value, num);
|
return new Amount().fromBits(value, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate amount from mbtc.
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.fromMBTC = function fromMBTC(value, num) {
|
Amount.fromMBTC = function fromMBTC(value, num) {
|
||||||
return new Amount().fromMBTC(value, num);
|
return new Amount().fromMBTC(value, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate amount from btc.
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.fromBTC = function fromBTC(value, num) {
|
Amount.fromBTC = function fromBTC(value, num) {
|
||||||
return new Amount().fromBTC(value, num);
|
return new Amount().fromBTC(value, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate amount from unit.
|
||||||
|
* @param {String} unit
|
||||||
|
* @param {Number|String} value
|
||||||
|
* @param {Bolean?} num
|
||||||
|
* @returns {Amount}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.from = function from(unit, value, num) {
|
Amount.from = function from(unit, value, num) {
|
||||||
return new Amount().from(unit, value, num);
|
return new Amount().from(unit, value, num);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inspect amount.
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
|
||||||
Amount.prototype.inspect = function inspect() {
|
Amount.prototype.inspect = function inspect() {
|
||||||
return '<Amount: ' + this.toString() + '>';
|
return '<Amount: ' + this.toString() + '>';
|
||||||
};
|
};
|
||||||
@ -169,12 +328,12 @@ Amount.btc = function btc(value, num) {
|
|||||||
* This function explicitly avoids any
|
* This function explicitly avoids any
|
||||||
* floating point arithmetic.
|
* floating point arithmetic.
|
||||||
* @param {Amount} value
|
* @param {Amount} value
|
||||||
* @param {Number} dec - Number of decimals.
|
* @param {Number} exp - Exponent.
|
||||||
* @param {Boolean} num - Return a number.
|
* @param {Boolean} num - Return a number.
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Amount.serialize = function serialize(value, dec, num) {
|
Amount.serialize = function serialize(value, exp, num) {
|
||||||
var negative = false;
|
var negative = false;
|
||||||
var hi, lo, result;
|
var hi, lo, result;
|
||||||
|
|
||||||
@ -189,11 +348,11 @@ Amount.serialize = function serialize(value, dec, num) {
|
|||||||
|
|
||||||
assert(value.length <= 16, 'Number exceeds 2^53-1.');
|
assert(value.length <= 16, 'Number exceeds 2^53-1.');
|
||||||
|
|
||||||
while (value.length < dec + 1)
|
while (value.length < exp + 1)
|
||||||
value = '0' + value;
|
value = '0' + value;
|
||||||
|
|
||||||
hi = value.slice(0, -dec);
|
hi = value.slice(0, -exp);
|
||||||
lo = value.slice(-dec);
|
lo = value.slice(-exp);
|
||||||
|
|
||||||
lo = lo.replace(/0+$/, '');
|
lo = lo.replace(/0+$/, '');
|
||||||
|
|
||||||
@ -214,21 +373,21 @@ Amount.serialize = function serialize(value, dec, num) {
|
|||||||
/**
|
/**
|
||||||
* Unsafely convert satoshis to a BTC string.
|
* Unsafely convert satoshis to a BTC string.
|
||||||
* @param {Amount} value
|
* @param {Amount} value
|
||||||
* @param {Number} dec - Number of decimals.
|
* @param {Number} exp - Exponent.
|
||||||
* @param {Boolean} num - Return a number.
|
* @param {Boolean} num - Return a number.
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Amount.serializeUnsafe = function serializeUnsafe(value, dec, num) {
|
Amount.serializeUnsafe = function serializeUnsafe(value, exp, num) {
|
||||||
assert(util.isInt(value), 'Non-satoshi value for conversion.');
|
assert(util.isInt(value), 'Non-satoshi value for conversion.');
|
||||||
|
|
||||||
value /= pow10(dec);
|
value /= pow10(exp);
|
||||||
value = value.toFixed(dec);
|
value = value.toFixed(exp);
|
||||||
|
|
||||||
if (num)
|
if (num)
|
||||||
return +value;
|
return +value;
|
||||||
|
|
||||||
if (dec !== 0) {
|
if (exp !== 0) {
|
||||||
value = value.replace(/0+$/, '');
|
value = value.replace(/0+$/, '');
|
||||||
if (value[value.length - 1] === '.')
|
if (value[value.length - 1] === '.')
|
||||||
value += '0';
|
value += '0';
|
||||||
@ -258,15 +417,15 @@ Amount.value = function value(value, num) {
|
|||||||
* extra validation to ensure the resulting
|
* extra validation to ensure the resulting
|
||||||
* Number will be 53 bits or less.
|
* Number will be 53 bits or less.
|
||||||
* @param {String} value - BTC
|
* @param {String} value - BTC
|
||||||
* @param {Number} dec - Number of decimals.
|
* @param {Number} exp - Exponent.
|
||||||
* @param {Boolean} num - Allow numbers.
|
* @param {Boolean} num - Allow numbers.
|
||||||
* @returns {Amount} Satoshis.
|
* @returns {Amount} Satoshis.
|
||||||
* @throws on parse error
|
* @throws on parse error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Amount.parse = function parse(value, dec, num) {
|
Amount.parse = function parse(value, exp, num) {
|
||||||
var negative = false;
|
var negative = false;
|
||||||
var mult = pow10(dec);
|
var mult = pow10(exp);
|
||||||
var maxLo = modSafe(mult);
|
var maxLo = modSafe(mult);
|
||||||
var maxHi = divSafe(mult);
|
var maxHi = divSafe(mult);
|
||||||
var parts, hi, lo, result;
|
var parts, hi, lo, result;
|
||||||
@ -293,13 +452,13 @@ Amount.parse = function parse(value, dec, num) {
|
|||||||
hi = hi.replace(/^0+/, '');
|
hi = hi.replace(/^0+/, '');
|
||||||
lo = lo.replace(/0+$/, '');
|
lo = lo.replace(/0+$/, '');
|
||||||
|
|
||||||
assert(hi.length <= 16 - dec, 'Number exceeds 2^53-1.');
|
assert(hi.length <= 16 - exp, 'Number exceeds 2^53-1.');
|
||||||
assert(lo.length <= dec, 'Too many decimal places.');
|
assert(lo.length <= exp, 'Too many decimal places.');
|
||||||
|
|
||||||
if (hi.length === 0)
|
if (hi.length === 0)
|
||||||
hi = '0';
|
hi = '0';
|
||||||
|
|
||||||
while (lo.length < dec)
|
while (lo.length < exp)
|
||||||
lo += '0';
|
lo += '0';
|
||||||
|
|
||||||
hi = parseInt(hi, 10);
|
hi = parseInt(hi, 10);
|
||||||
@ -319,13 +478,13 @@ Amount.parse = function parse(value, dec, num) {
|
|||||||
/**
|
/**
|
||||||
* Unsafely convert a BTC string to satoshis.
|
* Unsafely convert a BTC string to satoshis.
|
||||||
* @param {String} value - BTC
|
* @param {String} value - BTC
|
||||||
* @param {Number} dec - Number of decimals.
|
* @param {Number} exp - Exponent.
|
||||||
* @param {Boolean} num - Allow numbers.
|
* @param {Boolean} num - Allow numbers.
|
||||||
* @returns {Amount} Satoshis.
|
* @returns {Amount} Satoshis.
|
||||||
* @throws on parse error
|
* @throws on parse error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Amount.parseUnsafe = function parseUnsafe(value, dec, num) {
|
Amount.parseUnsafe = function parseUnsafe(value, exp, num) {
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
assert(util.isFloat(value), 'Non-BTC value for conversion.');
|
assert(util.isFloat(value), 'Non-BTC value for conversion.');
|
||||||
value = parseFloat(value, 10);
|
value = parseFloat(value, 10);
|
||||||
@ -334,7 +493,7 @@ Amount.parseUnsafe = function parseUnsafe(value, dec, num) {
|
|||||||
assert(num, 'Cannot parse number.');
|
assert(num, 'Cannot parse number.');
|
||||||
}
|
}
|
||||||
|
|
||||||
value *= pow10(dec);
|
value *= pow10(exp);
|
||||||
|
|
||||||
assert(value % 1 === 0, 'Too many decimal places.');
|
assert(value % 1 === 0, 'Too many decimal places.');
|
||||||
|
|
||||||
@ -366,7 +525,8 @@ function pow10(exp) {
|
|||||||
case 8:
|
case 8:
|
||||||
return 100000000;
|
return 100000000;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false, 'Exponent is too large.');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,7 +551,8 @@ function modSafe(mod) {
|
|||||||
case 100000000:
|
case 100000000:
|
||||||
return 54740991;
|
return 54740991;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false, 'Exponent is too large.');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +577,8 @@ function divSafe(div) {
|
|||||||
case 100000000:
|
case 100000000:
|
||||||
return 90071992;
|
return 90071992;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false, 'Exponent is too large.');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.Amount = require('./amount');
|
exports.Amount = require('./amount');
|
||||||
exports.errors = require('./errors');
|
exports.URI = require('./uri');
|
||||||
exports.uri = require('./uri');
|
|
||||||
|
|||||||
168
lib/btc/uri.js
168
lib/btc/uri.js
@ -8,23 +8,46 @@
|
|||||||
|
|
||||||
var util = require('../utils/util');
|
var util = require('../utils/util');
|
||||||
var Address = require('../primitives/address');
|
var Address = require('../primitives/address');
|
||||||
|
var KeyRing = require('../primitives/keyring');
|
||||||
var Amount = require('./amount');
|
var Amount = require('./amount');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a bitcoin URI.
|
||||||
|
* @constructor
|
||||||
|
* @param {Object|String} options
|
||||||
|
* @property {Address} address
|
||||||
|
* @property {Number|-1} version
|
||||||
|
* @property {Amount} amount
|
||||||
|
* @property {String|null} label
|
||||||
|
* @property {String|null} message
|
||||||
|
* @property {KeyRing|null} key
|
||||||
|
* @property {String|null} request
|
||||||
|
*/
|
||||||
|
|
||||||
function URI(options) {
|
function URI(options) {
|
||||||
if (!(this instanceof URI))
|
if (!(this instanceof URI))
|
||||||
return new URI(options);
|
return new URI(options);
|
||||||
|
|
||||||
this.address = new Address();
|
this.address = new Address();
|
||||||
|
this.version = -1;
|
||||||
this.amount = -1;
|
this.amount = -1;
|
||||||
this.label = null;
|
this.label = null;
|
||||||
this.message = null;
|
this.message = null;
|
||||||
|
this.key = null;
|
||||||
this.request = null;
|
this.request = null;
|
||||||
|
|
||||||
if (options)
|
if (options)
|
||||||
this.fromOptions(options);
|
this.fromOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from options object.
|
||||||
|
* @private
|
||||||
|
* @param {Object|String} options
|
||||||
|
* @returns {URI}
|
||||||
|
*/
|
||||||
|
|
||||||
URI.prototype.fromOptions = function fromOptions(options) {
|
URI.prototype.fromOptions = function fromOptions(options) {
|
||||||
if (typeof options === 'string')
|
if (typeof options === 'string')
|
||||||
return this.fromString(options);
|
return this.fromString(options);
|
||||||
@ -33,63 +56,100 @@ URI.prototype.fromOptions = function fromOptions(options) {
|
|||||||
this.address.fromOptions(options.address);
|
this.address.fromOptions(options.address);
|
||||||
|
|
||||||
if (options.amount != null) {
|
if (options.amount != null) {
|
||||||
assert(util.isNumber(options.amount));
|
assert(util.isUInt53(options.amount), 'Amount must be a uint53.');
|
||||||
this.amount = options.amount;
|
this.amount = options.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.version != null) {
|
||||||
|
assert(util.isUInt32(options.version), 'Version must be a uint32.');
|
||||||
|
this.version = options.version;
|
||||||
|
}
|
||||||
|
|
||||||
if (options.label) {
|
if (options.label) {
|
||||||
assert(typeof options.label === 'string');
|
assert(typeof options.label === 'string', 'Label must be a string.');
|
||||||
this.label = options.label;
|
this.label = options.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.message) {
|
if (options.message) {
|
||||||
assert(typeof options.message === 'string');
|
assert(typeof options.message === 'string', 'Message must be a string.');
|
||||||
this.message = options.message;
|
this.message = options.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.key) {
|
||||||
|
if (typeof options.key === 'string') {
|
||||||
|
this.key = KeyRing.fromSecret(options.key);
|
||||||
|
} else {
|
||||||
|
this.key = KeyRing.fromOptions(options.key);
|
||||||
|
assert(this.key.privateKey, 'Key must have a private key.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.request) {
|
if (options.request) {
|
||||||
assert(typeof options.request === 'string');
|
assert(typeof options.request === 'string', 'Request must be a string.');
|
||||||
this.request = options.request;
|
this.request = options.request;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate URI from options.
|
||||||
|
* @param {Object|String} options
|
||||||
|
* @returns {URI}
|
||||||
|
*/
|
||||||
|
|
||||||
URI.fromOptions = function fromOptions(options) {
|
URI.fromOptions = function fromOptions(options) {
|
||||||
return new URI().fromOptions(options);
|
return new URI().fromOptions(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse and inject properties from string.
|
||||||
|
* @private
|
||||||
|
* @param {String} str
|
||||||
|
* @returns {URI}
|
||||||
|
*/
|
||||||
|
|
||||||
URI.prototype.fromString = function fromString(str) {
|
URI.prototype.fromString = function fromString(str) {
|
||||||
var prefix, index, address, query;
|
var prefix, index, body, query, parts, address, version;
|
||||||
|
|
||||||
assert(typeof str === 'string');
|
assert(typeof str === 'string');
|
||||||
assert(str.length > 8, 'Not a bitcoin URI.');
|
assert(str.length > 8, 'Not a bitcoin URI.');
|
||||||
|
|
||||||
prefix = str.substring(0, 8);
|
prefix = str.substring(0, 8);
|
||||||
|
|
||||||
if (prefix !== 'bitcoin:')
|
assert(prefix === 'bitcoin:', 'Not a bitcoin URI.');
|
||||||
throw new Error('Not a bitcoin URI.');
|
|
||||||
|
|
||||||
str = str.substring(8);
|
str = str.substring(8);
|
||||||
|
|
||||||
index = str.indexOf('?');
|
index = str.indexOf('?');
|
||||||
|
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
address = str;
|
body = str;
|
||||||
} else {
|
} else {
|
||||||
address = str.substring(0, index);
|
body = str.substring(0, index);
|
||||||
query = str.substring(index + 1);
|
query = str.substring(index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parts = body.split(';');
|
||||||
|
assert(parts.length <= 2, 'Too many semicolons in body.');
|
||||||
|
|
||||||
|
address = parts[0];
|
||||||
|
|
||||||
this.address.fromBase58(address);
|
this.address.fromBase58(address);
|
||||||
|
|
||||||
|
if (parts.length === 2) {
|
||||||
|
version = parts[1];
|
||||||
|
assert(util.isDecimal(version), 'Version is not decimal.');
|
||||||
|
this.version = parseInt(version, 10);
|
||||||
|
}
|
||||||
|
|
||||||
if (!query)
|
if (!query)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
query = parsePairs(query);
|
query = parsePairs(query);
|
||||||
|
|
||||||
if (query.amount)
|
if (query.amount)
|
||||||
this.amount = Amount.value(query.amount);
|
this.amount = parseAmount(query.amount, query.size);
|
||||||
|
|
||||||
if (query.label)
|
if (query.label)
|
||||||
this.label = query.label;
|
this.label = query.label;
|
||||||
@ -97,22 +157,39 @@ URI.prototype.fromString = function fromString(str) {
|
|||||||
if (query.message)
|
if (query.message)
|
||||||
this.message = query.message;
|
this.message = query.message;
|
||||||
|
|
||||||
|
if (query.send)
|
||||||
|
this.key = KeyRing.fromSecret(query.send);
|
||||||
|
|
||||||
if (query.r)
|
if (query.r)
|
||||||
this.request = query.r;
|
this.request = query.r;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate uri from string.
|
||||||
|
* @param {String} str
|
||||||
|
* @returns {URI}
|
||||||
|
*/
|
||||||
|
|
||||||
URI.fromString = function fromString(str) {
|
URI.fromString = function fromString(str) {
|
||||||
return new URI().fromString(str);
|
return new URI().fromString(str);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize uri to a string.
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
|
||||||
URI.prototype.toString = function toString() {
|
URI.prototype.toString = function toString() {
|
||||||
var str = 'bitcoin:';
|
var str = 'bitcoin:';
|
||||||
var query = [];
|
var query = [];
|
||||||
|
|
||||||
str += this.address.toBase58();
|
str += this.address.toBase58();
|
||||||
|
|
||||||
|
if (this.version !== -1)
|
||||||
|
str += ';version=' + this.version;
|
||||||
|
|
||||||
if (this.amount !== -1)
|
if (this.amount !== -1)
|
||||||
query.push('amount=' + Amount.btc(this.amount));
|
query.push('amount=' + Amount.btc(this.amount));
|
||||||
|
|
||||||
@ -122,6 +199,9 @@ URI.prototype.toString = function toString() {
|
|||||||
if (this.message)
|
if (this.message)
|
||||||
query.push('message=' + escape(this.message));
|
query.push('message=' + escape(this.message));
|
||||||
|
|
||||||
|
if (this.key)
|
||||||
|
query.push('send=' + this.key.toSecret());
|
||||||
|
|
||||||
if (this.request)
|
if (this.request)
|
||||||
query.push('r=' + escape(this.request));
|
query.push('r=' + escape(this.request));
|
||||||
|
|
||||||
@ -131,6 +211,11 @@ URI.prototype.toString = function toString() {
|
|||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inspect bitcoin uri.
|
||||||
|
* @returns {String}
|
||||||
|
*/
|
||||||
|
|
||||||
URI.prototype.inspect = function inspect() {
|
URI.prototype.inspect = function inspect() {
|
||||||
return '<URI: ' + this.toString() + '>';
|
return '<URI: ' + this.toString() + '>';
|
||||||
};
|
};
|
||||||
@ -188,6 +273,69 @@ function escape(str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseAmount(amount, size) {
|
||||||
|
var value = amount;
|
||||||
|
var exp = 8;
|
||||||
|
var parts;
|
||||||
|
|
||||||
|
assert(typeof amount === 'string');
|
||||||
|
assert(amount.length > 0);
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
assert(typeof size === 'string');
|
||||||
|
assert(size.length > 0);
|
||||||
|
exp = size;
|
||||||
|
assert(util.isDecimal(exp), 'Exponent is not a decimal.');
|
||||||
|
exp = parseInt(exp, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value[0] === 'x') {
|
||||||
|
exp = 4;
|
||||||
|
|
||||||
|
assert(value.length > 1);
|
||||||
|
|
||||||
|
value = value.substring(1);
|
||||||
|
parts = value.split('X');
|
||||||
|
assert(parts.length <= 2, 'Too many bases.');
|
||||||
|
|
||||||
|
value = parts[0];
|
||||||
|
assert(value.length > 0, 'Value is empty.');
|
||||||
|
assert(util.isHex(value), 'Value is not hex.');
|
||||||
|
value = parseInt(value, 16);
|
||||||
|
assert(util.isNumber(value), 'Value exceeds 2^53-1 bits.');
|
||||||
|
|
||||||
|
if (parts.length === 2) {
|
||||||
|
exp = parts[1];
|
||||||
|
assert(util.isHex(exp), 'Exponent is not hex.');
|
||||||
|
exp = parseInt(exp, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(exp <= 4, 'Exponent is too large.');
|
||||||
|
|
||||||
|
value *= Math.pow(16, exp);
|
||||||
|
|
||||||
|
assert(util.isNumber(value), 'Value exceeds 2^53-1 bits.');
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
parts = value.split('X');
|
||||||
|
assert(parts.length <= 2, 'Too many bases.');
|
||||||
|
|
||||||
|
value = parts[0];
|
||||||
|
assert(value.length > 0, 'Value is empty.');
|
||||||
|
assert(value[0] !== '-', 'Value is negative.');
|
||||||
|
assert(util.isFloat(value), 'Value is not a float.');
|
||||||
|
|
||||||
|
if (parts.length === 2) {
|
||||||
|
exp = parts[1];
|
||||||
|
assert(util.isDecimal(exp), 'Exponent is not decimal.');
|
||||||
|
exp = parseInt(exp, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Amount.parse(value, exp, false);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
103
lib/env.js
103
lib/env.js
@ -10,99 +10,11 @@
|
|||||||
var lazy = require('./utils/lazy');
|
var lazy = require('./utils/lazy');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A BCoin "environment" which is used for
|
* A BCoin "environment" which exposes all
|
||||||
* bootstrapping the initial `bcoin` module.
|
* constructors for primitives, the blockchain,
|
||||||
* It exposes all constructors for primitives,
|
* mempool, wallet, etc. It also exposes a
|
||||||
* the blockchain, mempool, wallet, etc. It
|
|
||||||
* also sets the default network if there is
|
|
||||||
* one. It exposes a global {@link TimeData}
|
|
||||||
* object for adjusted time, as well as a
|
|
||||||
* global worker pool.
|
* global worker pool.
|
||||||
*
|
|
||||||
* @exports Environment
|
|
||||||
* @constructor
|
* @constructor
|
||||||
*
|
|
||||||
* @param {(Object|NetworkType)?} options - Options object or network type.
|
|
||||||
* @param {(Network|NetworkType)?} options.network
|
|
||||||
* @param {String} [options.prefix=~/.bcoin] - Prefix for filesystem.
|
|
||||||
* @param {String} [options.db=leveldb] - Database backend.
|
|
||||||
* @param {Boolean} [options.debug=false] - Whether to display debug output.
|
|
||||||
* @param {String|Boolean} [options.debugFile=~/.debug.log] - A file to
|
|
||||||
* pipe debug output to.
|
|
||||||
* @param {Boolean} [options.profile=false] - Enable profiler.
|
|
||||||
* @param {Boolean} [options.useWorkers=false] - Enable workers.
|
|
||||||
* @param {Number} [options.maxWorkers=6] - Max size of
|
|
||||||
* the worker pool.
|
|
||||||
* @param {String} [options.workerUri=/bcoin-worker.js] Location of the bcoin
|
|
||||||
* worker.js file for web workers.
|
|
||||||
* @param {String} [options.proxyServer=localhost:8080] -
|
|
||||||
* Websocket->tcp proxy server for browser.
|
|
||||||
* @param {Object?} options.logger - Custom logger.
|
|
||||||
* @property {Boolean} isBrowser
|
|
||||||
* @property {NetworkType} networkType
|
|
||||||
*
|
|
||||||
* @property {Function} bn - Big number constructor
|
|
||||||
* (see {@link https://github.com/indutny/bn.js} for docs).
|
|
||||||
* @property {Object} utils - {@link module:utils}.
|
|
||||||
* @property {Function} locker - {@link Locker} constructor.
|
|
||||||
* @property {Function} reader - {@link BufferReader} constructor.
|
|
||||||
* @property {Function} writer - {@link BufferWriter} constructor.
|
|
||||||
* @property {Object} ec - {@link module:ec}.
|
|
||||||
* @property {Function} lru - {@link LRU} constructor.
|
|
||||||
* @property {Function} bloom - {@link Bloom} constructor.
|
|
||||||
* @property {Function} rbt - {@link RBT} constructor.
|
|
||||||
* @property {Function} lowlevelup - See {@link LowlevelUp}.
|
|
||||||
* @property {Function} uri - See {@link module:uri}.
|
|
||||||
* @property {Function} logger - {@link Logger} constructor.
|
|
||||||
*
|
|
||||||
* @property {Object} constants - See {@link module:constants}.
|
|
||||||
* @property {Object} networks - See {@link module:network}.
|
|
||||||
* @property {Object} errors
|
|
||||||
* @property {Function} errors.VerifyError - {@link VerifyError} constructor.
|
|
||||||
* @property {Function} errors.ScriptError - {@link ScriptError} constructor.
|
|
||||||
* @property {Function} profiler - {@link module:profiler}.
|
|
||||||
* @property {Function} ldb - See {@link module:ldb}.
|
|
||||||
* @property {Function} script - {@link Script} constructor.
|
|
||||||
* @property {Function} opcode - {@link Opcode} constructor.
|
|
||||||
* @property {Function} stack - {@link Stack} constructor.
|
|
||||||
* @property {Function} witness - {@link Witness} constructor.
|
|
||||||
* @property {Function} input - {@link Input} constructor.
|
|
||||||
* @property {Function} output - {@link Output} constructor.
|
|
||||||
* @property {Function} coin - {@link Coin} constructor.
|
|
||||||
* @property {Function} coins - {@link Coins} constructor.
|
|
||||||
* @property {Function} coinview - {@link CoinView} constructor.
|
|
||||||
* @property {Function} tx - {@link TX} constructor.
|
|
||||||
* @property {Function} mtx - {@link MTX} constructor.
|
|
||||||
* @property {Function} txdb - {@link TXDB} constructor.
|
|
||||||
* @property {Function} abstractblock - {@link AbstractBlock} constructor.
|
|
||||||
* @property {Function} memblock - {@link MemBlock} constructor.
|
|
||||||
* @property {Function} block - {@link Block} constructor.
|
|
||||||
* @property {Function} merkleblock - {@link MerkleBlock} constructor.
|
|
||||||
* @property {Function} headers - {@link Headers} constructor.
|
|
||||||
* @property {Function} node - {@link Node} constructor.
|
|
||||||
* @property {Function} spvnode - {@link SPVNode} constructor.
|
|
||||||
* @property {Function} fullnode - {@link Fullnode} constructor.
|
|
||||||
* @property {Function} chainentry - {@link ChainEntry} constructor.
|
|
||||||
* @property {Function} chaindb - {@link ChainDB} constructor.
|
|
||||||
* @property {Function} chain - {@link Chain} constructor.
|
|
||||||
* @property {Function} mempool - {@link Mempool} constructor.
|
|
||||||
* @property {Function} mempoolentry - {@link MempoolEntry} constructor.
|
|
||||||
* @property {Function} hd - {@link HD} constructor.
|
|
||||||
* @property {Function} address - {@link Address} constructor.
|
|
||||||
* @property {Function} wallet - {@link Wallet} constructor.
|
|
||||||
* @property {Function} walletdb - {@link WalletDB} constructor.
|
|
||||||
* @property {Function} peer - {@link Peer} constructor.
|
|
||||||
* @property {Function} pool - {@link Pool} constructor.
|
|
||||||
* @property {Function} miner - {@link Miner} constructor.
|
|
||||||
* @property {Function} minerblock - {@link MinerBlock} constructor.
|
|
||||||
* @property {Object} http
|
|
||||||
* @property {Function} http.client - {@link HTTPClient} constructor.
|
|
||||||
* @property {Function} http.http - {@link HTTPBase} constructor.
|
|
||||||
* @property {Function} http.request - See {@link request}.
|
|
||||||
* @property {Function} http.server - {@link HTTPServer} constructor.
|
|
||||||
* @property {Object} workers - See {@link module:workers}.
|
|
||||||
* @property {TimeData} time - For adjusted time.
|
|
||||||
* @property {Workers?} workerPool - Default global worker pool.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Environment() {
|
function Environment() {
|
||||||
@ -125,7 +37,6 @@ function Environment() {
|
|||||||
// BTC
|
// BTC
|
||||||
this.require('btc', './btc');
|
this.require('btc', './btc');
|
||||||
this.require('amount', './btc/amount');
|
this.require('amount', './btc/amount');
|
||||||
this.require('errors', './btc/errors');
|
|
||||||
this.require('uri', './btc/uri');
|
this.require('uri', './btc/uri');
|
||||||
|
|
||||||
// Coins
|
// Coins
|
||||||
@ -150,7 +61,7 @@ function Environment() {
|
|||||||
this.require('rpc', './http/rpc');
|
this.require('rpc', './http/rpc');
|
||||||
|
|
||||||
// Mempool
|
// Mempool
|
||||||
this.require('txmempool', './mempool'); // -> txmempool?
|
this.require('txmempool', './mempool');
|
||||||
this.require('fees', './mempool/fees');
|
this.require('fees', './mempool/fees');
|
||||||
this.require('mempool', './mempool/mempool');
|
this.require('mempool', './mempool/mempool');
|
||||||
this.require('mempoolentry', './mempool/mempoolentry');
|
this.require('mempoolentry', './mempool/mempoolentry');
|
||||||
@ -196,13 +107,14 @@ function Environment() {
|
|||||||
// Protocol
|
// Protocol
|
||||||
this.require('protocol', './protocol');
|
this.require('protocol', './protocol');
|
||||||
this.require('consensus', './protocol/consensus');
|
this.require('consensus', './protocol/consensus');
|
||||||
|
this.require('errors', './protocol/errors');
|
||||||
this.require('network', './protocol/network');
|
this.require('network', './protocol/network');
|
||||||
this.require('networks', './protocol/networks');
|
this.require('networks', './protocol/networks');
|
||||||
this.require('policy', './protocol/policy');
|
this.require('policy', './protocol/policy');
|
||||||
this.require('timedata', './protocol/timedata');
|
this.require('timedata', './protocol/timedata');
|
||||||
|
|
||||||
// Script
|
// Script
|
||||||
this.require('scripting', './script'); // -> scripting?
|
this.require('txscript', './script');
|
||||||
this.require('opcode', './script/opcode');
|
this.require('opcode', './script/opcode');
|
||||||
this.require('program', './script/program');
|
this.require('program', './script/program');
|
||||||
this.require('script', './script/script');
|
this.require('script', './script/script');
|
||||||
@ -255,7 +167,8 @@ Environment.prototype.set = function set(options) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the adjusted time.
|
* Get the adjusted time of
|
||||||
|
* the default network.
|
||||||
* @returns {Number} Adjusted time.
|
* @returns {Number} Adjusted time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ var policy = require('../protocol/policy');
|
|||||||
var util = require('../utils/util');
|
var util = require('../utils/util');
|
||||||
var co = require('../utils/co');
|
var co = require('../utils/co');
|
||||||
var crypto = require('../crypto/crypto');
|
var crypto = require('../crypto/crypto');
|
||||||
var errors = require('../btc/errors');
|
var errors = require('../protocol/errors');
|
||||||
var Bloom = require('../utils/bloom');
|
var Bloom = require('../utils/bloom');
|
||||||
var Address = require('../primitives/address');
|
var Address = require('../primitives/address');
|
||||||
var Coin = require('../primitives/coin');
|
var Coin = require('../primitives/coin');
|
||||||
|
|||||||
@ -26,7 +26,7 @@ var BIP152 = require('./bip152');
|
|||||||
var Block = require('../primitives/block');
|
var Block = require('../primitives/block');
|
||||||
var TX = require('../primitives/tx');
|
var TX = require('../primitives/tx');
|
||||||
var encoding = require('../utils/encoding');
|
var encoding = require('../utils/encoding');
|
||||||
var errors = require('../btc/errors');
|
var errors = require('../protocol/errors');
|
||||||
var NetAddress = require('../primitives/netaddress');
|
var NetAddress = require('../primitives/netaddress');
|
||||||
var invTypes = InvItem.types;
|
var invTypes = InvItem.types;
|
||||||
var packetTypes = packets.types;
|
var packetTypes = packets.types;
|
||||||
|
|||||||
@ -14,7 +14,7 @@ var util = require('../utils/util');
|
|||||||
var IP = require('../utils/ip');
|
var IP = require('../utils/ip');
|
||||||
var co = require('../utils/co');
|
var co = require('../utils/co');
|
||||||
var common = require('./common');
|
var common = require('./common');
|
||||||
var errors = require('../btc/errors');
|
var errors = require('../protocol/errors');
|
||||||
var NetAddress = require('../primitives/netaddress');
|
var NetAddress = require('../primitives/netaddress');
|
||||||
var Address = require('../primitives/address');
|
var Address = require('../primitives/address');
|
||||||
var BIP150 = require('./bip150');
|
var BIP150 = require('./bip150');
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var util = require('../utils/util');
|
var util = require('../utils/util');
|
||||||
var crypto = require('../crypto/crypto');
|
var crypto = require('../crypto/crypto');
|
||||||
var VerifyResult = require('../btc/errors').VerifyResult;
|
var VerifyResult = require('../protocol/errors').VerifyResult;
|
||||||
var StaticWriter = require('../utils/staticwriter');
|
var StaticWriter = require('../utils/staticwriter');
|
||||||
var InvItem = require('./invitem');
|
var InvItem = require('./invitem');
|
||||||
var encoding = require('../utils/encoding');
|
var encoding = require('../utils/encoding');
|
||||||
|
|||||||
@ -24,12 +24,12 @@ var base58 = require('../utils/base58');
|
|||||||
* @constructor
|
* @constructor
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {Buffer|Hash} options.hash - Address hash.
|
* @param {Buffer|Hash} options.hash - Address hash.
|
||||||
* @param {AddressType} options.type - Address type
|
* @param {AddressPrefix} options.type - Address type
|
||||||
* `{witness,}{pubkeyhash,scripthash}`.
|
* `{witness,}{pubkeyhash,scripthash}`.
|
||||||
* @param {Number} [options.version=-1] - Witness program version.
|
* @param {Number} [options.version=-1] - Witness program version.
|
||||||
* @param {(Network|NetworkType)?} options.network - Network name.
|
* @param {(Network|NetworkType)?} options.network - Network name.
|
||||||
* @property {Buffer} hash
|
* @property {Buffer} hash
|
||||||
* @property {AddressType} type
|
* @property {AddressPrefix} type
|
||||||
* @property {Number} version
|
* @property {Number} version
|
||||||
* @property {Network} network
|
* @property {Network} network
|
||||||
*/
|
*/
|
||||||
@ -48,18 +48,31 @@ function Address(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address types.
|
* Address types. Note that the values
|
||||||
|
* have a direct mapping to script types.
|
||||||
|
* These also represent the "prefix type"
|
||||||
|
* as a network-agnostic version of the
|
||||||
|
* prefix byte. They DO NOT represent the
|
||||||
|
* script type. For example, script type
|
||||||
|
* `WITNESSMASTHASH` would be prefix type
|
||||||
|
* `WITNESSSCRIPTHASH` with a `version`
|
||||||
|
* of 1.
|
||||||
* @enum {Number}
|
* @enum {Number}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.types = common.types;
|
Address.types = {
|
||||||
|
PUBKEYHASH: common.types.PUBKEYHASH,
|
||||||
|
SCRIPTHASH: common.types.SCRIPTHASH,
|
||||||
|
WITNESSSCRIPTHASH: common.types.WITNESSSCRIPTHASH,
|
||||||
|
WITNESSPUBKEYHASH: common.types.WITNESSPUBKEYHASH
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address types by value.
|
* Address types by value.
|
||||||
* @const {RevMap}
|
* @const {RevMap}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.typesByVal = common.typesByVal;
|
exports.typesByVal = util.revMap(Address.types);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject properties from options object.
|
* Inject properties from options object.
|
||||||
@ -130,7 +143,7 @@ Address.prototype.verifyNetwork = function verifyNetwork(network) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the address type as a string.
|
* Get the address type as a string.
|
||||||
* @returns {AddressType}
|
* @returns {AddressPrefix}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.prototype.getType = function getType() {
|
Address.prototype.getType = function getType() {
|
||||||
@ -426,7 +439,7 @@ Address.fromScript = function fromScript(script) {
|
|||||||
* Inject properties from a hash.
|
* Inject properties from a hash.
|
||||||
* @private
|
* @private
|
||||||
* @param {Buffer|Hash} hash
|
* @param {Buffer|Hash} hash
|
||||||
* @param {AddressType} type
|
* @param {AddressPrefix} type
|
||||||
* @param {Number} [version=-1]
|
* @param {Number} [version=-1]
|
||||||
* @param {(Network|NetworkType)?} network
|
* @param {(Network|NetworkType)?} network
|
||||||
* @throws on bad hash size
|
* @throws on bad hash size
|
||||||
@ -436,8 +449,10 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
|||||||
if (typeof hash === 'string')
|
if (typeof hash === 'string')
|
||||||
hash = new Buffer(hash, 'hex');
|
hash = new Buffer(hash, 'hex');
|
||||||
|
|
||||||
if (typeof type === 'string')
|
if (typeof type === 'string') {
|
||||||
type = Address.types[type.toUpperCase()];
|
type = Address.types[type.toUpperCase()];
|
||||||
|
assert(type != null, 'Not a valid address type.');
|
||||||
|
}
|
||||||
|
|
||||||
if (type == null)
|
if (type == null)
|
||||||
type = Address.types.PUBKEYHASH;
|
type = Address.types.PUBKEYHASH;
|
||||||
@ -477,8 +492,8 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a naked address from hash/type/version.
|
* Create a naked address from hash/type/version.
|
||||||
* @param {Buffer|Hash} hash
|
* @param {Hash} hash
|
||||||
* @param {AddressType} type
|
* @param {AddressPrefix} type
|
||||||
* @param {Number} [version=-1]
|
* @param {Number} [version=-1]
|
||||||
* @param {(Network|NetworkType)?} network
|
* @param {(Network|NetworkType)?} network
|
||||||
* @returns {Address}
|
* @returns {Address}
|
||||||
@ -490,89 +505,203 @@ Address.fromHash = function fromHash(hash, type, version, network) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject properties from data.
|
* Inject properties from pubkeyhash.
|
||||||
* @private
|
* @private
|
||||||
* @param {Buffer|Buffer[]} data
|
* @param {Buffer} hash
|
||||||
* @param {AddressType} type
|
* @param {Network?} network
|
||||||
* @param {Number} [version=-1]
|
* @returns {Address}
|
||||||
* @param {(Network|NetworkType)?} network
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.prototype.fromData = function fromData(data, type, version, network) {
|
Address.prototype.fromPubkeyhash = function fromPubkeyhash(hash, network) {
|
||||||
if (typeof type === 'string')
|
var type = Address.types.PUBKEYHASH;
|
||||||
type = Address.types[type.toUpperCase()];
|
return this.fromHash(hash, type, -1, network);
|
||||||
|
};
|
||||||
|
|
||||||
if (type === Address.types.WITNESSSCRIPTHASH) {
|
/**
|
||||||
if (version === 0) {
|
* Instantiate address from pubkeyhash.
|
||||||
assert(Buffer.isBuffer(data));
|
* @param {Buffer} hash
|
||||||
data = crypto.sha256(data);
|
* @param {Network?} network
|
||||||
} else if (version === 1) {
|
* @returns {Address}
|
||||||
assert(Array.isArray(data));
|
*/
|
||||||
throw new Error('MASTv2 creation not implemented.');
|
|
||||||
} else {
|
Address.fromPubkeyhash = function fromPubkeyhash(hash, network) {
|
||||||
throw new Error('Cannot create from version=' + version);
|
return new Address().fromPubkeyhash(hash, network);
|
||||||
}
|
};
|
||||||
} else if (type === Address.types.WITNESSPUBKEYHASH) {
|
|
||||||
if (version !== 0)
|
/**
|
||||||
throw new Error('Cannot create from version=' + version);
|
* Inject properties from scripthash.
|
||||||
assert(Buffer.isBuffer(data));
|
* @private
|
||||||
data = crypto.hash160(data);
|
* @param {Buffer} hash
|
||||||
} else {
|
* @param {Network?} network
|
||||||
data = crypto.hash160(data);
|
* @returns {Address}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.prototype.fromScripthash = function fromScripthash(hash, network) {
|
||||||
|
var type = Address.types.SCRIPTHASH;
|
||||||
|
return this.fromHash(hash, type, -1, network);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate address from scripthash.
|
||||||
|
* @param {Buffer} hash
|
||||||
|
* @param {Network?} network
|
||||||
|
* @returns {Address}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.fromScripthash = function fromScripthash(hash, network) {
|
||||||
|
return new Address().fromScripthash(hash, network);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from witness pubkeyhash.
|
||||||
|
* @private
|
||||||
|
* @param {Buffer} hash
|
||||||
|
* @param {Network?} network
|
||||||
|
* @returns {Address}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.prototype.fromWitnessPubkeyhash = function fromWitnessPubkeyhash(hash, network) {
|
||||||
|
var type = Address.types.WITNESSPUBKEYHASH;
|
||||||
|
return this.fromHash(hash, type, 0, network);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate address from witness pubkeyhash.
|
||||||
|
* @param {Buffer} hash
|
||||||
|
* @param {Network?} network
|
||||||
|
* @returns {Address}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.fromWitnessPubkeyhash = function fromWitnessPubkeyhash(hash, network) {
|
||||||
|
return new Address().fromWitnessPubkeyhash(hash, network);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from witness scripthash.
|
||||||
|
* @private
|
||||||
|
* @param {Buffer} hash
|
||||||
|
* @param {Network?} network
|
||||||
|
* @returns {Address}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.prototype.fromWitnessScripthash = function fromWitnessScripthash(hash, network) {
|
||||||
|
var type = Address.types.WITNESSSCRIPTHASH;
|
||||||
|
return this.fromHash(hash, type, 0, network);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate address from witness scripthash.
|
||||||
|
* @param {Buffer} hash
|
||||||
|
* @param {Network?} network
|
||||||
|
* @returns {Address}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.fromWitnessScripthash = function fromWitnessScripthash(hash, network) {
|
||||||
|
return new Address().fromScripthash(hash, network);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject properties from witness program.
|
||||||
|
* @private
|
||||||
|
* @param {Number} version
|
||||||
|
* @param {Buffer} hash
|
||||||
|
* @param {Network?} network
|
||||||
|
* @returns {Address}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.prototype.fromProgram = function fromProgram(version, hash, network) {
|
||||||
|
var type;
|
||||||
|
|
||||||
|
assert(version >= 0, 'Bad version for witness program.');
|
||||||
|
|
||||||
|
if (typeof hash === 'string')
|
||||||
|
hash = new Buffer(hash, 'hex');
|
||||||
|
|
||||||
|
switch (hash.length) {
|
||||||
|
case 20:
|
||||||
|
type = Address.types.WITNESSPUBKEYHASH;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
type = Address.types.WITNESSSCRIPTHASH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false, 'Unknown witness program data length.');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.fromHash(data, type, version, network);
|
return this.fromHash(hash, type, version, network);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an Address from data/type/version.
|
* Instantiate address from witness program.
|
||||||
* @param {Buffer|Buffer[]} data - Data to be hashed.
|
* @param {Number} version
|
||||||
* Normally a buffer, but can also be an array of
|
* @param {Buffer} hash
|
||||||
* buffers for MAST.
|
* @param {Network?} network
|
||||||
* @param {AddressType} type
|
|
||||||
* @param {Number} [version=-1]
|
|
||||||
* @param {(Network|NetworkType)?} network
|
|
||||||
* @returns {Address}
|
* @returns {Address}
|
||||||
* @throws on bad hash size
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.fromData = function fromData(data, type, version, network) {
|
Address.fromProgram = function fromProgram(version, hash, network) {
|
||||||
return new Address().fromData(data, type, version, network);
|
return new Address().fromProgram(version, hash, network);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate an address, optionally test against a type.
|
* Test whether the address is pubkeyhash.
|
||||||
* @param {Base58Address} address
|
|
||||||
* @param {AddressType}
|
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.validate = function validate(address, type) {
|
Address.prototype.isPubkeyhash = function isPubkeyhash() {
|
||||||
if (!address)
|
return this.type === Address.types.PUBKEYHASH;
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!Buffer.isBuffer(address) && typeof address !== 'string')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
address = Address.fromBase58(address);
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof type === 'string')
|
|
||||||
type = Address.types[type.toUpperCase()];
|
|
||||||
|
|
||||||
if (type && address.type !== type)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the hex hash of a base58
|
* Test whether the address is scripthash.
|
||||||
* address or address object.
|
* @returns {Boolean}
|
||||||
* @param {Base58Address|Address} data
|
*/
|
||||||
|
|
||||||
|
Address.prototype.isScripthash = function isScripthash() {
|
||||||
|
return this.type === Address.types.SCRIPTHASH;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the address is witness pubkeyhash.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.prototype.isWitnessPubkeyhash = function isWitnessPubkeyhash() {
|
||||||
|
return this.version === 0 && this.type === Address.types.WITNESSPUBKEYHASH;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the address is witness scripthash.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.prototype.isWitnessScripthash = function isWitnessScripthash() {
|
||||||
|
return this.version === 0 && this.type === Address.types.WITNESSSCRIPTHASH;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the address is witness masthash.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.prototype.isWitnessMasthash = function isWitnessMasthash() {
|
||||||
|
return this.version === 1 && this.type === Address.types.WITNESSSCRIPTHASH;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the address is a witness program.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Address.prototype.isProgram = function isProgram() {
|
||||||
|
return this.version !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hash of a base58 address or address-related object.
|
||||||
|
* @param {Base58Address|Address|Hash} data
|
||||||
|
* @param {String} enc
|
||||||
* @returns {Hash|null}
|
* @returns {Hash|null}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -603,7 +732,7 @@ Address.getHash = function getHash(data, enc) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a network address prefix for a specified address type.
|
* Get a network address prefix for a specified address type.
|
||||||
* @param {AddressType} type
|
* @param {AddressPrefix} type
|
||||||
* @param {Network} network
|
* @param {Network} network
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
@ -628,7 +757,7 @@ Address.getPrefix = function getPrefix(type, network) {
|
|||||||
* Get an address type for a specified network address prefix.
|
* Get an address type for a specified network address prefix.
|
||||||
* @param {Number} prefix
|
* @param {Number} prefix
|
||||||
* @param {Network} network
|
* @param {Network} network
|
||||||
* @returns {AddressType}
|
* @returns {AddressPrefix}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.getType = function getType(prefix, network) {
|
Address.getType = function getType(prefix, network) {
|
||||||
@ -649,7 +778,7 @@ Address.getType = function getType(prefix, network) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether an address type is a witness program.
|
* Test whether an address type is a witness program.
|
||||||
* @param {AddressType} type
|
* @param {AddressPrefix} type
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ var encoding = require('../utils/encoding');
|
|||||||
var crypto = require('../crypto/crypto');
|
var crypto = require('../crypto/crypto');
|
||||||
var consensus = require('../protocol/consensus');
|
var consensus = require('../protocol/consensus');
|
||||||
var AbstractBlock = require('./abstractblock');
|
var AbstractBlock = require('./abstractblock');
|
||||||
var VerifyResult = require('../btc/errors').VerifyResult;
|
var VerifyResult = require('../protocol/errors').VerifyResult;
|
||||||
var BufferReader = require('../utils/reader');
|
var BufferReader = require('../utils/reader');
|
||||||
var StaticWriter = require('../utils/staticwriter');
|
var StaticWriter = require('../utils/staticwriter');
|
||||||
var TX = require('./tx');
|
var TX = require('./tx');
|
||||||
|
|||||||
@ -477,7 +477,7 @@ KeyRing.prototype.getNestedAddress = function getNestedAddress(enc) {
|
|||||||
|
|
||||||
if (!this._nestedAddress) {
|
if (!this._nestedAddress) {
|
||||||
hash = this.getNestedHash();
|
hash = this.getNestedHash();
|
||||||
address = this.compile(hash, Script.types.SCRIPTHASH);
|
address = Address.fromScripthash(hash, this.network);
|
||||||
this._nestedAddress = address;
|
this._nestedAddress = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,10 +550,10 @@ KeyRing.prototype.getScriptAddress = function getScriptAddress(enc) {
|
|||||||
if (!this._scriptAddress) {
|
if (!this._scriptAddress) {
|
||||||
if (this.witness) {
|
if (this.witness) {
|
||||||
hash = this.getScriptHash256();
|
hash = this.getScriptHash256();
|
||||||
address = this.compile(hash, Script.types.WITNESSSCRIPTHASH, 0);
|
address = Address.fromWitnessScripthash(hash, this.network);
|
||||||
} else {
|
} else {
|
||||||
hash = this.getScriptHash160();
|
hash = this.getScriptHash160();
|
||||||
address = this.compile(hash, Script.types.SCRIPTHASH);
|
address = Address.fromScripthash(hash, this.network);
|
||||||
}
|
}
|
||||||
this._scriptAddress = address;
|
this._scriptAddress = address;
|
||||||
}
|
}
|
||||||
@ -591,9 +591,9 @@ KeyRing.prototype.getKeyAddress = function getKeyAddress(enc) {
|
|||||||
if (!this._keyAddress) {
|
if (!this._keyAddress) {
|
||||||
hash = this.getKeyHash();
|
hash = this.getKeyHash();
|
||||||
if (this.witness)
|
if (this.witness)
|
||||||
address = this.compile(hash, Script.types.WITNESSPUBKEYHASH, 0);
|
address = Address.fromWitnessPubkeyhash(hash, this.network);
|
||||||
else
|
else
|
||||||
address = this.compile(hash, Script.types.PUBKEYHASH);
|
address = Address.fromPubkeyhash(hash, this.network);
|
||||||
this._keyAddress = address;
|
this._keyAddress = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,20 +603,6 @@ KeyRing.prototype.getKeyAddress = function getKeyAddress(enc) {
|
|||||||
return this._keyAddress;
|
return this._keyAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Compile a hash to an address.
|
|
||||||
* @private
|
|
||||||
* @param {Hash|Buffer} hash
|
|
||||||
* @param {AddressType?} type
|
|
||||||
* @param {Number?} version - Witness version.
|
|
||||||
* @returns {Address}
|
|
||||||
* @throws Error on bad hash/prefix.
|
|
||||||
*/
|
|
||||||
|
|
||||||
KeyRing.prototype.compile = function compile(hash, type, version) {
|
|
||||||
return Address.fromHash(hash, type, version, this.network);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get hash.
|
* Get hash.
|
||||||
* @param {String?} enc - `"hex"` or `null`.
|
* @param {String?} enc - `"hex"` or `null`.
|
||||||
@ -759,18 +745,18 @@ KeyRing.prototype.getVersion = function getVersion() {
|
|||||||
|
|
||||||
KeyRing.prototype.getType = function getType() {
|
KeyRing.prototype.getType = function getType() {
|
||||||
if (this.nested)
|
if (this.nested)
|
||||||
return Script.types.SCRIPTHASH;
|
return Address.types.SCRIPTHASH;
|
||||||
|
|
||||||
if (this.witness) {
|
if (this.witness) {
|
||||||
if (this.script)
|
if (this.script)
|
||||||
return Script.types.WITNESSSCRIPTHASH;
|
return Address.types.WITNESSSCRIPTHASH;
|
||||||
return Script.types.WITNESSPUBKEYHASH;
|
return Address.types.WITNESSPUBKEYHASH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.script)
|
if (this.script)
|
||||||
return Script.types.SCRIPTHASH;
|
return Address.types.SCRIPTHASH;
|
||||||
|
|
||||||
return Script.types.PUBKEYHASH;
|
return Address.types.PUBKEYHASH;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -795,7 +781,7 @@ KeyRing.prototype.toJSON = function toJSON() {
|
|||||||
publicKey: this.publicKey.toString('hex'),
|
publicKey: this.publicKey.toString('hex'),
|
||||||
script: this.script ? this.script.toRaw().toString('hex') : null,
|
script: this.script ? this.script.toRaw().toString('hex') : null,
|
||||||
program: this.witness ? this.getProgram().toRaw().toString('hex') : null,
|
program: this.witness ? this.getProgram().toRaw().toString('hex') : null,
|
||||||
type: Script.typesByVal[this.getType()].toLowerCase(),
|
type: Address.typesByVal[this.getType()].toLowerCase(),
|
||||||
address: this.getAddress('base58')
|
address: this.getAddress('base58')
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,7 +11,7 @@ var assert = require('assert');
|
|||||||
var util = require('../utils/util');
|
var util = require('../utils/util');
|
||||||
var crypto = require('../crypto/crypto');
|
var crypto = require('../crypto/crypto');
|
||||||
var AbstractBlock = require('./abstractblock');
|
var AbstractBlock = require('./abstractblock');
|
||||||
var VerifyResult = require('../btc/errors').VerifyResult;
|
var VerifyResult = require('../protocol/errors').VerifyResult;
|
||||||
var BufferReader = require('../utils/reader');
|
var BufferReader = require('../utils/reader');
|
||||||
var StaticWriter = require('../utils/staticwriter');
|
var StaticWriter = require('../utils/staticwriter');
|
||||||
var encoding = require('../utils/encoding');
|
var encoding = require('../utils/encoding');
|
||||||
|
|||||||
@ -17,7 +17,7 @@ var Network = require('../protocol/network');
|
|||||||
var Script = require('../script/script');
|
var Script = require('../script/script');
|
||||||
var BufferReader = require('../utils/reader');
|
var BufferReader = require('../utils/reader');
|
||||||
var StaticWriter = require('../utils/staticwriter');
|
var StaticWriter = require('../utils/staticwriter');
|
||||||
var VerifyResult = require('../btc/errors').VerifyResult;
|
var VerifyResult = require('../protocol/errors').VerifyResult;
|
||||||
var Input = require('./input');
|
var Input = require('./input');
|
||||||
var Output = require('./output');
|
var Output = require('./output');
|
||||||
var Outpoint = require('./outpoint');
|
var Outpoint = require('./outpoint');
|
||||||
|
|||||||
@ -36,19 +36,19 @@ function VerifyError(msg, code, reason, score) {
|
|||||||
if (Error.captureStackTrace)
|
if (Error.captureStackTrace)
|
||||||
Error.captureStackTrace(this, VerifyError);
|
Error.captureStackTrace(this, VerifyError);
|
||||||
|
|
||||||
this.type = 'VerifyError';
|
|
||||||
|
|
||||||
assert(typeof code === 'string');
|
assert(typeof code === 'string');
|
||||||
assert(typeof reason === 'string');
|
assert(typeof reason === 'string');
|
||||||
assert(score >= 0);
|
assert(score >= 0);
|
||||||
|
|
||||||
this.hash = msg.hash();
|
this.type = 'VerifyError';
|
||||||
this.malleated = false;
|
this.message = '';
|
||||||
|
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.reason = reason;
|
this.reason = reason;
|
||||||
this.score = score;
|
this.score = score;
|
||||||
|
|
||||||
|
this.hash = msg.hash();
|
||||||
|
this.malleated = false;
|
||||||
|
|
||||||
this.message = 'Verification failure: ' + reason
|
this.message = 'Verification failure: ' + reason
|
||||||
+ ' (code=' + code + ', score=' + score
|
+ ' (code=' + code + ', score=' + score
|
||||||
+ ', hash=' + util.revHex(this.hash.toString('hex'))
|
+ ', hash=' + util.revHex(this.hash.toString('hex'))
|
||||||
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.consensus = require('./consensus');
|
exports.consensus = require('./consensus');
|
||||||
|
exports.errors = require('./errors');
|
||||||
exports.networks = require('./networks');
|
exports.networks = require('./networks');
|
||||||
exports.Network = require('./network');
|
exports.Network = require('./network');
|
||||||
exports.policy = require('./policy');
|
exports.policy = require('./policy');
|
||||||
|
|||||||
@ -1822,13 +1822,13 @@ Script.prototype.fromAddress = function fromAddress(address) {
|
|||||||
|
|
||||||
assert(address instanceof Address, 'Not an address.');
|
assert(address instanceof Address, 'Not an address.');
|
||||||
|
|
||||||
if (address.type === scriptTypes.PUBKEYHASH)
|
if (address.isPubkeyhash())
|
||||||
return this.fromPubkeyhash(address.hash);
|
return this.fromPubkeyhash(address.hash);
|
||||||
|
|
||||||
if (address.type === scriptTypes.SCRIPTHASH)
|
if (address.isScripthash())
|
||||||
return this.fromScripthash(address.hash);
|
return this.fromScripthash(address.hash);
|
||||||
|
|
||||||
if (address.version !== -1)
|
if (address.isProgram())
|
||||||
return this.fromProgram(address.version, address.hash);
|
return this.fromProgram(address.version, address.hash);
|
||||||
|
|
||||||
throw new Error('Unknown address type.');
|
throw new Error('Unknown address type.');
|
||||||
|
|||||||
@ -162,6 +162,16 @@ util.hrtime = function hrtime(time) {
|
|||||||
return process.hrtime();
|
return process.hrtime();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether a string is decimal.
|
||||||
|
* @param {String?} obj
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
util.isDecimal = function isDecimal(obj) {
|
||||||
|
return typeof obj === 'string' && /^\d+$/.test(obj);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether a string is hex. Note that this
|
* Test whether a string is hex. Note that this
|
||||||
* _could_ yield a false positive on base58
|
* _could_ yield a false positive on base58
|
||||||
|
|||||||
@ -42,7 +42,7 @@ function Path(options) {
|
|||||||
this.data = null;
|
this.data = null;
|
||||||
|
|
||||||
// Currently unused.
|
// Currently unused.
|
||||||
this.type = Script.types.PUBKEYHASH;
|
this.type = Address.types.PUBKEYHASH;
|
||||||
this.version = -1;
|
this.version = -1;
|
||||||
this.hash = null; // Passed in by caller.
|
this.hash = null; // Passed in by caller.
|
||||||
|
|
||||||
|
|||||||
@ -276,8 +276,8 @@ describe('Script', function() {
|
|||||||
hash: encoding.NULL_HASH,
|
hash: encoding.NULL_HASH,
|
||||||
index: 0xffffffff
|
index: 0xffffffff
|
||||||
},
|
},
|
||||||
script: new Script([opcodes.OP_0, opcodes.OP_0]),
|
script: [opcodes.OP_0, opcodes.OP_0],
|
||||||
witness: new Witness(),
|
witness: [],
|
||||||
sequence: 0xffffffff
|
sequence: 0xffffffff
|
||||||
}],
|
}],
|
||||||
outputs: [{
|
outputs: [{
|
||||||
@ -301,7 +301,7 @@ describe('Script', function() {
|
|||||||
sequence: 0xffffffff
|
sequence: 0xffffffff
|
||||||
}],
|
}],
|
||||||
outputs: [{
|
outputs: [{
|
||||||
script: new Script(),
|
script: [],
|
||||||
value: amount
|
value: amount
|
||||||
}],
|
}],
|
||||||
locktime: 0
|
locktime: 0
|
||||||
|
|||||||
@ -77,15 +77,17 @@ describe('Wallet', function() {
|
|||||||
var w = yield walletdb.create();
|
var w = yield walletdb.create();
|
||||||
var addr = w.getAddress('base58');
|
var addr = w.getAddress('base58');
|
||||||
assert(addr);
|
assert(addr);
|
||||||
assert(Address.validate(addr));
|
assert(Address.fromBase58(addr));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should validate existing address', function() {
|
it('should validate existing address', function() {
|
||||||
assert(Address.validate('1KQ1wMNwXHUYj1nV2xzsRcKUH8gVFpTFUc'));
|
assert(Address.fromBase58('1KQ1wMNwXHUYj1nV2xzsRcKUH8gVFpTFUc'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to validate invalid address', function() {
|
it('should fail to validate invalid address', function() {
|
||||||
assert(!Address.validate('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc'));
|
assert.throws(function() {
|
||||||
|
Address.fromBase58('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create and get wallet', cob(function* () {
|
it('should create and get wallet', cob(function* () {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user