implement all sighash types. add hasUnspent().

This commit is contained in:
Christopher Jeffrey 2015-12-15 01:21:11 -08:00
parent b0a3a0e853
commit c68ab4ee7d
4 changed files with 87 additions and 15 deletions

View File

@ -135,7 +135,7 @@ exports.hashType = {
all: 1,
none: 2,
single: 3,
anyonecaypay: 0x80
anyonecanpay: 0x80
};
exports.rhashType = Object.keys(exports.hashType).reduce(function(out, type) {

View File

@ -88,19 +88,21 @@ script.encode = function encode(s) {
return res;
};
script.subscript = function subscript(s) {
script.subscript = function subscript(s, lastSep) {
if (!s)
return [];
var lastSep = -1;
for (var i = 0; i < s.length; i++) {
if (s[i] === 'codesep')
lastSep = i;
else if (s[i] === 'checksig' ||
s[i] === 'checksigverify' ||
s[i] === 'checkmultisig' ||
s[i] === 'checkmultisigverify') {
break;
if (lastSep == null) {
lastSep = -1;
for (var i = 0; i < s.length; i++) {
if (s[i] === 'codesep')
lastSep = i;
else if (s[i] === 'checksig' ||
s[i] === 'checksigverify' ||
s[i] === 'checkmultisig' ||
s[i] === 'checkmultisigverify') {
break;
}
}
}
@ -579,13 +581,13 @@ script.execute = function execute(s, stack, tx, index) {
var pub = stack.pop();
var sig = stack.pop();
var type = sig[sig.length - 1];
if (!constants.rhashType[type & 0x7f])
if (!constants.rhashType[type & 0x1f])
return false;
if (!script.isValidSig(sig))
return false;
var subscript = s.slice(lastSep + 1);
var subscript = script.subscript(s, lastSep);
var hash = tx.subscriptHash(index, subscript, type);
var res = script.verify(hash, sig.slice(0, -1), pub);
@ -633,13 +635,13 @@ script.execute = function execute(s, stack, tx, index) {
for (var i = 0; i < m; i++) {
var sig = stack.pop();
var type = sig[sig.length - 1];
if (!constants.rhashType[type & 0x7f])
if (!constants.rhashType[type & 0x1f])
return false;
if (!script.isValidSig(sig))
return false;
var subscript = s.slice(lastSep + 1);
var subscript = script.subscript(s, lastSep);
var hash = tx.subscriptHash(index, subscript, type);
// Strict order:

View File

@ -207,6 +207,41 @@ TXPool.prototype.unspent = function unspent() {
}, this);
};
TXPool.prototype.hasUnspent = function hasUnspent(hash, unspent) {
if (Array.isArray(hash) && hash.length && typeof hash[0] !== 'number') {
unspent = this.unspent();
var has = hash.map(function(hash) {
var h = this.hasUnspent(hash, unspent);
if (!h)
return false;
return h[0];
}, this).filter(Boolean);
if (has.length !== hash.length)
return null;
return has;
}
if (Array.isArray(hash))
hash = utils.toHex(hash);
else if (hash.out)
hash = hash.out.hash;
else if (hash.tx)
hash = hash.tx.hash('hex');
else if (hash instanceof bcoin.tx)
hash = hash.hash('hex');
unspent = unspent || this.unspent();
var has = unspent.filter(function(item) {
return item.tx.hash('hex') === hash;
});
if (!has.length)
return null;
return has;
};
TXPool.prototype.pending = function pending() {
return Object.keys(this._all).map(function(key) {
return this._all[key];

View File

@ -417,8 +417,43 @@ TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
copy.inputs.forEach(function(input, i) {
input.script = index === i ? s : [];
});
if ((type & 0x1f) === constants.hashType.all) {
;
} else if ((type & 0x1f) === constants.hashType.none) {
copy.outputs = [];
copy.inputs.forEach(function(input, i) {
if (i !== index)
input.seq = 0;
});
} else if ((type & 0x1f) === constants.hashType.single) {
while (copy.outputs.length < index + 1)
copy.outputs.push({});
while (copy.outputs.length > index + 1)
copy.outputs.pop();
copy.outputs.forEach(function(output, i) {
if (i !== index) {
output.script = [];
// output.value = new bn('ffffffffffffffff', 'hex');
output.value = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
output.value.toArray = function() { return this; };
}
});
copy.inputs.forEach(function(input, i) {
if (i !== index)
input.seq = 0;
});
}
if (type & constants.hashType.anyonecanpay) {
copy.inputs.length = 1;
copy.inputs[0].script = s;
}
var verifyStr = copy.render();
utils.writeU32(verifyStr, type, verifyStr.length);
var hash = utils.dsha256(verifyStr);
return hash;