address: types and MAST.
This commit is contained in:
parent
afa7862e55
commit
503cbfc886
@ -15,6 +15,7 @@ var assert = utils.assert;
|
||||
var BufferWriter = require('./writer');
|
||||
var BufferReader = require('./reader');
|
||||
var Script = bcoin.script;
|
||||
var scriptTypes = constants.scriptTypes;
|
||||
|
||||
/**
|
||||
* Represents an address.
|
||||
@ -37,7 +38,7 @@ function Address(options) {
|
||||
return new Address(options);
|
||||
|
||||
this.hash = constants.ZERO_HASH160;
|
||||
this.type = 'pubkeyhash';
|
||||
this.type = scriptTypes.PUBKEYHASH;
|
||||
this.version = -1;
|
||||
this.network = bcoin.network.get().type;
|
||||
|
||||
@ -82,6 +83,15 @@ Address.prototype.getHash = function getHash(enc) {
|
||||
return this.hash;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the address type as a string.
|
||||
* @returns {AddressType}
|
||||
*/
|
||||
|
||||
Address.prototype.getType = function getType() {
|
||||
return constants.scriptTypesByVal[this.type].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Compile the address object to its raw serialization.
|
||||
* @param {{NetworkType|Network)?} network
|
||||
@ -97,9 +107,9 @@ Address.prototype.toRaw = function toRaw(network) {
|
||||
network = this.network;
|
||||
|
||||
network = bcoin.network.get(network);
|
||||
prefix = network.address.prefixes[this.type];
|
||||
prefix = Address.getPrefix(this.type, network);
|
||||
|
||||
assert(prefix != null, 'Not a valid address prefix.');
|
||||
assert(prefix !== -1, 'Not a valid address prefix.');
|
||||
|
||||
p.writeU8(prefix);
|
||||
if (this.version !== -1) {
|
||||
@ -140,8 +150,10 @@ Address.prototype.toScript = function toScript() {
|
||||
Address.prototype.toString = function toString(enc) {
|
||||
if (enc === 'hex')
|
||||
return this.getHash('hex');
|
||||
|
||||
if (enc === 'base58')
|
||||
enc = null;
|
||||
|
||||
return this.toBase58(enc);
|
||||
};
|
||||
|
||||
@ -152,7 +164,7 @@ Address.prototype.toString = function toString(enc) {
|
||||
|
||||
Address.prototype.inspect = function inspect() {
|
||||
return '<Address:'
|
||||
+ ' type=' + this.type
|
||||
+ ' type=' + this.getType()
|
||||
+ ' version=' + this.version
|
||||
+ ' base58=' + this.toBase58()
|
||||
+ '>';
|
||||
@ -175,12 +187,12 @@ Address.prototype.fromRaw = function fromRaw(data) {
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
network = networks[networks.types[i]];
|
||||
type = network.address.prefixesByVal[prefix];
|
||||
if (type != null)
|
||||
type = Address.getType(prefix, network);
|
||||
if (type !== -1)
|
||||
break;
|
||||
}
|
||||
|
||||
assert(type != null, 'Unknown address prefix.');
|
||||
assert(i < networks.types.length, 'Unknown address prefix.');
|
||||
|
||||
if (data.length > 25) {
|
||||
version = p.readU8();
|
||||
@ -236,59 +248,52 @@ Address.fromBase58 = function fromBase58(address) {
|
||||
*/
|
||||
|
||||
Address.prototype.fromScript = function fromScript(script) {
|
||||
var program;
|
||||
|
||||
if (script.isProgram()) {
|
||||
program = script.toProgram();
|
||||
// TODO: MAST support
|
||||
if (program.isUnknown())
|
||||
return;
|
||||
this.hash = program.data;
|
||||
this.type = program.type;
|
||||
this.version = program.version;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Fast case
|
||||
if (script.isPubkey(true)) {
|
||||
this.hash = utils.hash160(script.raw.slice(1, script.raw[0] + 1));
|
||||
this.type = 'pubkeyhash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isPubkeyhash(true)) {
|
||||
this.hash = script.raw.slice(3, 23);
|
||||
this.type = 'pubkeyhash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isScripthash()) {
|
||||
this.hash = script.raw.slice(2, 22);
|
||||
this.type = 'scripthash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Slow case (allow non-minimal data and parse script)
|
||||
if (script.isPubkey()) {
|
||||
this.hash = utils.hash160(script.code[0].data);
|
||||
this.type = 'pubkeyhash';
|
||||
this.hash = utils.hash160(script.get(0));
|
||||
this.type = scriptTypes.PUBKEYHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isPubkeyhash()) {
|
||||
this.hash = script.code[2].data;
|
||||
this.type = 'pubkeyhash';
|
||||
this.hash = script.get(2);
|
||||
this.type = scriptTypes.PUBKEYHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isScripthash()) {
|
||||
this.hash = script.get(1);
|
||||
this.type = scriptTypes.SCRIPTHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isWitnessPubkeyhash()) {
|
||||
this.hash = script.get(1);
|
||||
this.type = scriptTypes.WITNESSPUBKEYHASH;
|
||||
this.version = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isWitnessScripthash()) {
|
||||
this.hash = script.get(1);
|
||||
this.type = scriptTypes.WITNESSSCRIPTHASH;
|
||||
this.version = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isWitnessMasthash()) {
|
||||
this.hash = script.get(1);
|
||||
this.type = scriptTypes.WITNESSSCRIPTHASH;
|
||||
this.version = 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Put this last: it's the slowest to check.
|
||||
if (script.isMultisig()) {
|
||||
this.hash = utils.hash160(script.raw);
|
||||
this.type = 'scripthash';
|
||||
this.hash = utils.hash160(script.toRaw());
|
||||
this.type = scriptTypes.SCRIPTHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
@ -301,16 +306,18 @@ Address.prototype.fromScript = function fromScript(script) {
|
||||
*/
|
||||
|
||||
Address.prototype.fromWitness = function fromWitness(witness) {
|
||||
// We're pretty much screwed here
|
||||
// since we can't get the version.
|
||||
if (witness.isPubkeyhashInput()) {
|
||||
this.hash = utils.hash160(witness.items[1]);
|
||||
this.type = 'witnesspubkeyhash';
|
||||
this.hash = utils.hash160(witness.get(1));
|
||||
this.type = scriptTypes.WITNESSPUBKEYHASH;
|
||||
this.version = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (witness.isScripthashInput()) {
|
||||
this.hash = utils.sha256(witness.items[witness.items.length - 1]);
|
||||
this.type = 'witnessscripthash';
|
||||
this.hash = utils.sha256(witness.get(witness.length - 1));
|
||||
this.type = scriptTypes.WITNESSSCRIPTHASH;
|
||||
this.version = 0;
|
||||
return this;
|
||||
}
|
||||
@ -324,15 +331,15 @@ Address.prototype.fromWitness = function fromWitness(witness) {
|
||||
|
||||
Address.prototype.fromInputScript = function fromInputScript(script) {
|
||||
if (script.isPubkeyhashInput()) {
|
||||
this.hash = utils.hash160(script.code[1].data);
|
||||
this.type = 'pubkeyhash';
|
||||
this.hash = utils.hash160(script.get(1));
|
||||
this.type = scriptTypes.PUBKEYHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isScripthashInput()) {
|
||||
this.hash = utils.hash160(script.code[script.code.length - 1].data);
|
||||
this.type = 'scripthash';
|
||||
this.hash = utils.hash160(script.get(script.length - 1));
|
||||
this.type = scriptTypes.SCRIPTHASH;
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
@ -389,8 +396,11 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
||||
if (typeof hash === 'string')
|
||||
hash = new Buffer(hash, 'hex');
|
||||
|
||||
if (!type)
|
||||
type = 'pubkeyhash';
|
||||
if (typeof type === 'string')
|
||||
type = scriptTypes[type.toUpperCase()];
|
||||
|
||||
if (type == null)
|
||||
type = scriptTypes.PUBKEYHASH;
|
||||
|
||||
if (version == null)
|
||||
version = -1;
|
||||
@ -398,21 +408,22 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
||||
network = bcoin.network.get(network);
|
||||
|
||||
assert(Buffer.isBuffer(hash));
|
||||
assert(typeof type === 'string');
|
||||
assert(utils.isNumber(type));
|
||||
assert(utils.isNumber(version));
|
||||
assert(network.address.prefixes[type] != null, 'Not a valid address prefix.');
|
||||
|
||||
assert(Address.getPrefix(type, network) !== -1, 'Not a valid address type.');
|
||||
|
||||
if (version === -1) {
|
||||
assert(!network.address.witness[type], 'Wrong version (witness)');
|
||||
assert(!Address.isWitness(type), 'Wrong version (witness)');
|
||||
assert(hash.length === 20, 'Hash is the wrong size.');
|
||||
} else {
|
||||
assert(network.address.witness[type], 'Wrong version (non-witness).');
|
||||
assert(Address.isWitness(type), 'Wrong version (non-witness).');
|
||||
assert(version >= 0 && version <= 16, 'Bad program version.');
|
||||
if (version === 0 && type === 'witnesspubkeyhash')
|
||||
if (version === 0 && type === scriptTypes.WITNESSPUBKEYHASH)
|
||||
assert(hash.length === 20, 'Hash is the wrong size.');
|
||||
else if (version === 0 && type === 'witnessscripthash')
|
||||
else if (version === 0 && type === scriptTypes.WITNESSSCRIPTHASH)
|
||||
assert(hash.length === 32, 'Hash is the wrong size.');
|
||||
else if (version === 1 && type === 'witnessscripthash')
|
||||
else if (version === 1 && type === scriptTypes.WITNESSSCRIPTHASH)
|
||||
assert(hash.length === 32, 'Hash is the wrong size.');
|
||||
}
|
||||
|
||||
@ -439,30 +450,45 @@ Address.fromHash = function fromHash(hash, type, version, network) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from hash.
|
||||
* @param {Hash|Buffer} hash
|
||||
* @param {AddressType?} type
|
||||
* @param {Number?} version - Witness program version.
|
||||
* Inject properties from data.
|
||||
* @private
|
||||
* @param {Buffer|Buffer[]} data
|
||||
* @param {AddressType} type
|
||||
* @param {Number} [version=-1]
|
||||
* @param {(Network|NetworkType)?} network
|
||||
* @throws on bad hash size
|
||||
*/
|
||||
|
||||
Address.prototype.fromData = function fromData(data, type, version, network) {
|
||||
if (type === 'witnessscripthash') {
|
||||
assert(version === 0);
|
||||
data = utils.sha256(data);
|
||||
} else if (type === 'witnesspubkeyhash') {
|
||||
assert(version === 0);
|
||||
if (typeof type === 'string')
|
||||
type = scriptTypes[type.toUpperCase()];
|
||||
|
||||
if (type === scriptTypes.WITNESSSCRIPTHASH) {
|
||||
if (version === 0) {
|
||||
assert(Buffer.isBuffer(data));
|
||||
data = utils.sha256(data);
|
||||
} else if (version === 1) {
|
||||
assert(Array.isArray(data));
|
||||
data = utils.getMerkleRoot(data);
|
||||
} else {
|
||||
throw new Error('Cannot create from version=' + version);
|
||||
}
|
||||
} else if (type === scriptTypes.WITNESSPUBKEYHASH) {
|
||||
if (version !== 0)
|
||||
throw new Error('Cannot create from version=' + version);
|
||||
assert(Buffer.isBuffer(data));
|
||||
data = utils.hash160(data);
|
||||
} else {
|
||||
data = utils.hash160(data);
|
||||
}
|
||||
|
||||
return this.fromHash(data, type, version, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an Address from data/type/version.
|
||||
* @param {Buffer} data - Data to be hashed.
|
||||
* @param {Buffer|Buffer[]} data - Data to be hashed.
|
||||
* Normally a buffer, but can also be an array of
|
||||
* buffers for MAST.
|
||||
* @param {AddressType} type
|
||||
* @param {Number} [version=-1]
|
||||
* @param {(Network|NetworkType)?} network
|
||||
@ -494,6 +520,9 @@ Address.validate = function validate(address, type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof type === 'string')
|
||||
type = scriptTypes[type.toUpperCase()];
|
||||
|
||||
if (type && address.type !== type)
|
||||
return false;
|
||||
|
||||
@ -530,6 +559,69 @@ Address.getHash = function getHash(data, enc) {
|
||||
: hash;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a network address prefix for a specified address type.
|
||||
* @param {AddressType} type
|
||||
* @param {Network} network
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
Address.getPrefix = function getPrefix(type, network) {
|
||||
var prefixes = network.addressPrefix;
|
||||
switch (type) {
|
||||
case scriptTypes.PUBKEYHASH:
|
||||
return prefixes.pubkeyhash;
|
||||
case scriptTypes.SCRIPTHASH:
|
||||
return prefixes.scripthash;
|
||||
case scriptTypes.WITNESSPUBKEYHASH:
|
||||
return prefixes.witnesspubkeyhash;
|
||||
case scriptTypes.WITNESSSCRIPTHASH:
|
||||
return prefixes.witnessscripthash;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an address type for a specified network address prefix.
|
||||
* @param {Number} prefix
|
||||
* @param {Network} network
|
||||
* @returns {AddressType}
|
||||
*/
|
||||
|
||||
Address.getType = function getType(prefix, network) {
|
||||
var prefixes = network.addressPrefix;
|
||||
switch (prefix) {
|
||||
case prefixes.pubkeyhash:
|
||||
return scriptTypes.PUBKEYHASH;
|
||||
case prefixes.scripthash:
|
||||
return scriptTypes.SCRIPTHASH;
|
||||
case prefixes.witnesspubkeyhash:
|
||||
return scriptTypes.WITNESSPUBKEYHASH;
|
||||
case prefixes.witnessscripthash:
|
||||
return scriptTypes.WITNESSSCRIPTHASH;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether an address type is a witness program.
|
||||
* @param {AddressType} type
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Address.isWitness = function isWitness(type) {
|
||||
switch (type) {
|
||||
case scriptTypes.WITNESSPUBKEYHASH:
|
||||
return true;
|
||||
case scriptTypes.WITNESSSCRIPTHASH:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -1083,7 +1083,7 @@ HDPrivateKey.isExtended = function isExtended(data) {
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].prefixes.xprivkey58;
|
||||
prefix = networks[type].keyPrefix.xprivkey58;
|
||||
if (data.indexOf(prefix) === 0)
|
||||
return true;
|
||||
}
|
||||
@ -1107,7 +1107,7 @@ HDPrivateKey.hasPrefix = function hasPrefix(data) {
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].prefixes.xprivkey;
|
||||
prefix = networks[type].keyPrefix.xprivkey;
|
||||
if (version === prefix)
|
||||
return type;
|
||||
}
|
||||
@ -1326,7 +1326,7 @@ HDPrivateKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].prefixes.xprivkey;
|
||||
prefix = networks[type].keyPrefix.xprivkey;
|
||||
if (version === prefix)
|
||||
break;
|
||||
}
|
||||
@ -1363,7 +1363,7 @@ HDPrivateKey.prototype.toRaw = function toRaw(network, writer) {
|
||||
|
||||
network = bcoin.network.get(network);
|
||||
|
||||
p.writeU32BE(network.prefixes.xprivkey);
|
||||
p.writeU32BE(network.keyPrefix.xprivkey);
|
||||
p.writeU8(this.depth);
|
||||
p.writeBytes(this.parentFingerPrint);
|
||||
p.writeU32BE(this.childIndex);
|
||||
@ -1806,7 +1806,7 @@ HDPublicKey.isExtended = function isExtended(data) {
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].prefixes.xpubkey58;
|
||||
prefix = networks[type].keyPrefix.xpubkey58;
|
||||
if (data.indexOf(prefix) === 0)
|
||||
return true;
|
||||
}
|
||||
@ -1830,7 +1830,7 @@ HDPublicKey.hasPrefix = function hasPrefix(data) {
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].prefixes.xpubkey;
|
||||
prefix = networks[type].keyPrefix.xpubkey;
|
||||
if (version === prefix)
|
||||
return type;
|
||||
}
|
||||
@ -1870,7 +1870,7 @@ HDPublicKey.prototype.fromRaw = function fromRaw(raw) {
|
||||
|
||||
for (i = 0; i < networks.types.length; i++) {
|
||||
type = networks.types[i];
|
||||
prefix = networks[type].prefixes.xpubkey;
|
||||
prefix = networks[type].keyPrefix.xpubkey;
|
||||
if (version === prefix)
|
||||
break;
|
||||
}
|
||||
@ -1906,7 +1906,7 @@ HDPublicKey.prototype.toRaw = function toRaw(network, writer) {
|
||||
|
||||
network = bcoin.network.get(network);
|
||||
|
||||
p.writeU32BE(network.prefixes.xpubkey);
|
||||
p.writeU32BE(network.keyPrefix.xpubkey);
|
||||
p.writeU8(this.depth);
|
||||
p.writeBytes(this.parentFingerPrint);
|
||||
p.writeU32BE(this.childIndex);
|
||||
|
||||
@ -247,10 +247,10 @@ Input.fromOptions = function fromOptions(options) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the previous output script type. Will "guess"
|
||||
* based on the input script and/or witness if coin
|
||||
* is not available.
|
||||
* @returns {String} type
|
||||
* Get the previous output script type as a string.
|
||||
* Will "guess" based on the input script and/or
|
||||
* witness if coin is not available.
|
||||
* @returns {ScriptType} type
|
||||
*/
|
||||
|
||||
Input.prototype.getType = function getType() {
|
||||
@ -267,7 +267,7 @@ Input.prototype.getType = function getType() {
|
||||
else
|
||||
type = this.script.getInputType();
|
||||
|
||||
return type;
|
||||
return constants.scriptTypesByVal[type].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -161,7 +161,7 @@ KeyPair.prototype.toRaw = function toRaw(network, writer) {
|
||||
|
||||
network = bcoin.network.get(network);
|
||||
|
||||
p.writeU8(network.prefixes.privkey);
|
||||
p.writeU8(network.keyPrefix.privkey);
|
||||
p.writeBytes(this.getPrivateKey());
|
||||
|
||||
if (this.compressed)
|
||||
@ -199,7 +199,7 @@ KeyPair.prototype.fromRaw = function fromRaw(data) {
|
||||
|
||||
for (i = 0; i < network.types.length; i++) {
|
||||
type = network.types[i];
|
||||
prefix = network[type].prefixes.privkey;
|
||||
prefix = network[type].keyPrefix.privkey;
|
||||
if (version === prefix)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -8,10 +8,12 @@
|
||||
'use strict';
|
||||
|
||||
var bcoin = require('./env');
|
||||
var constants = bcoin.protocol.constants;
|
||||
var utils = bcoin.utils;
|
||||
var assert = utils.assert;
|
||||
var BufferReader = require('./reader');
|
||||
var BufferWriter = require('./writer');
|
||||
var scriptTypes = constants.scriptTypes;
|
||||
|
||||
/**
|
||||
* Represents a key ring which amounts to an address. Used for {@link Wallet}.
|
||||
@ -259,7 +261,7 @@ KeyRing.prototype.getProgramAddress = function getProgramAddress(enc) {
|
||||
|
||||
if (!this._programAddress) {
|
||||
hash = this.getProgramHash();
|
||||
address = this.compile(hash, 'scripthash');
|
||||
address = this.compile(hash, scriptTypes.SCRIPTHASH);
|
||||
this._programAddress = address;
|
||||
}
|
||||
|
||||
@ -332,10 +334,10 @@ KeyRing.prototype.getScriptAddress = function getScriptAddress(enc) {
|
||||
if (!this._scriptAddress) {
|
||||
if (this.witness) {
|
||||
hash = this.getScriptHash256();
|
||||
address = this.compile(hash, 'witnessscripthash', 0);
|
||||
address = this.compile(hash, scriptTypes.WITNESSSCRIPTHASH, 0);
|
||||
} else {
|
||||
hash = this.getScriptHash160();
|
||||
address = this.compile(hash, 'scripthash');
|
||||
address = this.compile(hash, scriptTypes.SCRIPTHASH);
|
||||
}
|
||||
this._scriptAddress = address;
|
||||
}
|
||||
@ -373,9 +375,9 @@ KeyRing.prototype.getKeyAddress = function getKeyAddress(enc) {
|
||||
if (!this._keyAddress) {
|
||||
hash = this.getKeyHash();
|
||||
if (this.witness)
|
||||
address = this.compile(hash, 'witnesspubkeyhash', 0);
|
||||
address = this.compile(hash, scriptTypes.WITNESSPUBKEYHASH, 0);
|
||||
else
|
||||
address = this.compile(hash, 'pubkeyhash');
|
||||
address = this.compile(hash, scriptTypes.PUBKEYHASH);
|
||||
this._keyAddress = address;
|
||||
}
|
||||
|
||||
|
||||
@ -46,8 +46,8 @@ function Network(options) {
|
||||
this.activationThreshold = options.activationThreshold;
|
||||
this.minerWindow = options.minerWindow;
|
||||
this.deployments = options.deployments;
|
||||
this.prefixes = options.prefixes;
|
||||
this.address = options.address;
|
||||
this.keyPrefix = options.keyPrefix;
|
||||
this.addressPrefix = options.addressPrefix;
|
||||
this.requireStandard = options.requireStandard;
|
||||
this.rpcPort = options.rpcPort;
|
||||
this.minRelay = options.minRelay;
|
||||
|
||||
@ -68,12 +68,12 @@ Output.fromOptions = function fromOptions(options) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the script type.
|
||||
* @returns {String} type
|
||||
* Get the script type as a string.
|
||||
* @returns {ScriptType} type
|
||||
*/
|
||||
|
||||
Output.prototype.getType = function getType() {
|
||||
return this.script.getType();
|
||||
return constants.scriptTypesByVal[this.script.getType()].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -674,11 +674,19 @@ exports.scriptTypes = {
|
||||
SCRIPTHASH: 3,
|
||||
MULTISIG: 4,
|
||||
NULLDATA: 5,
|
||||
WITNESSSCRIPTHASH: 6,
|
||||
WITNESSKEYHASH: 7,
|
||||
WITNESSMAST: 8
|
||||
WITNESSMALFORMED: 0x80 | 0,
|
||||
WITNESSSCRIPTHASH: 0x80 | 1,
|
||||
WITNESSPUBKEYHASH: 0x80 | 2,
|
||||
WITNESSMASTHASH: 0x80 | 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Output script types by value.
|
||||
* @const {RevMap}
|
||||
*/
|
||||
|
||||
exports.scriptTypesByVal = utils.revMap(exports.scriptTypes);
|
||||
|
||||
/**
|
||||
* Script and locktime flags. See {@link VerifyFlags}.
|
||||
* @enum {Number}
|
||||
|
||||
@ -358,7 +358,7 @@ main.deployments = {
|
||||
* @default
|
||||
*/
|
||||
|
||||
main.prefixes = {
|
||||
main.keyPrefix = {
|
||||
privkey: 128,
|
||||
xpubkey: 0x0488b21e,
|
||||
xprivkey: 0x0488ade4,
|
||||
@ -367,42 +367,17 @@ main.prefixes = {
|
||||
};
|
||||
|
||||
/**
|
||||
* {@link Base58Address} constants.
|
||||
* {@link Address} prefixes.
|
||||
* @enum {Object}
|
||||
*/
|
||||
|
||||
main.address = {
|
||||
/**
|
||||
* {@link Base58Address} prefixes.
|
||||
* @enum {Number}
|
||||
*/
|
||||
|
||||
prefixes: {
|
||||
pubkeyhash: 0,
|
||||
scripthash: 5,
|
||||
witnesspubkeyhash: 6,
|
||||
witnessscripthash: 10
|
||||
},
|
||||
|
||||
/**
|
||||
* {@link Base58Address} witness types.
|
||||
* @enum {Number}
|
||||
*/
|
||||
|
||||
witness: {
|
||||
witnesspubkeyhash: true,
|
||||
witnessscripthash: true
|
||||
}
|
||||
main.addressPrefix = {
|
||||
pubkeyhash: 0,
|
||||
scripthash: 5,
|
||||
witnesspubkeyhash: 6,
|
||||
witnessscripthash: 10
|
||||
};
|
||||
|
||||
/**
|
||||
* {@link Base58Address} prefixes by value.
|
||||
* @type {RevMap}
|
||||
* @default
|
||||
*/
|
||||
|
||||
main.address.prefixesByVal = utils.revMap(main.address.prefixes);
|
||||
|
||||
/**
|
||||
* Default value for whether the mempool
|
||||
* accepts non-standard transactions.
|
||||
@ -585,7 +560,7 @@ testnet.deployments = {
|
||||
}
|
||||
};
|
||||
|
||||
testnet.prefixes = {
|
||||
testnet.keyPrefix = {
|
||||
privkey: 239,
|
||||
xpubkey: 0x043587cf,
|
||||
xprivkey: 0x04358394,
|
||||
@ -593,21 +568,13 @@ testnet.prefixes = {
|
||||
xpubkey58: 'tpub'
|
||||
};
|
||||
|
||||
testnet.address = {
|
||||
prefixes: {
|
||||
pubkeyhash: 111,
|
||||
scripthash: 196,
|
||||
witnesspubkeyhash: 3,
|
||||
witnessscripthash: 40
|
||||
},
|
||||
witness: {
|
||||
witnesspubkeyhash: true,
|
||||
witnessscripthash: true
|
||||
}
|
||||
testnet.addressPrefix = {
|
||||
pubkeyhash: 111,
|
||||
scripthash: 196,
|
||||
witnesspubkeyhash: 3,
|
||||
witnessscripthash: 40
|
||||
};
|
||||
|
||||
testnet.address.prefixesByVal = utils.revMap(testnet.address.prefixes);
|
||||
|
||||
testnet.requireStandard = false;
|
||||
|
||||
testnet.rpcPort = 18332;
|
||||
@ -736,7 +703,7 @@ regtest.deployments = {
|
||||
}
|
||||
};
|
||||
|
||||
regtest.prefixes = {
|
||||
regtest.keyPrefix = {
|
||||
privkey: 239,
|
||||
xpubkey: 0x043587cf,
|
||||
xprivkey: 0x04358394,
|
||||
@ -744,21 +711,13 @@ regtest.prefixes = {
|
||||
xpubkey58: 'tpub'
|
||||
};
|
||||
|
||||
regtest.address = {
|
||||
prefixes: {
|
||||
pubkeyhash: 111,
|
||||
scripthash: 196,
|
||||
witnesspubkeyhash: 3,
|
||||
witnessscripthash: 40
|
||||
},
|
||||
witness: {
|
||||
witnesspubkeyhash: true,
|
||||
witnessscripthash: true
|
||||
}
|
||||
regtest.addressPrefix = {
|
||||
pubkeyhash: 111,
|
||||
scripthash: 196,
|
||||
witnesspubkeyhash: 3,
|
||||
witnessscripthash: 40
|
||||
};
|
||||
|
||||
regtest.address.prefixesByVal = utils.revMap(regtest.address.prefixes);
|
||||
|
||||
regtest.requireStandard = false;
|
||||
|
||||
regtest.rpcPort = 18332;
|
||||
@ -866,7 +825,7 @@ segnet3.minerWindow = 144;
|
||||
|
||||
segnet3.deployments = {};
|
||||
|
||||
segnet3.prefixes = {
|
||||
segnet3.keyPrefix = {
|
||||
privkey: 158,
|
||||
xpubkey: 0x053587cf,
|
||||
xprivkey: 0x05358394,
|
||||
@ -874,21 +833,13 @@ segnet3.prefixes = {
|
||||
xpubkey58: '2793'
|
||||
};
|
||||
|
||||
segnet3.address = {
|
||||
prefixes: {
|
||||
pubkeyhash: 30,
|
||||
scripthash: 50,
|
||||
witnesspubkeyhash: 3,
|
||||
witnessscripthash: 40
|
||||
},
|
||||
witness: {
|
||||
witnesspubkeyhash: true,
|
||||
witnessscripthash: true
|
||||
}
|
||||
segnet3.addressPrefix = {
|
||||
pubkeyhash: 30,
|
||||
scripthash: 50,
|
||||
witnesspubkeyhash: 3,
|
||||
witnessscripthash: 40
|
||||
};
|
||||
|
||||
segnet3.address.prefixesByVal = utils.revMap(segnet3.address.prefixes);
|
||||
|
||||
segnet3.requireStandard = false;
|
||||
|
||||
segnet3.rpcPort = 28332;
|
||||
@ -1011,7 +962,7 @@ segnet4.deployments = {
|
||||
}
|
||||
};
|
||||
|
||||
segnet4.prefixes = {
|
||||
segnet4.keyPrefix = {
|
||||
privkey: 158,
|
||||
xpubkey: 0x053587cf,
|
||||
xprivkey: 0x05358394,
|
||||
@ -1019,21 +970,13 @@ segnet4.prefixes = {
|
||||
xpubkey58: '2793'
|
||||
};
|
||||
|
||||
segnet4.address = {
|
||||
prefixes: {
|
||||
pubkeyhash: 30,
|
||||
scripthash: 50,
|
||||
witnesspubkeyhash: 3,
|
||||
witnessscripthash: 40
|
||||
},
|
||||
witness: {
|
||||
witnesspubkeyhash: true,
|
||||
witnessscripthash: true
|
||||
}
|
||||
segnet4.addressPrefix = {
|
||||
pubkeyhash: 30,
|
||||
scripthash: 50,
|
||||
witnesspubkeyhash: 3,
|
||||
witnessscripthash: 40
|
||||
};
|
||||
|
||||
segnet4.address.prefixesByVal = utils.revMap(segnet4.address.prefixes);
|
||||
|
||||
segnet4.requireStandard = false;
|
||||
|
||||
segnet4.rpcPort = 28902;
|
||||
|
||||
@ -19,6 +19,7 @@ var STACK_TRUE = new Buffer([1]);
|
||||
var STACK_FALSE = new Buffer([]);
|
||||
var STACK_NEGATE = new Buffer([0x81]);
|
||||
var ScriptError = bcoin.errors.ScriptError;
|
||||
var scriptTypes = constants.scriptTypes;
|
||||
|
||||
/**
|
||||
* Refers to the witness field of segregated witness transactions.
|
||||
@ -166,13 +167,17 @@ Witness.prototype.toStack = function toStack() {
|
||||
/**
|
||||
* "Guess" the type of the witness.
|
||||
* This method is not 100% reliable.
|
||||
* @returns {String}
|
||||
* @returns {ScriptType}
|
||||
*/
|
||||
|
||||
Witness.prototype.getInputType = function getInputType() {
|
||||
return (this.isPubkeyhashInput() && 'witnesspubkeyhash')
|
||||
|| (this.isScripthashInput() && 'witnessscripthash')
|
||||
|| 'unknown';
|
||||
if (this.isPubkeyhashInput())
|
||||
return scriptTypes.WITNESSPUBKEYHASH;
|
||||
|
||||
if (this.isScripthashInput())
|
||||
return scriptTypes.WITNESSSCRIPTHASH;
|
||||
|
||||
return scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -234,7 +239,7 @@ Witness.prototype.isScripthashInput = function isScripthashInput() {
|
||||
*/
|
||||
|
||||
Witness.prototype.isUnknownInput = function isUnknownInput() {
|
||||
return this.getInputType() === 'unknown';
|
||||
return this.getInputType() === scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2663,10 +2668,10 @@ Script.prototype.fromAddress = function fromAddress(address) {
|
||||
if (!address)
|
||||
throw new Error('Unknown address type.');
|
||||
|
||||
if (address.type === 'pubkeyhash')
|
||||
if (address.type === scriptTypes.PUBKEYHASH)
|
||||
return this.fromPubkeyhash(address.hash);
|
||||
|
||||
if (address.type === 'scripthash')
|
||||
if (address.type === scriptTypes.SCRIPTHASH)
|
||||
return this.fromScripthash(address.hash);
|
||||
|
||||
if (address.version !== -1)
|
||||
@ -2740,27 +2745,35 @@ Script.prototype.getRedeem = function getRedeem() {
|
||||
|
||||
/**
|
||||
* Get the standard script type.
|
||||
* @returns {String} Script script (can be
|
||||
* any of 'witnesspubkeyhash', 'witnessscripthash',
|
||||
* 'pubkey', 'multisig', 'scripthash', 'nulldata',
|
||||
* or 'unknown').
|
||||
* @returns {ScriptType}
|
||||
*/
|
||||
|
||||
Script.prototype.getType = function getType() {
|
||||
if (this.isProgram()) {
|
||||
if (this.isWitnessPubkeyhash())
|
||||
return 'witnesspubkeyhash';
|
||||
if (this.isWitnessScripthash())
|
||||
return 'witnessscripthash';
|
||||
return 'unknown';
|
||||
}
|
||||
if (this.isPubkey())
|
||||
return scriptTypes.PUBKEY;
|
||||
|
||||
return (this.isPubkey() && 'pubkey')
|
||||
|| (this.isPubkeyhash() && 'pubkeyhash')
|
||||
|| (this.isMultisig() && 'multisig')
|
||||
|| (this.isScripthash() && 'scripthash')
|
||||
|| (this.isNulldata() && 'nulldata')
|
||||
|| 'unknown';
|
||||
if (this.isPubkeyhash())
|
||||
return scriptTypes.PUBKEYHASH;
|
||||
|
||||
if (this.isScripthash())
|
||||
return scriptTypes.SCRIPTHASH;
|
||||
|
||||
if (this.isWitnessPubkeyhash())
|
||||
return scriptTypes.WITNESSPUBKEYHASH;
|
||||
|
||||
if (this.isWitnessScripthash())
|
||||
return scriptTypes.WITNESSSCRIPTHASH;
|
||||
|
||||
if (this.isWitnessMasthash())
|
||||
return scriptTypes.WITNESSMASTHASH;
|
||||
|
||||
if (this.isMultisig())
|
||||
return scriptTypes.MULTISIG;
|
||||
|
||||
if (this.isNulldata())
|
||||
return scriptTypes.NULLDATA;
|
||||
|
||||
return scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2769,7 +2782,7 @@ Script.prototype.getType = function getType() {
|
||||
*/
|
||||
|
||||
Script.prototype.isUnknown = function isUnknown() {
|
||||
return this.getType() === 'unknown';
|
||||
return this.getType() === scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2781,7 +2794,7 @@ Script.prototype.isStandard = function isStandard() {
|
||||
var type = this.getType();
|
||||
var m, n;
|
||||
|
||||
if (type === 'multisig') {
|
||||
if (type === scriptTypes.MULTISIG) {
|
||||
m = Script.getSmall(this.raw[0]);
|
||||
n = Script.getSmall(this.raw[this.raw.length - 2]);
|
||||
|
||||
@ -2790,9 +2803,17 @@ Script.prototype.isStandard = function isStandard() {
|
||||
|
||||
if (m < 1 || m > n)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return type !== 'unknown';
|
||||
if (type === scriptTypes.NULLDATA) {
|
||||
if (this.raw.length > constants.script.MAX_OP_RETURN_BYTES)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return type !== scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2935,9 +2956,6 @@ Script.prototype.isScripthash = function isScripthash() {
|
||||
Script.prototype.isNulldata = function isNulldata(minimal) {
|
||||
var i, op;
|
||||
|
||||
if (this.raw.length > constants.script.MAX_OP_RETURN_BYTES)
|
||||
return false;
|
||||
|
||||
if (this.raw.length === 0)
|
||||
return false;
|
||||
|
||||
@ -2948,6 +2966,9 @@ Script.prototype.isNulldata = function isNulldata(minimal) {
|
||||
return true;
|
||||
|
||||
if (minimal) {
|
||||
if (this.raw.length > constants.script.MAX_OP_RETURN_BYTES)
|
||||
return false;
|
||||
|
||||
if (this.raw.length === 2)
|
||||
return Script.getSmall(this.raw[1]) !== -1;
|
||||
|
||||
@ -2962,10 +2983,13 @@ Script.prototype.isNulldata = function isNulldata(minimal) {
|
||||
|
||||
for (i = 1; i < this.code.length; i++) {
|
||||
op = this.code[i];
|
||||
|
||||
if (op.data)
|
||||
continue;
|
||||
|
||||
if (op.value === -1)
|
||||
return false;
|
||||
|
||||
if (op.value > opcodes.OP_16)
|
||||
return false;
|
||||
}
|
||||
@ -3070,7 +3094,7 @@ Script.prototype.isWitnessScripthash = function isWitnessScripthash() {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Script.prototype.isMAST = function isMAST() {
|
||||
Script.prototype.isWitnessMasthash = function isWitnessMasthash() {
|
||||
return this.raw.length === 34
|
||||
&& this.raw[0] === opcodes.OP_1
|
||||
&& this.raw[1] === 0x20;
|
||||
@ -3088,15 +3112,23 @@ Script.prototype.isUnspendable = function isUnspendable() {
|
||||
/**
|
||||
* "Guess" the type of the input script.
|
||||
* This method is not 100% reliable.
|
||||
* @returns {String}
|
||||
* @returns {ScriptType}
|
||||
*/
|
||||
|
||||
Script.prototype.getInputType = function getInputType() {
|
||||
return (this.isPubkeyInput() && 'pubkey')
|
||||
|| (this.isPubkeyhashInput() && 'pubkeyhash')
|
||||
|| (this.isMultisigInput() && 'multisig')
|
||||
|| (this.isScripthashInput() && 'scripthash')
|
||||
|| 'unknown';
|
||||
if (this.isPubkeyInput())
|
||||
return scriptTypes.PUBKEY;
|
||||
|
||||
if (this.isPubkeyhashInput())
|
||||
return scriptTypes.PUBKEYHASH;
|
||||
|
||||
if (this.isScripthashInput())
|
||||
return scriptTypes.SCRIPTHASH;
|
||||
|
||||
if (this.isMultisigInput())
|
||||
return scriptTypes.MULTISIG;
|
||||
|
||||
return scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -3106,7 +3138,7 @@ Script.prototype.getInputType = function getInputType() {
|
||||
*/
|
||||
|
||||
Script.prototype.isUnknownInput = function isUnknownInput() {
|
||||
return this.getInputType() === 'unknown';
|
||||
return this.getInputType() === scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -4157,10 +4189,10 @@ Script.verify = function verify(input, witness, output, tx, i, flags) {
|
||||
if (flags & constants.flags.VERIFY_P2SH)
|
||||
copy = stack.clone();
|
||||
|
||||
// Execute the previous output script
|
||||
// Execute the previous output script.
|
||||
output.execute(stack, flags, tx, i, 0);
|
||||
|
||||
// Verify the script did not fail as well as the stack values
|
||||
// Verify the stack values.
|
||||
if (stack.length === 0 || !Script.bool(stack.pop()))
|
||||
throw new ScriptError('EVAL_FALSE');
|
||||
|
||||
@ -4171,7 +4203,7 @@ Script.verify = function verify(input, witness, output, tx, i, flags) {
|
||||
if (input.raw.length !== 0)
|
||||
throw new ScriptError('WITNESS_MALLEATED');
|
||||
|
||||
// Verify the program in the output script
|
||||
// Verify the program in the output script.
|
||||
Script.verifyProgram(witness, output, flags, tx, i);
|
||||
|
||||
// Force a cleanstack
|
||||
@ -4195,10 +4227,10 @@ Script.verify = function verify(input, witness, output, tx, i, flags) {
|
||||
raw = stack.pop();
|
||||
redeem = new Script(raw);
|
||||
|
||||
// Execute the redeem script
|
||||
// Execute the redeem script.
|
||||
redeem.execute(stack, flags, tx, i, 0);
|
||||
|
||||
// Verify the script did not fail as well as the stack values
|
||||
// Verify the the stack values.
|
||||
if (stack.length === 0 || !Script.bool(stack.pop()))
|
||||
throw new ScriptError('EVAL_FALSE');
|
||||
|
||||
@ -4209,15 +4241,15 @@ Script.verify = function verify(input, witness, output, tx, i, flags) {
|
||||
if (!utils.equal(input.raw, Opcode.fromPush(raw).toRaw()))
|
||||
throw new ScriptError('WITNESS_MALLEATED_P2SH');
|
||||
|
||||
// Verify the program in the redeem script
|
||||
// Verify the program in the redeem script.
|
||||
Script.verifyProgram(witness, redeem, flags, tx, i);
|
||||
|
||||
// Force a cleanstack
|
||||
// Force a cleanstack.
|
||||
stack.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure there is nothing left on the stack
|
||||
// Ensure there is nothing left on the stack.
|
||||
if (flags & constants.flags.VERIFY_CLEANSTACK) {
|
||||
assert((flags & constants.flags.VERIFY_P2SH) !== 0);
|
||||
// assert((flags & constants.flags.VERIFY_WITNESS) !== 0);
|
||||
@ -4273,7 +4305,7 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i) {
|
||||
|
||||
redeem = Script.fromPubkeyhash(program.data);
|
||||
} else {
|
||||
// Failure on version=0 (bad program data length)
|
||||
// Failure on version=0 (bad program data length).
|
||||
throw new ScriptError('WITNESS_PROGRAM_WRONG_LENGTH');
|
||||
}
|
||||
} else if ((flags & constants.flags.VERIFY_MAST) && program.version === 1) {
|
||||
@ -4341,14 +4373,16 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Witnesses still have push limits.
|
||||
for (j = 0; j < stack.length; j++) {
|
||||
if (stack.get(j).length > constants.script.MAX_PUSH)
|
||||
throw new ScriptError('PUSH_SIZE');
|
||||
}
|
||||
|
||||
// Verify the redeem script.
|
||||
redeem.execute(stack, flags, tx, i, 1);
|
||||
|
||||
// Verify the script did not fail as well as the stack values
|
||||
// Verify the stack values.
|
||||
if (stack.length !== 1 || !Script.bool(stack.pop()))
|
||||
throw new ScriptError('EVAL_FALSE');
|
||||
|
||||
@ -4799,24 +4833,44 @@ function Program(version, data) {
|
||||
if (!(this instanceof Program))
|
||||
return new Program(version, data);
|
||||
|
||||
assert(utils.isNumber(version));
|
||||
assert(Buffer.isBuffer(data));
|
||||
assert(version >= 0 && version <= 16);
|
||||
assert(data.length >= 2 && data.length <= 40);
|
||||
|
||||
this.version = version;
|
||||
this.data = data;
|
||||
this.type = null;
|
||||
|
||||
// TODO: MAST support
|
||||
if (version > 0) {
|
||||
// No interpretation of script (anyone can spend)
|
||||
this.type = 'unknown';
|
||||
} else if (version === 0 && data.length === 20) {
|
||||
this.type = 'witnesspubkeyhash';
|
||||
} else if (version === 0 && data.length === 32) {
|
||||
this.type = 'witnessscripthash';
|
||||
} else {
|
||||
// Fail on bad version=0
|
||||
this.type = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the witness program type.
|
||||
* @returns {ScriptType}
|
||||
*/
|
||||
|
||||
Program.prototype.getType = function getType() {
|
||||
if (this.version === 0) {
|
||||
if (this.data.length === 20)
|
||||
return scriptTypes.WITNESSPUBKEYHASH;
|
||||
|
||||
if (this.data.length === 32)
|
||||
return scriptTypes.WITNESSSCRIPTHASH;
|
||||
|
||||
// Fail on bad version=0
|
||||
return scriptTypes.WITNESSMALFORMED;
|
||||
}
|
||||
|
||||
if (this.version === 1) {
|
||||
if (this.data.length === 32)
|
||||
return scriptTypes.WITNESSMASTHASH;
|
||||
|
||||
// Fail on bad version=1
|
||||
return scriptTypes.WITNESSMALFORMED;
|
||||
}
|
||||
|
||||
// No interpretation of script (anyone can spend)
|
||||
return scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the program is either
|
||||
* an unknown version or malformed.
|
||||
@ -4824,7 +4878,18 @@ function Program(version, data) {
|
||||
*/
|
||||
|
||||
Program.prototype.isUnknown = function isUnknown() {
|
||||
return !this.type || this.type === 'unknown';
|
||||
var type = this.getType();
|
||||
return type === scriptTypes.WITNESSMALFORMED
|
||||
|| type === scriptTypes.NONSTANDARD;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the program is malformed.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Program.prototype.isMalformed = function isMalformed() {
|
||||
return this.getType() === scriptTypes.WITNESSMALFORMED;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -4836,7 +4901,7 @@ Program.prototype.inspect = function inspect() {
|
||||
return '<Program:'
|
||||
+ ' version=' + this.version
|
||||
+ ' data=' + this.data.toString('hex')
|
||||
+ ' type=' + this.type
|
||||
+ ' type=' + constants.scriptTypesByVal[this.getType()].toLowerCase()
|
||||
+ '>';
|
||||
};
|
||||
|
||||
@ -4848,7 +4913,8 @@ exports = Script;
|
||||
|
||||
exports.opcodes = constants.opcodes;
|
||||
exports.opcodesByVal = constants.opcodesByVal;
|
||||
exports.types = constants.scriptTypes;
|
||||
exports.types = scriptTypes;
|
||||
exports.typesByVal = constants.scriptTypesByVal;
|
||||
exports.flags = constants.flags;
|
||||
|
||||
exports.Script = Script;
|
||||
|
||||
@ -27,10 +27,22 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Can be `pubkeyhash`, `scripthash`, `witnesspubkeyhash`,
|
||||
* or `witnessscripthash`, or an address prefix
|
||||
* (see {@link network.address}).
|
||||
* @typedef {String|Number} AddressType
|
||||
* An output script type.
|
||||
* @see {module:constants.scriptTypes}
|
||||
* May sometimes be a string if specified.
|
||||
* @typedef {Number|String} ScriptType
|
||||
* @global
|
||||
*/
|
||||
|
||||
/**
|
||||
* A subset of {@link ScriptType}, including
|
||||
* pubkeyhash, scripthash, witnesspubkeyhash,
|
||||
* and witnessscripthash. This value
|
||||
* specifically refers to the address prefix.
|
||||
* It is a network-agnostic way of representing
|
||||
* prefixes. May sometimes be a string if
|
||||
* specified.
|
||||
* @typedef {Number|String} AddressType
|
||||
* @global
|
||||
*/
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ var constants = bcoin.protocol.constants;
|
||||
var network = bcoin.protocol.network;
|
||||
var utils = bcoin.utils;
|
||||
var assert = require('assert');
|
||||
var scriptTypes = constants.scriptTypes;
|
||||
|
||||
var FAKE_SIG = new Buffer([0,0,0,0,0,0,0,0,0]);
|
||||
|
||||
@ -104,10 +105,12 @@ describe('Wallet', function() {
|
||||
walletdb.create({ witness: witness }, function(err, w) {
|
||||
assert.ifError(err);
|
||||
|
||||
var ad = bcoin.address.fromBase58(w.getAddress('base58'));
|
||||
|
||||
if (witness)
|
||||
assert(bcoin.address.fromBase58(w.getAddress('base58')).type === 'witnesspubkeyhash');
|
||||
assert(ad.type === scriptTypes.WITNESSPUBKEYHASH);
|
||||
else
|
||||
assert(bcoin.address.fromBase58(w.getAddress('base58')).type === 'pubkeyhash');
|
||||
assert(ad.type === scriptTypes.PUBKEYHASH);
|
||||
|
||||
var src = bcoin.mtx({
|
||||
outputs: [{
|
||||
@ -232,7 +235,7 @@ describe('Wallet', function() {
|
||||
w.scriptInputs(fake, function(err) {
|
||||
assert.ifError(err);
|
||||
// Fake signature
|
||||
fake.inputs[0].script.code[0] = bcoin.opcode.fromData(FAKE_SIG);
|
||||
fake.inputs[0].script.set(0, FAKE_SIG);
|
||||
fake.inputs[0].script.compile();
|
||||
// balance: 11000
|
||||
|
||||
@ -609,10 +612,12 @@ describe('Wallet', function() {
|
||||
// Our p2sh address
|
||||
var addr = w1.getAddress('base58');
|
||||
|
||||
var ad = bcoin.address.fromBase58(addr);
|
||||
|
||||
if (witness)
|
||||
assert(bcoin.address.fromBase58(addr).type === 'witnessscripthash');
|
||||
assert(ad.type === scriptTypes.WITNESSSCRIPTHASH);
|
||||
else
|
||||
assert(bcoin.address.fromBase58(addr).type === 'scripthash');
|
||||
assert(ad.type === scriptTypes.SCRIPTHASH);
|
||||
|
||||
assert.equal(w1.getAddress('base58'), addr);
|
||||
assert.equal(w2.getAddress('base58'), addr);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user