tests passing.
This commit is contained in:
parent
3d9d6be23c
commit
1804acc77c
@ -110,6 +110,24 @@ script.subscript = function subscript(s) {
|
|||||||
return res;
|
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) {
|
script.execute = function execute(s, stack, tx) {
|
||||||
if (s.length > 10000) {
|
if (s.length > 10000) {
|
||||||
return false;
|
return false;
|
||||||
@ -155,7 +173,7 @@ script.execute = function execute(s, stack, tx) {
|
|||||||
// if (typeof tx === 'function')
|
// if (typeof tx === 'function')
|
||||||
// tx = tx(constants.rhashType[type]);
|
// 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 (o === 'checksigverify') {
|
||||||
if (!res)
|
if (!res)
|
||||||
return false;
|
return false;
|
||||||
@ -205,7 +223,7 @@ script.execute = function execute(s, stack, tx) {
|
|||||||
|
|
||||||
var res = false;
|
var res = false;
|
||||||
for (; !res && j < n; j++)
|
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)
|
if (res)
|
||||||
succ++;
|
succ++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,8 +42,8 @@ function TX(data, block) {
|
|||||||
// ps = Pending Since
|
// ps = Pending Since
|
||||||
this.ps = this.ts === 0 ? +new Date() / 1000 : 0;
|
this.ps = this.ts === 0 ? +new Date() / 1000 : 0;
|
||||||
|
|
||||||
this.m = data.m;
|
this.m = data.m || null;
|
||||||
this.n = data.n;
|
this.n = data.n || null;
|
||||||
this.change = data.change || null;
|
this.change = data.change || null;
|
||||||
this.fee = data.fee || 10000;
|
this.fee = data.fee || 10000;
|
||||||
this.dust = 5460;
|
this.dust = 5460;
|
||||||
@ -146,7 +146,8 @@ TX.prototype.scriptInput = function(input, pub, nsigs) {
|
|||||||
|
|
||||||
// P2PKH and simple tx
|
// P2PKH and simple tx
|
||||||
if (bcoin.script.isPubkeyhash(s) || bcoin.script.isSimplePubkeyhash(s)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,19 +157,23 @@ TX.prototype.scriptInput = function(input, pub, nsigs) {
|
|||||||
nsigs = nsigs || this.m;
|
nsigs = nsigs || this.m;
|
||||||
if (!nsigs)
|
if (!nsigs)
|
||||||
throw new Error('`nsigs` is required for multisig');
|
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++)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// P2SH multisig
|
// P2SH multisig
|
||||||
// p2sh format: OP_FALSE [sig-1] [sig-2] ... [redeem-script]
|
// p2sh format: OP_FALSE [sig-1] [sig-2] ... [redeem-script]
|
||||||
if (bcoin.script.isScripthash(s)) {
|
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;
|
var m = pub[0] - constants.opcodes['1'] + 1;
|
||||||
for (var i = 0; i < m; i++)
|
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
|
// P2SH requires the redeem script after signatures
|
||||||
input.script.push(pub);
|
input.script.push(pub);
|
||||||
return;
|
return;
|
||||||
@ -186,7 +191,7 @@ TX.prototype.signInput = function(input, key, type) {
|
|||||||
var s = input.out.tx.getSubscript(input.out.index);
|
var s = input.out.tx.getSubscript(input.out.index);
|
||||||
|
|
||||||
// Get the hash of the current tx, minus the other inputs, plus the sighash.
|
// 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
|
// Sign the transaction with our one input
|
||||||
var signature = bcoin.ecdsa.sign(hash, key).toDER();
|
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))
|
if (utils.isEqual(input.script[i], signature))
|
||||||
break;
|
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;
|
input.script[i] = signature;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -228,10 +234,10 @@ TX.prototype.signInput = function(input, key, type) {
|
|||||||
// Build the scriptSig and sign it
|
// Build the scriptSig and sign it
|
||||||
TX.prototype.scriptSig = function(input, key, pub, type, nsigs) {
|
TX.prototype.scriptSig = function(input, key, pub, type, nsigs) {
|
||||||
// Build script for input
|
// Build script for input
|
||||||
tx.scriptInput(input, pub, nsigs);
|
this.scriptInput(input, pub, nsigs);
|
||||||
|
|
||||||
// Sign input
|
// Sign input
|
||||||
tx.signInput(input, key, type);
|
this.signInput(input, key, type);
|
||||||
|
|
||||||
return input.script;
|
return input.script;
|
||||||
};
|
};
|
||||||
@ -251,13 +257,15 @@ TX.prototype.output = function output(output, value) {
|
|||||||
value: new bn(output.value),
|
value: new bn(output.value),
|
||||||
script: this.scriptOutput(output)
|
script: this.scriptOutput(output)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
// compat
|
// compat
|
||||||
TX.prototype.out = TX.prototype.output;
|
TX.prototype.out = TX.prototype.output;
|
||||||
|
|
||||||
TX.prototype.scriptOutput = function(options) {
|
TX.prototype.scriptOutput = function(options) {
|
||||||
var script = [];
|
var script = options.script ? options.script.slice() : [];
|
||||||
|
|
||||||
if (Array.isArray(options.keys || options.address)) {
|
if (Array.isArray(options.keys || options.address)) {
|
||||||
// Raw multisig transaction
|
// Raw multisig transaction
|
||||||
@ -360,7 +368,6 @@ TX.prototype.verify = function verify(index, force) {
|
|||||||
if (!res)
|
if (!res)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// XXX sighash_all here?
|
|
||||||
return stack.length > 0 && utils.isEqual(stack.pop(), [ 1 ]);
|
return stack.length > 0 && utils.isEqual(stack.pop(), [ 1 ]);
|
||||||
}, this);
|
}, this);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -316,7 +316,13 @@ Wallet.prototype.balance = function balance() {
|
|||||||
|
|
||||||
Wallet.prototype.fill = function fill(tx, cb) {
|
Wallet.prototype.fill = function fill(tx, cb) {
|
||||||
cb = utils.asyncify(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);
|
this.sign(tx);
|
||||||
cb(null, tx);
|
cb(null, tx);
|
||||||
return tx;
|
return tx;
|
||||||
|
|||||||
@ -52,7 +52,7 @@ describe('Wallet', function() {
|
|||||||
outputs: [{
|
outputs: [{
|
||||||
value: 5460 * 2,
|
value: 5460 * 2,
|
||||||
minSignatures: 1,
|
minSignatures: 1,
|
||||||
address: [ w.getPublicKey(), w.getPublicKey().concat(1) ]
|
keys: [ w.getPublicKey(), w.getPublicKey().concat(1) ]
|
||||||
}, {
|
}, {
|
||||||
value: 5460 * 2,
|
value: 5460 * 2,
|
||||||
address: w.getAddress() + 'x'
|
address: w.getAddress() + 'x'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user