signature work. script function renames. add wallet.fillTX/tx.fill.
This commit is contained in:
parent
6f86ca2d02
commit
b77314dd0f
@ -743,11 +743,11 @@ script.execute = function execute(s, stack, tx, index, flags, recurse) {
|
||||
if (!script.isKey(key))
|
||||
return false;
|
||||
|
||||
if (!script.isSig(sig))
|
||||
if (!script.isSignature(sig))
|
||||
return false;
|
||||
|
||||
if (flags.strictder !== false) {
|
||||
if (!script.isValidSig(sig))
|
||||
if (!script.isValidSignature(sig))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -815,11 +815,11 @@ script.execute = function execute(s, stack, tx, index, flags, recurse) {
|
||||
for (i = 0, j = 0; i < m && j < n; i++) {
|
||||
sig = stack.pop();
|
||||
|
||||
if (!script.isSig(sig))
|
||||
if (!script.isSignature(sig))
|
||||
return false;
|
||||
|
||||
if (flags.strictder !== false) {
|
||||
if (!script.isValidSig(sig))
|
||||
if (!script.isValidSignature(sig))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1193,7 +1193,7 @@ script.isPubkeyInput = function isPubkeyInput(s, key, tx, i) {
|
||||
if (s.length !== 1 || !Array.isArray(s[0]))
|
||||
return false;
|
||||
|
||||
if (!script.isSig(s[0]))
|
||||
if (!script.isSignature(s[0]))
|
||||
return false;
|
||||
|
||||
// Execute the script against our key's
|
||||
@ -1211,7 +1211,7 @@ script.isPubkeyhashInput = function isPubkeyhashInput(s, key) {
|
||||
if (s.length !== 2 || !Array.isArray(s[0]) || !Array.isArray(s[1]))
|
||||
return false;
|
||||
|
||||
if (!script.isSig(s[0]))
|
||||
if (!script.isSignature(s[0]))
|
||||
return false;
|
||||
|
||||
if (!script.isKey(s[1]))
|
||||
@ -1240,7 +1240,7 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
|
||||
return false;
|
||||
|
||||
for (i = 1; i < s.length; i++) {
|
||||
if (!script.isSig(s[i]))
|
||||
if (!script.isSignature(s[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1411,7 +1411,7 @@ script.isKey = function isKey(key) {
|
||||
return key.length >= 33 && key.length <= 65;
|
||||
};
|
||||
|
||||
script.isSig = function isSig(sig, allowZero) {
|
||||
script.isSignature = function isSignature(sig, allowZero) {
|
||||
if (!utils.isBuffer(sig))
|
||||
return false;
|
||||
|
||||
@ -1432,7 +1432,7 @@ script.isSig = function isSig(sig, allowZero) {
|
||||
*
|
||||
* This function is consensus-critical since BIP66.
|
||||
*/
|
||||
script.isValidSig = function isValidSig(sig, allowZero) {
|
||||
script.isValidSignature = function isValidSignature(sig, allowZero) {
|
||||
var lenR, lenS;
|
||||
|
||||
if (!utils.isBuffer(sig))
|
||||
|
||||
136
lib/bcoin/tx.js
136
lib/bcoin/tx.js
@ -158,7 +158,7 @@ TX.prototype._inputIndex = function _inputIndex(hash, index) {
|
||||
|
||||
// Build the scriptSigs for inputs, excluding the signatures
|
||||
TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
||||
var input, s, standard, n, i;
|
||||
var input, s, n, i;
|
||||
|
||||
if (typeof index !== 'number')
|
||||
index = this.inputs.indexOf(index);
|
||||
@ -167,6 +167,9 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
||||
input = this.inputs[index];
|
||||
assert(input);
|
||||
|
||||
// We should have previous outputs by now.
|
||||
assert(input.out.tx);
|
||||
|
||||
// Get the previous output's subscript
|
||||
s = input.out.tx.getSubscript(input.out.index);
|
||||
|
||||
@ -194,10 +197,13 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
||||
// but we create n signature slots so we can order
|
||||
// the signatures properly.
|
||||
input.script = [ [] ];
|
||||
|
||||
// Grab `n` value (number of keys).
|
||||
n = s[s.length - 2];
|
||||
// If using pushdata instead of OP_1-16:
|
||||
if (Array.isArray(n))
|
||||
n = n[0] || 0;
|
||||
|
||||
// Fill script with `n` signature slots.
|
||||
for (i = 0; i < n; i++)
|
||||
input.script[i + 1] = [];
|
||||
}
|
||||
@ -212,7 +218,7 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
||||
// Sign the now-built scriptSigs
|
||||
TX.prototype.signInput = function signInput(index, key, type) {
|
||||
var input, s, hash, signature;
|
||||
var len, redeem, m, keys, pub, pubn, ki, signatures, i;
|
||||
var len, redeem, m, n, keys, pub, pubn, ki, signatures, i;
|
||||
|
||||
if (typeof index !== 'number')
|
||||
index = this.inputs.indexOf(index);
|
||||
@ -227,6 +233,9 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
input = this.inputs[index];
|
||||
assert(input);
|
||||
|
||||
// We should have previous outputs by now.
|
||||
assert(input.out.tx);
|
||||
|
||||
// Get the previous output's subscript
|
||||
s = input.out.tx.getSubscript(input.out.index);
|
||||
|
||||
@ -256,19 +265,56 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
len--;
|
||||
}
|
||||
|
||||
// Add signatures.
|
||||
if (bcoin.script.isPubkey(s)) {
|
||||
// P2PK
|
||||
input.script[0] = signature;
|
||||
if (Array.isArray(input.script[0]) && !input.script[0].length)
|
||||
input.script[0] = signature;
|
||||
return true;
|
||||
} else if (bcoin.script.isPubkeyhash(s)) {
|
||||
// P2PKH
|
||||
input.script[0] = signature;
|
||||
if (Array.isArray(input.script[0]) && !input.script[0].length)
|
||||
input.script[0] = signature;
|
||||
return true;
|
||||
} else if (bcoin.script.isMultisig(s)) {
|
||||
// Multisig
|
||||
|
||||
// Grab `m` value (number of sigs required).
|
||||
m = s[0];
|
||||
// If using pushdata instead of OP_1-16:
|
||||
if (Array.isArray(m))
|
||||
m = m[0] || 0;
|
||||
|
||||
// Grab `n` value (number of keys).
|
||||
n = s[s.length - 2];
|
||||
if (Array.isArray(m))
|
||||
n = n[0] || 0;
|
||||
|
||||
// Something is very wrong here. Abort.
|
||||
if (m < 1 || m > 15 || n < m || n > 15 || len - 1 > n)
|
||||
return;
|
||||
|
||||
// Count the number of current signatures.
|
||||
signatures = 0;
|
||||
for (i = 1; i < len; i++) {
|
||||
if (Array.isArray(input.script[i]) && input.script[i].length)
|
||||
signatures++;
|
||||
}
|
||||
|
||||
// Signatures are already finalized.
|
||||
if (signatures === m && len - 1 === m)
|
||||
return;
|
||||
|
||||
// This can happen in a case where another
|
||||
// implementation adds signatures willy-nilly
|
||||
// or by `m`. Add some signature slots for
|
||||
// us to use.
|
||||
while (len - 1 < n) {
|
||||
input.script.splice(len, 0, []);
|
||||
len++;
|
||||
}
|
||||
|
||||
// Grab the redeem script's keys to figure
|
||||
// out where our key should go.
|
||||
keys = s.slice(1, -2);
|
||||
pub = key.getPublic(true, 'array');
|
||||
pubn = key.getPublic(false, 'array');
|
||||
@ -280,39 +326,57 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Public key is not in the prev_out script
|
||||
// Our public key is not in the prev_out
|
||||
// script. We tried to sign a transaction
|
||||
// that is not redeemable by us.
|
||||
if (ki === keys.length)
|
||||
return;
|
||||
|
||||
// No signature slot available
|
||||
if (ki + 1 > len - 1)
|
||||
return;
|
||||
// Offset key index by one to turn it into
|
||||
// "sig index". Accounts for OP_0 byte at
|
||||
// the start.
|
||||
ki++;
|
||||
|
||||
// Add our signature to the correct slot
|
||||
// and count the total number of signatures.
|
||||
signatures = 0;
|
||||
for (i = 1; i < len; i++) {
|
||||
if (Array.isArray(input.script[i]) && input.script[i].length) {
|
||||
signatures++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i - 1 === ki) {
|
||||
if (signatures >= m)
|
||||
continue;
|
||||
input.script[i] = signature;
|
||||
// and increment the total number of
|
||||
// signatures.
|
||||
if (ki < len && signatures < m) {
|
||||
if (Array.isArray(input.script[ki]) && !input.script[ki].length) {
|
||||
input.script[ki] = signature;
|
||||
signatures++;
|
||||
}
|
||||
}
|
||||
|
||||
// All signatures added. Finalize by removing empty slots.
|
||||
// All signatures added. Finalize.
|
||||
if (signatures >= m) {
|
||||
// Remove empty slots left over.
|
||||
for (i = len - 1; i >= 1; i--) {
|
||||
if (Array.isArray(input.script[i]) && !input.script[i].length)
|
||||
if (Array.isArray(input.script[i]) && !input.script[i].length) {
|
||||
input.script.splice(i, 1);
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove signatures which are not required.
|
||||
// If just using bcoin for signing, this
|
||||
// should never happen except with dealing
|
||||
// with implementations that potentially
|
||||
// handle signature slots differently.
|
||||
while (signatures > m) {
|
||||
input.script.splice(len - 1, 1);
|
||||
signatures--;
|
||||
len--;
|
||||
}
|
||||
|
||||
// Sanity checks.
|
||||
assert.equal(signatures, m);
|
||||
assert.equal(len - 1, m);
|
||||
}
|
||||
|
||||
return signatures === m;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) {
|
||||
@ -857,6 +921,30 @@ TX.prototype.funds = function funds(side) {
|
||||
return acc;
|
||||
};
|
||||
|
||||
TX.prototype.fill = function fill(txs) {
|
||||
var inputs;
|
||||
|
||||
if (txs instanceof bcoin.txPool)
|
||||
txs = txs._all;
|
||||
else if (txs instanceof bcoin.wallet)
|
||||
txs = txs.tx._all;
|
||||
|
||||
if (Array.isArray(txs)) {
|
||||
txs = txs.reduce(function(out, tx) {
|
||||
out[tx.hash('hex')] = tx;
|
||||
return out;
|
||||
}, {});
|
||||
}
|
||||
|
||||
inputs = this.inputs.filter(function(input) {
|
||||
if (!input.out.tx && txs[input.out.hash])
|
||||
input.out.tx = txs[input.out.hash];
|
||||
return !!input.out.tx;
|
||||
}, this);
|
||||
|
||||
return inputs.length === this.inputs.length;
|
||||
};
|
||||
|
||||
// Used for postVerify/ContextualBlockCheck and miner isFinalTx call.
|
||||
// BIP113 will require that time-locked transactions have nLockTime set to
|
||||
// less than the median time of the previous block they're contained in.
|
||||
|
||||
@ -242,7 +242,7 @@ Wallet.prototype.getPrivateKey = function getPrivateKey(enc) {
|
||||
return priv;
|
||||
};
|
||||
|
||||
Wallet.prototype.getScript = function getScript(enc) {
|
||||
Wallet.prototype.getScript = function getScript() {
|
||||
if (this.redeem)
|
||||
return this.redeem.slice();
|
||||
return bcoin.script.encode(bcoin.script.redeem(this.keys, this.m, this.n));
|
||||
@ -448,6 +448,10 @@ Wallet.prototype.fillUnspent = function fillUnspent(tx, changeAddress) {
|
||||
return tx.fillUnspent(this.unspent(), changeAddress);
|
||||
};
|
||||
|
||||
Wallet.prototype.fillTX = function fillTX(tx) {
|
||||
return tx.fill(this);
|
||||
};
|
||||
|
||||
Wallet.prototype.scriptInputs = function scriptInputs(tx) {
|
||||
var pub = this.getPublicKey();
|
||||
var redeem = this.getScript();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user