mtx: refactor.
This commit is contained in:
parent
a42d11cb80
commit
34f59e8a60
@ -623,7 +623,7 @@ KeyRing.prototype.getRedeem = function(hash) {
|
||||
*/
|
||||
|
||||
KeyRing.prototype.scriptInputs = function scriptInputs(tx) {
|
||||
return tx.template(this.publicKey, this.script, this.program);
|
||||
return tx.template(this.publicKey, this.script);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -635,7 +635,7 @@ KeyRing.prototype.scriptInputs = function scriptInputs(tx) {
|
||||
*/
|
||||
|
||||
KeyRing.prototype.sign = function sign(tx, key) {
|
||||
return tx.sign(key, this.script, this.program);
|
||||
return tx.sign(key, this.script);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
393
lib/bcoin/mtx.js
393
lib/bcoin/mtx.js
@ -211,37 +211,16 @@ MTX.prototype.addOutput = function addOutput(options, value) {
|
||||
* Build input script (or witness) templates (with
|
||||
* OP_0 in place of signatures).
|
||||
* @param {Number} index - Input index.
|
||||
* @param {KeyRing} ring - Address used to build. The address
|
||||
* must be able to redeem the coin.
|
||||
* @param {Buffer} key - Public key.
|
||||
* @param {Script} script - Redeem script.
|
||||
* @returns {Boolean} Whether the script was able to be built.
|
||||
* @throws on unavailable coins.
|
||||
*/
|
||||
|
||||
function getRedeem(hash, script, program) {
|
||||
if (program) {
|
||||
if (utils.equal(program.hash160(), hash))
|
||||
return program;
|
||||
}
|
||||
MTX.prototype.scriptInput = function scriptInput(index, key, script) {
|
||||
var input = this.inputs[index];
|
||||
var prev, redeem;
|
||||
|
||||
if (script) {
|
||||
if (utils.equal(script.hash160(), hash))
|
||||
return script;
|
||||
|
||||
if (utils.equal(script.sha256(), hash))
|
||||
return script;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MTX.prototype.buildInput = function buildInput(index, key, script, program) {
|
||||
var input, prev, redeem;
|
||||
|
||||
if (key.getPublicKey)
|
||||
key = key.getPublicKey();
|
||||
|
||||
// Get the input
|
||||
input = this.inputs[index];
|
||||
assert(input);
|
||||
assert(input, 'Input does not exist.');
|
||||
|
||||
// We should have previous outputs by now.
|
||||
if (!input.coin)
|
||||
@ -249,8 +228,13 @@ MTX.prototype.buildInput = function buildInput(index, key, script, program) {
|
||||
|
||||
// Don't bother with any below calculation
|
||||
// if the output is already templated.
|
||||
if (input.script.length !== 0 || input.witness.length !== 0)
|
||||
if (input.script.length !== 0
|
||||
|| input.witness.length !== 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key.getPublicKey)
|
||||
key = key.getPublicKey();
|
||||
|
||||
// Get the previous output's script
|
||||
prev = input.coin.script;
|
||||
@ -259,7 +243,7 @@ MTX.prototype.buildInput = function buildInput(index, key, script, program) {
|
||||
// with segwit: figuring out where the redeem script and witness
|
||||
// redeem scripts go.
|
||||
if (prev.isScripthash()) {
|
||||
redeem = getRedeem(prev.get(1), script, program);
|
||||
redeem = this._getRedeem(prev.get(1), key, script);
|
||||
|
||||
if (!redeem)
|
||||
return false;
|
||||
@ -268,22 +252,31 @@ MTX.prototype.buildInput = function buildInput(index, key, script, program) {
|
||||
if (redeem.isProgram()) {
|
||||
// P2WSH nested within pay-to-scripthash.
|
||||
if (redeem.isWitnessScripthash()) {
|
||||
prev = getRedeem(redeem.get(1), script, program);
|
||||
prev = this._getRedeem(redeem.get(1), key, script);
|
||||
|
||||
if (!prev)
|
||||
return false;
|
||||
this.scriptVector(prev, input.witness, key);
|
||||
|
||||
if (!this.scriptVector(prev, input.witness, key))
|
||||
return false;
|
||||
|
||||
input.witness.push(prev.toRaw());
|
||||
input.script.push(redeem.toRaw());
|
||||
input.script.compile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// P2WPKH nested within pay-to-scripthash.
|
||||
if (redeem.isWitnessPubkeyhash()) {
|
||||
prev = Script.fromPubkeyhash(utils.hash160(key));
|
||||
this.scriptVector(prev, input.witness, key);
|
||||
|
||||
if (!this.scriptVector(prev, input.witness, key))
|
||||
return false;
|
||||
|
||||
input.script.push(redeem.toRaw());
|
||||
input.script.compile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -292,9 +285,12 @@ MTX.prototype.buildInput = function buildInput(index, key, script, program) {
|
||||
}
|
||||
|
||||
// Regular P2SH.
|
||||
this.scriptVector(redeem, input.script, key);
|
||||
if (!this.scriptVector(redeem, input.script, key))
|
||||
return false;
|
||||
|
||||
input.script.push(redeem.toRaw());
|
||||
input.script.compile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -302,22 +298,29 @@ MTX.prototype.buildInput = function buildInput(index, key, script, program) {
|
||||
if (prev.isProgram()) {
|
||||
// Bare P2WSH.
|
||||
if (prev.isWitnessScripthash()) {
|
||||
redeem = getRedeem(prev.get(1), script, program);
|
||||
redeem = this._getRedeem(prev.get(1), key, script);
|
||||
|
||||
if (!redeem)
|
||||
return false;
|
||||
|
||||
this.scriptVector(redeem, input.witness, key);
|
||||
if (!this.scriptVector(redeem, input.witness, key))
|
||||
return false;
|
||||
|
||||
input.witness.push(redeem.toRaw());
|
||||
input.script.compile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Bare P2WPKH.
|
||||
if (prev.isWitnessPubkeyhash()) {
|
||||
prev = Script.fromPubkeyhash(prev.get(1));
|
||||
this.scriptVector(prev, input.witness, key);
|
||||
|
||||
if (!this.scriptVector(prev, input.witness, key))
|
||||
return false;
|
||||
|
||||
input.script.compile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -326,10 +329,18 @@ MTX.prototype.buildInput = function buildInput(index, key, script, program) {
|
||||
}
|
||||
|
||||
// Wow, a normal output! Praise be to Jengus and Gord.
|
||||
this.scriptVector(prev, input.script, key);
|
||||
return true;
|
||||
return this.scriptVector(prev, input.script, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Build script for a single vector
|
||||
* based on a previous script.
|
||||
* @param {Script} prev
|
||||
* @param {Witness|Script} vector
|
||||
* @param {Buffer} key
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
MTX.prototype.scriptVector = function scriptVector(prev, vector, key) {
|
||||
var i, n;
|
||||
|
||||
@ -338,10 +349,6 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, key) {
|
||||
if (!utils.equal(prev.get(1), key))
|
||||
return false;
|
||||
|
||||
// Already has a script template (at least)
|
||||
if (vector.length !== 0)
|
||||
return true;
|
||||
|
||||
vector.set(0, opcodes.OP_0);
|
||||
|
||||
return true;
|
||||
@ -352,10 +359,6 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, key) {
|
||||
if (!utils.equal(prev.get(2), utils.hash160(key)))
|
||||
return false;
|
||||
|
||||
// Already has a script template (at least)
|
||||
if (vector.length !== 0)
|
||||
return true;
|
||||
|
||||
vector.set(0, opcodes.OP_0);
|
||||
vector.set(1, key);
|
||||
|
||||
@ -367,10 +370,6 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, key) {
|
||||
if (prev.indexOf(key) === -1)
|
||||
return false;
|
||||
|
||||
// Already has a script template (at least)
|
||||
if (vector.length !== 0)
|
||||
return true;
|
||||
|
||||
// Technically we should create m signature slots,
|
||||
// but we create n signature slots so we can order
|
||||
// the signatures properly.
|
||||
@ -386,35 +385,61 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (prev.indexOf(key) === -1)
|
||||
return false;
|
||||
return false;
|
||||
};
|
||||
|
||||
// Already has a script template (at least)
|
||||
if (vector.length !== 0)
|
||||
return true;
|
||||
/**
|
||||
* Calculate a redeem script based on hash.
|
||||
* Test against passed in redeem script.
|
||||
* @private
|
||||
* @param {Buffer} hash - 32 or 20 byte hash.
|
||||
* @param {Buffer} key - Public key.
|
||||
* @param {Script} script - Known redeem script.
|
||||
* @returns {Script|null}
|
||||
*/
|
||||
|
||||
// Likely a non-standard scripthash multisig
|
||||
// input. Determine n value by counting keys.
|
||||
// Also, only allow nonstandard types for
|
||||
// scripthash.
|
||||
vector.set(0, opcodes.OP_0);
|
||||
MTX.prototype._getRedeem = function getRedeem(hash, key, script) {
|
||||
var program;
|
||||
|
||||
// Fill script with `n` signature slots.
|
||||
for (i = 0; i < prev.length; i++) {
|
||||
if (Script.isKey(prev.get(i)))
|
||||
vector.set(i + 1, opcodes.OP_0);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
switch (hash.length) {
|
||||
case 20:
|
||||
program = bcoin.script.fromProgram(0, utils.hash160(key));
|
||||
|
||||
if (utils.equal(program.hash160(), hash))
|
||||
return program;
|
||||
|
||||
if (!script)
|
||||
return;
|
||||
|
||||
program = script.forWitness();
|
||||
|
||||
if (utils.equal(program.hash160(), hash))
|
||||
return program;
|
||||
|
||||
if (utils.equal(script.hash160(), hash))
|
||||
return script;
|
||||
|
||||
break;
|
||||
case 32:
|
||||
if (!script)
|
||||
return;
|
||||
|
||||
if (utils.equal(script.sha256(), hash))
|
||||
return script;
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign an input.
|
||||
* @param {Number} index - Index of input being signed.
|
||||
* @param {KeyRing} ring - Address used to sign. The address
|
||||
* must be able to redeem the coin.
|
||||
* @param {HDPrivateKey|KeyPair|Buffer} key - Private key.
|
||||
* @param {SighashType} type
|
||||
* @returns {Boolean} Whether the input was able to be signed.
|
||||
* @throws on unavailable coins.
|
||||
*/
|
||||
|
||||
MTX.prototype.signInput = function signInput(index, key, type) {
|
||||
@ -423,15 +448,15 @@ MTX.prototype.signInput = function signInput(index, key, type) {
|
||||
var redeem = false;
|
||||
var prev, vector, sig, result;
|
||||
|
||||
assert(input);
|
||||
|
||||
if (key.getPrivateKey)
|
||||
key = key.getPrivateKey();
|
||||
assert(input, 'Input does not exist.');
|
||||
|
||||
// We should have previous outputs by now.
|
||||
if (!input.coin)
|
||||
return false;
|
||||
|
||||
if (key.getPrivateKey)
|
||||
key = key.getPrivateKey();
|
||||
|
||||
// Get the previous output's script
|
||||
prev = input.coin.script;
|
||||
vector = input.script;
|
||||
@ -465,7 +490,7 @@ MTX.prototype.signInput = function signInput(index, key, type) {
|
||||
}
|
||||
|
||||
// Create our signature.
|
||||
sig = this.createSignature(index, prev, key, type, version);
|
||||
sig = this.signature(index, prev, key, type, version);
|
||||
|
||||
if (redeem) {
|
||||
redeem = vector.pop();
|
||||
@ -478,9 +503,19 @@ MTX.prototype.signInput = function signInput(index, key, type) {
|
||||
return this.signVector(prev, vector, sig, key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a signature to a vector
|
||||
* based on a previous script.
|
||||
* @param {Script} prev
|
||||
* @param {Witness|Script} vector
|
||||
* @param {Buffer} sig
|
||||
* @param {Buffer} key
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
MTX.prototype.signVector = function signVector(prev, vector, sig, key) {
|
||||
var pub = bcoin.ec.publicKeyCreate(key, true);
|
||||
var keys, i, m, n, signatures, keyIndex;
|
||||
var i, m, n, keys, keyIndex, total;
|
||||
|
||||
// P2PK
|
||||
if (prev.isPubkey()) {
|
||||
@ -534,102 +569,109 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, key) {
|
||||
|
||||
// Grab `n` value (number of keys).
|
||||
n = prev.getSmall(prev.length - 2);
|
||||
} else {
|
||||
keys = [];
|
||||
|
||||
for (i = 0; i < prev.length; i++) {
|
||||
if (Script.isKey(prev.get(i)))
|
||||
keys.push(prev.get(i));
|
||||
if (vector.getSmall(0) !== 0)
|
||||
throw new Error('Input has not been templated.');
|
||||
|
||||
// Too many signature slots. Abort.
|
||||
if (vector.length - 1 > n)
|
||||
return false;
|
||||
|
||||
// Count the number of current signatures.
|
||||
total = 0;
|
||||
for (i = 1; i < vector.length; i++) {
|
||||
if (Script.isSignature(vector.get(i)))
|
||||
total++;
|
||||
}
|
||||
|
||||
// We don't know what m is, so
|
||||
// we can never finalize the signatures.
|
||||
m = keys.length;
|
||||
n = keys.length;
|
||||
}
|
||||
// Signatures are already finalized.
|
||||
if (total === m && vector.length - 1 === m)
|
||||
return true;
|
||||
|
||||
if (vector.getSmall(0) !== 0)
|
||||
throw new Error('Input has not been templated.');
|
||||
// Add some signature slots for us to use if
|
||||
// there was for some reason not enough.
|
||||
while (vector.length - 1 < n)
|
||||
vector.push(opcodes.OP_0);
|
||||
|
||||
// Too many signature slots. Abort.
|
||||
if (vector.length - 1 > n)
|
||||
return false;
|
||||
// Find the key index so we can place
|
||||
// the signature in the same index.
|
||||
keyIndex = utils.indexOf(keys, pub);
|
||||
|
||||
// Count the number of current signatures.
|
||||
signatures = 0;
|
||||
for (i = 1; i < vector.length; i++) {
|
||||
if (Script.isSignature(vector.get(i)))
|
||||
signatures++;
|
||||
}
|
||||
// Our public key is not in the prev_out
|
||||
// script. We tried to sign a transaction
|
||||
// that is not redeemable by us.
|
||||
if (keyIndex === -1)
|
||||
return false;
|
||||
|
||||
// Offset key index by one to turn it into
|
||||
// "sig index". Accounts for OP_0 byte at
|
||||
// the start.
|
||||
keyIndex++;
|
||||
|
||||
// Add our signature to the correct slot
|
||||
// and increment the total number of
|
||||
// signatures.
|
||||
if (keyIndex < vector.length && total < m) {
|
||||
if (vector.getSmall(keyIndex) === 0) {
|
||||
vector.set(keyIndex, sig);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
// All signatures added. Finalize.
|
||||
if (total >= m) {
|
||||
// Remove empty slots left over.
|
||||
for (i = vector.length - 1; i >= 1; i--) {
|
||||
if (vector.getSmall(i) === 0)
|
||||
vector.remove(i);
|
||||
}
|
||||
|
||||
// Remove signatures which are not required.
|
||||
// This should never happen.
|
||||
while (total > m) {
|
||||
vector.pop();
|
||||
total--;
|
||||
}
|
||||
|
||||
// Sanity checks.
|
||||
assert(total === m);
|
||||
assert(vector.length - 1 === m);
|
||||
}
|
||||
|
||||
vector.compile();
|
||||
|
||||
if (total !== m)
|
||||
return false;
|
||||
|
||||
// Signatures are already finalized.
|
||||
if (signatures === m && vector.length - 1 === m)
|
||||
return true;
|
||||
|
||||
// Add some signature slots for us to use if
|
||||
// there was for some reason not enough.
|
||||
while (vector.length - 1 < n)
|
||||
vector.push(opcodes.OP_0);
|
||||
|
||||
// Find the key index so we can place
|
||||
// the signature in the same index.
|
||||
keyIndex = utils.indexOf(keys, pub);
|
||||
|
||||
// Our public key is not in the prev_out
|
||||
// script. We tried to sign a transaction
|
||||
// that is not redeemable by us.
|
||||
if (keyIndex === -1)
|
||||
return false;
|
||||
|
||||
// Offset key index by one to turn it into
|
||||
// "sig index". Accounts for OP_0 byte at
|
||||
// the start.
|
||||
keyIndex++;
|
||||
|
||||
// Add our signature to the correct slot
|
||||
// and increment the total number of
|
||||
// signatures.
|
||||
if (keyIndex < vector.length && signatures < m) {
|
||||
if (vector.getSmall(keyIndex) === 0) {
|
||||
vector.set(keyIndex, sig);
|
||||
signatures++;
|
||||
}
|
||||
}
|
||||
|
||||
// All signatures added. Finalize.
|
||||
if (signatures >= m) {
|
||||
// Remove empty slots left over.
|
||||
for (i = vector.length - 1; i >= 1; i--) {
|
||||
if (vector.getSmall(i) === 0)
|
||||
vector.remove(i);
|
||||
}
|
||||
|
||||
// Remove signatures which are not required.
|
||||
// This should never happen.
|
||||
while (signatures > m) {
|
||||
vector.pop();
|
||||
signatures--;
|
||||
}
|
||||
|
||||
// Sanity checks.
|
||||
assert(signatures === m);
|
||||
assert(vector.length - 1 === m);
|
||||
}
|
||||
|
||||
vector.compile();
|
||||
|
||||
return signatures === m;
|
||||
return false;
|
||||
};
|
||||
|
||||
MTX.prototype.combineMultisig = function combineMultisig(index, prev, version, script, signature) {
|
||||
/**
|
||||
* Combine and sort multisig signatures for script.
|
||||
* Mimics bitcoind's behavior.
|
||||
* @param {Number} index
|
||||
* @param {Script} prev
|
||||
* @param {Witness|Script} vector
|
||||
* @param {Number} version
|
||||
* @param {Buffer} data
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
MTX.prototype.combine = function combine(index, prev, vector, version, data) {
|
||||
var m = prev.getSmall(0);
|
||||
var sigs = [signature];
|
||||
var sigs = [];
|
||||
var map = {};
|
||||
var result;
|
||||
var result = false;
|
||||
var i, j, sig, type, msg, key, pub, res;
|
||||
|
||||
for (i = 1; i < script.length; i++) {
|
||||
sig = script.get(i);
|
||||
if (data)
|
||||
sigs.push(data);
|
||||
|
||||
for (i = 1; i < vector.length; i++) {
|
||||
sig = vector.get(i);
|
||||
if (Script.isSignature(sig))
|
||||
sigs.push(sig);
|
||||
}
|
||||
@ -651,27 +693,29 @@ MTX.prototype.combineMultisig = function combineMultisig(index, prev, version, s
|
||||
|
||||
if (res) {
|
||||
map[pub] = sig;
|
||||
if (utils.equal(sig, signature))
|
||||
if (utils.equal(sig, data))
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
script.clear();
|
||||
script.push(opcodes.OP_0);
|
||||
vector.clear();
|
||||
vector.push(opcodes.OP_0);
|
||||
|
||||
for (i = 1; i < prev.length - 2; i++) {
|
||||
key = prev.get(i);
|
||||
pub = key.toString('hex');
|
||||
sig = map[pub];
|
||||
if (sig)
|
||||
script.push(sig);
|
||||
vector.push(sig);
|
||||
}
|
||||
|
||||
while (script.length - 1 < m)
|
||||
script.push(opcodes.OP_0);
|
||||
while (vector.length - 1 < m)
|
||||
vector.push(opcodes.OP_0);
|
||||
|
||||
vector.compile();
|
||||
|
||||
script.compile();
|
||||
return result;
|
||||
};
|
||||
|
||||
@ -686,7 +730,7 @@ MTX.prototype.combineMultisig = function combineMultisig(index, prev, version, s
|
||||
* @returns {Buffer} Signature in DER format.
|
||||
*/
|
||||
|
||||
MTX.prototype.createSignature = function createSignature(index, prev, key, type, version) {
|
||||
MTX.prototype.signature = function signature(index, prev, key, type, version) {
|
||||
var hash;
|
||||
|
||||
if (type == null)
|
||||
@ -703,7 +747,6 @@ MTX.prototype.createSignature = function createSignature(index, prev, key, type,
|
||||
return Script.sign(hash, key, type);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Test whether the transaction is fully-signed.
|
||||
* @returns {Boolean}
|
||||
@ -754,10 +797,16 @@ MTX.prototype.isSigned = function isSigned() {
|
||||
if (prev.isPubkey()) {
|
||||
if (!Script.isSignature(vector.get(0)))
|
||||
return false;
|
||||
} else if (prev.isPubkeyhash()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev.isPubkeyhash()) {
|
||||
if (!Script.isSignature(vector.get(0)))
|
||||
return false;
|
||||
} else if (prev.isMultisig()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev.isMultisig()) {
|
||||
// Grab `m` value (number of required sigs).
|
||||
m = prev.getSmall(0);
|
||||
|
||||
@ -771,9 +820,11 @@ MTX.prototype.isSigned = function isSigned() {
|
||||
// of required signatures.
|
||||
if (len - 1 !== m)
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -790,7 +841,7 @@ MTX.prototype.isSigned = function isSigned() {
|
||||
* @throws on unavailable coins.
|
||||
*/
|
||||
|
||||
MTX.prototype.template = function template(key, script, program, type) {
|
||||
MTX.prototype.template = function template(key, script) {
|
||||
var total = 0;
|
||||
var i;
|
||||
|
||||
@ -799,7 +850,7 @@ MTX.prototype.template = function template(key, script, program, type) {
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
// Build script for input
|
||||
if (!this.buildInput(i, key, script, program))
|
||||
if (!this.scriptInput(i, key, script))
|
||||
continue;
|
||||
total++;
|
||||
}
|
||||
@ -818,7 +869,7 @@ MTX.prototype.template = function template(key, script, program, type) {
|
||||
* @throws on unavailable coins.
|
||||
*/
|
||||
|
||||
MTX.prototype.sign = function sign(key, script, program, type) {
|
||||
MTX.prototype.sign = function sign(key, script, type) {
|
||||
var total = 0;
|
||||
var i, pub;
|
||||
|
||||
@ -829,7 +880,7 @@ MTX.prototype.sign = function sign(key, script, program, type) {
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
// Build script for input
|
||||
if (!this.buildInput(i, pub, script, program))
|
||||
if (!this.scriptInput(i, pub, script))
|
||||
continue;
|
||||
|
||||
// Sign input
|
||||
@ -1465,7 +1516,7 @@ MTX.isMTX = function isMTX(obj) {
|
||||
return obj
|
||||
&& Array.isArray(obj.inputs)
|
||||
&& typeof obj.locktime === 'number'
|
||||
&& typeof obj.buildInput === 'function';
|
||||
&& typeof obj.scriptInput === 'function';
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -3085,6 +3085,29 @@ Script.prototype.toProgram = function toProgram() {
|
||||
return new Program(version, data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the script to the equivalent witness
|
||||
* program (mimics bitcoind's scriptForWitness).
|
||||
* @returns {Program|null}
|
||||
*/
|
||||
|
||||
Script.prototype.forWitness = function() {
|
||||
var hash;
|
||||
|
||||
if (this.isProgram())
|
||||
return this;
|
||||
|
||||
if (this.isPubkey()) {
|
||||
hash = utils.hash160(this.get(0));
|
||||
return Script.fromProgram(0, hash);
|
||||
}
|
||||
|
||||
if (this.isPubkeyhash())
|
||||
return Script.fromProgram(0, this.get(2));
|
||||
|
||||
return Script.fromProgram(0, this.sha256());
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the output script is
|
||||
* a pay-to-witness-pubkeyhash program.
|
||||
|
||||
@ -879,8 +879,8 @@ Wallet.prototype.fund = function fund(tx, options, callback, force) {
|
||||
height: self.db.height,
|
||||
rate: rate,
|
||||
wallet: self,
|
||||
m: self.m,
|
||||
n: self.n
|
||||
m: account.m,
|
||||
n: account.n
|
||||
});
|
||||
} catch (e) {
|
||||
return callback(e);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user