fixes and improvements. allow arbitrary redeem scripts for wallet.
This commit is contained in:
parent
442c984c12
commit
cf5a117a3e
@ -739,7 +739,6 @@ script.execute = function execute(s, stack, tx, index, flags, recurse) {
|
||||
|
||||
key = stack.pop();
|
||||
sig = stack.pop();
|
||||
type = sig[sig.length - 1];
|
||||
|
||||
if (!script.isKey(key))
|
||||
return false;
|
||||
@ -752,11 +751,13 @@ script.execute = function execute(s, stack, tx, index, flags, recurse) {
|
||||
return false;
|
||||
}
|
||||
|
||||
type = sig[sig.length - 1];
|
||||
|
||||
if (!constants.hashTypeByVal[type & 0x1f])
|
||||
return false;
|
||||
|
||||
subscript = script.subscript(s, lastSep);
|
||||
hash = tx.subscriptHash(index, subscript, type);
|
||||
hash = tx.signatureHash(index, subscript, type);
|
||||
|
||||
res = script.checksig(hash, sig.slice(0, -1), key);
|
||||
if (o === 'checksigverify') {
|
||||
@ -804,7 +805,6 @@ script.execute = function execute(s, stack, tx, index, flags, recurse) {
|
||||
succ = 0;
|
||||
for (i = 0, j = 0; i < m && j < n; i++) {
|
||||
sig = stack.pop();
|
||||
type = sig[sig.length - 1];
|
||||
|
||||
if (flags.strictder !== false) {
|
||||
if (!script.isValidSig(sig))
|
||||
@ -814,10 +814,12 @@ script.execute = function execute(s, stack, tx, index, flags, recurse) {
|
||||
return false;
|
||||
}
|
||||
|
||||
type = sig[sig.length - 1];
|
||||
|
||||
if (!constants.hashTypeByVal[type & 0x1f])
|
||||
return false;
|
||||
|
||||
hash = tx.subscriptHash(index, subscript, type);
|
||||
hash = tx.signatureHash(index, subscript, type);
|
||||
|
||||
res = false;
|
||||
for (; !res && j < n; j++)
|
||||
@ -830,15 +832,13 @@ script.execute = function execute(s, stack, tx, index, flags, recurse) {
|
||||
// Extra value
|
||||
if (stack.length < 1)
|
||||
return false;
|
||||
|
||||
val = stack.pop();
|
||||
|
||||
if (flags.verifynulldummy !== false) {
|
||||
if (stack[stack.length - 1].length > 0)
|
||||
if (!Array.isArray(val) || val.length > 0)
|
||||
return false;
|
||||
}
|
||||
stack.pop();
|
||||
|
||||
// Too many signatures on stack
|
||||
// if (stack.length > 0)
|
||||
// return false;
|
||||
|
||||
res = succ >= m;
|
||||
if (o === 'checkmultisigverify') {
|
||||
@ -982,16 +982,16 @@ script.size = function size(s) {
|
||||
return bcoin.script.encode(s).length;
|
||||
};
|
||||
|
||||
script.normalize = function normalize(s) {
|
||||
var bytes = true;
|
||||
var i;
|
||||
|
||||
for (i = 0; bytes && i < s.length; i++) {
|
||||
script.isEncoded = function(s) {
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
if (typeof s[i] !== 'number')
|
||||
bytes = false;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (bytes)
|
||||
script.normalize = function normalize(s) {
|
||||
if (script.isEncoded(s))
|
||||
s = script.decode(s);
|
||||
|
||||
s = script.subscript(s);
|
||||
@ -1632,10 +1632,10 @@ script.args = function args(s) {
|
||||
return m + 1;
|
||||
}
|
||||
|
||||
if (this.type === 'scripthash')
|
||||
if (type === 'scripthash')
|
||||
return 1;
|
||||
|
||||
if (this.type === 'nulldata')
|
||||
if (type === 'nulldata')
|
||||
return -1;
|
||||
|
||||
return -1;
|
||||
|
||||
@ -217,7 +217,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
if (typeof index !== 'number')
|
||||
index = this.inputs.indexOf(index);
|
||||
|
||||
if (!type)
|
||||
if (type == null)
|
||||
type = 'all';
|
||||
|
||||
if (typeof type === 'string')
|
||||
@ -238,7 +238,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
}
|
||||
|
||||
// Get the hash of the current tx, minus the other inputs, plus the sighash.
|
||||
hash = this.subscriptHash(index, redeem, type);
|
||||
hash = this.signatureHash(index, redeem, type);
|
||||
|
||||
// Sign the transaction with our one input
|
||||
signature = bcoin.ecdsa.sign(hash, key.priv).toDER();
|
||||
@ -315,7 +315,6 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
}
|
||||
};
|
||||
|
||||
// Build the scriptSig and sign it
|
||||
TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) {
|
||||
var input;
|
||||
|
||||
@ -363,7 +362,6 @@ TX.prototype.output = function output(obj, value) {
|
||||
return this;
|
||||
};
|
||||
|
||||
// compat
|
||||
TX.prototype.out = TX.prototype.output;
|
||||
|
||||
TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
@ -493,7 +491,7 @@ TX.prototype.getSubscript = function getSubscript(index) {
|
||||
return bcoin.script.subscript(script);
|
||||
};
|
||||
|
||||
TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
|
||||
TX.prototype.signatureHash = function signatureHash(index, s, type) {
|
||||
var copy = this.clone();
|
||||
var msg, hash;
|
||||
|
||||
@ -503,6 +501,8 @@ TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
|
||||
if (typeof type === 'string')
|
||||
type = constants.hashType[type];
|
||||
|
||||
assert(type != null);
|
||||
|
||||
// bitcoind used to return 1 as an error code:
|
||||
// it ended up being treated like a hash.
|
||||
if (index >= copy.inputs.length)
|
||||
@ -538,6 +538,8 @@ TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
|
||||
if (i !== index)
|
||||
input.seq = 0;
|
||||
});
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (type & constants.hashType.anyonecanpay) {
|
||||
@ -562,9 +564,6 @@ TX.prototype.verify = function verify(index, force, flags) {
|
||||
if (this.inputs.length === 0)
|
||||
return false;
|
||||
|
||||
if (!flags)
|
||||
flags = {};
|
||||
|
||||
return this.inputs.every(function(input, i) {
|
||||
var output;
|
||||
|
||||
@ -1011,8 +1010,6 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
||||
return false;
|
||||
args += targs;
|
||||
} else {
|
||||
// Bitcoind returns here whether true
|
||||
// or false... strange behavior (bug?)
|
||||
return script.sigops(s, true) <= constants.script.maxScripthashSigops;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ function Wallet(options, passphrase) {
|
||||
this.loaded = false;
|
||||
this.lastTs = 0;
|
||||
this.changeAddress = options.changeAddress || null;
|
||||
this.redeem = options.redeem || options.script;
|
||||
|
||||
if (options.priv instanceof bcoin.hd.priv) {
|
||||
this.hd = options.priv;
|
||||
@ -85,6 +86,12 @@ function Wallet(options, passphrase) {
|
||||
|
||||
this.multisig(options.multisig || {});
|
||||
|
||||
if (this.redeem) {
|
||||
if (!bcoin.script.isEncoded(this.redeem))
|
||||
this.redeem = bcoin.script.encode(this.redeem);
|
||||
this.type = 'scripthash';
|
||||
}
|
||||
|
||||
this.tx = new bcoin.txPool(this);
|
||||
|
||||
this._init();
|
||||
@ -450,7 +457,6 @@ Wallet.prototype.scriptInputs = function scriptInputs(tx) {
|
||||
if (!input.out.tx && this.tx._all[input.out.hash])
|
||||
input.out.tx = this.tx._all[input.out.hash];
|
||||
|
||||
// Filter inputs that this wallet own
|
||||
if (!input.out.tx || !this.ownOutput(input.out.tx))
|
||||
return false;
|
||||
|
||||
@ -466,9 +472,6 @@ Wallet.prototype.signInputs = function signInputs(tx, type) {
|
||||
var key = this.key;
|
||||
var inputs = tx.inputs;
|
||||
|
||||
if (!type)
|
||||
type = 'all';
|
||||
|
||||
inputs = inputs.filter(function(input, i) {
|
||||
if (!input.out.tx && this.tx._all[input.out.hash])
|
||||
input.out.tx = this.tx._all[input.out.hash];
|
||||
@ -485,9 +488,6 @@ Wallet.prototype.signInputs = function signInputs(tx, type) {
|
||||
};
|
||||
|
||||
Wallet.prototype.sign = function sign(tx, type) {
|
||||
if (!type)
|
||||
type = 'all';
|
||||
|
||||
var pub = this.getPublicKey();
|
||||
var redeem = this.getScript();
|
||||
var key = this.key;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user