tests passing.

This commit is contained in:
Christopher Jeffrey 2015-12-07 12:28:50 -08:00
parent 3d9d6be23c
commit 1804acc77c
4 changed files with 48 additions and 17 deletions

View File

@ -110,6 +110,24 @@ script.subscript = function subscript(s) {
return res;
};
script.verify = function verify(hash, sig, pub) {
var k = bcoin.ecdsa.keyFromPublic(pub);
// Points at Infinity make verify() throw.
// This specifically throws on wallet-test.js
// where [1] is concatted to the pubkey.
if (k.getPublic().isInfinity())
return false;
// Use a try catch in case there are
// any uncaught errors for bad inputs in verify().
try {
return bcoin.ecdsa.verify(hash, sig, pub);
} catch (e) {
return false;
}
};
script.execute = function execute(s, stack, tx) {
if (s.length > 10000) {
return false;
@ -155,7 +173,7 @@ script.execute = function execute(s, stack, tx) {
// if (typeof tx === 'function')
// tx = tx(constants.rhashType[type]);
var res = bcoin.ecdsa.verify(tx, sig.slice(0, -1), pub);
var res = script.verify(tx, sig.slice(0, -1), pub);
if (o === 'checksigverify') {
if (!res)
return false;
@ -205,7 +223,7 @@ script.execute = function execute(s, stack, tx) {
var res = false;
for (; !res && j < n; j++)
res = bcoin.ecdsa.verify(tx, sig.slice(0, -1), keys[j]);
res = script.verify(tx, sig.slice(0, -1), keys[j]);
if (res)
succ++;
}

View File

@ -42,8 +42,8 @@ function TX(data, block) {
// ps = Pending Since
this.ps = this.ts === 0 ? +new Date() / 1000 : 0;
this.m = data.m;
this.n = data.n;
this.m = data.m || null;
this.n = data.n || null;
this.change = data.change || null;
this.fee = data.fee || 10000;
this.dust = 5460;
@ -146,7 +146,8 @@ TX.prototype.scriptInput = function(input, pub, nsigs) {
// P2PKH and simple tx
if (bcoin.script.isPubkeyhash(s) || bcoin.script.isSimplePubkeyhash(s)) {
input.script = [ constants.opcodes['0'], pub ];
//input.script = [ constants.opcodes['0'], pub ];
input.script = [ [], pub ];
return;
}
@ -156,19 +157,23 @@ TX.prototype.scriptInput = function(input, pub, nsigs) {
nsigs = nsigs || this.m;
if (!nsigs)
throw new Error('`nsigs` is required for multisig');
input.script = [ constants.opcodes['false'] ];
//input.script = [ constants.opcodes['false'] ];
input.script = [ [] ];
for (var i = 0; i < nsigs; i++)
input.script[i + 1] = constants.opcodes['0'];
//input.script[i + 1] = constants.opcodes['0'];
input.script[i + 1] = [];
return;
}
// P2SH multisig
// p2sh format: OP_FALSE [sig-1] [sig-2] ... [redeem-script]
if (bcoin.script.isScripthash(s)) {
input.script = [ constants.opcodes['false'] ];
//input.script = [ constants.opcodes['false'] ];
input.script = [ [] ];
var m = pub[0] - constants.opcodes['1'] + 1;
for (var i = 0; i < m; i++)
input.script[i + 1] = constants.opcodes['0'];
//input.script[i + 1] = constants.opcodes['0'];
input.script[i + 1] = [];
// P2SH requires the redeem script after signatures
input.script.push(pub);
return;
@ -186,7 +191,7 @@ TX.prototype.signInput = function(input, key, type) {
var s = input.out.tx.getSubscript(input.out.index);
// Get the hash of the current tx, minus the other inputs, plus the sighash.
var hash = this.subscriptHash(tx.inputs.indexOf(input), s, type);
var hash = this.subscriptHash(this.inputs.indexOf(input), s, type);
// Sign the transaction with our one input
var signature = bcoin.ecdsa.sign(hash, key).toDER();
@ -214,7 +219,8 @@ TX.prototype.signInput = function(input, key, type) {
if (utils.isEqual(input.script[i], signature))
break;
if (input.script[i] === constants.opcodes['0']) {
//if (input.script[i] === constants.opcodes['0']) {
if (input.script[i].length === 0) {
input.script[i] = signature;
break;
}
@ -228,10 +234,10 @@ TX.prototype.signInput = function(input, key, type) {
// Build the scriptSig and sign it
TX.prototype.scriptSig = function(input, key, pub, type, nsigs) {
// Build script for input
tx.scriptInput(input, pub, nsigs);
this.scriptInput(input, pub, nsigs);
// Sign input
tx.signInput(input, key, type);
this.signInput(input, key, type);
return input.script;
};
@ -251,13 +257,15 @@ TX.prototype.output = function output(output, value) {
value: new bn(output.value),
script: this.scriptOutput(output)
});
return this;
};
// compat
TX.prototype.out = TX.prototype.output;
TX.prototype.scriptOutput = function(options) {
var script = [];
var script = options.script ? options.script.slice() : [];
if (Array.isArray(options.keys || options.address)) {
// Raw multisig transaction
@ -360,7 +368,6 @@ TX.prototype.verify = function verify(index, force) {
if (!res)
return false;
// XXX sighash_all here?
return stack.length > 0 && utils.isEqual(stack.pop(), [ 1 ]);
}, this);
};

View File

@ -316,7 +316,13 @@ Wallet.prototype.balance = function balance() {
Wallet.prototype.fill = function fill(tx, cb) {
cb = utils.asyncify(cb);
tx.fillUnspent(this.unspent(), this.getAddress());
var result = tx.fillUnspent(this.unspent(), this.getAddress());
if (!result) {
var err = new Error('Not enough funds');
err.minBalance = tx.cost;
cb(err);
return null;
}
this.sign(tx);
cb(null, tx);
return tx;

View File

@ -52,7 +52,7 @@ describe('Wallet', function() {
outputs: [{
value: 5460 * 2,
minSignatures: 1,
address: [ w.getPublicKey(), w.getPublicKey().concat(1) ]
keys: [ w.getPublicKey(), w.getPublicKey().concat(1) ]
}, {
value: 5460 * 2,
address: w.getAddress() + 'x'