better key and sig parsing for scripts.

This commit is contained in:
Christopher Jeffrey 2016-01-19 13:22:55 -08:00
parent c8da41aa9d
commit b389dd1b5f
5 changed files with 47 additions and 30 deletions

View File

@ -642,7 +642,7 @@ Block.prototype.toJSON = function toJSON() {
ts: this.ts, ts: this.ts,
network: this.network, network: this.network,
relayedBy: this.relayedBy, relayedBy: this.relayedBy,
block: utils.toHex(bcoin.protocol.framer.block(this, this.subtype)) block: utils.toHex(this.render())
}; };
}; };

View File

@ -51,6 +51,10 @@ Input.prototype.__defineGetter__('type', function() {
return this.data.type; return this.data.type;
}); });
Input.prototype.__defineGetter__('subtype', function() {
return this.data.subtype;
});
Input.prototype.__defineGetter__('signature', function() { Input.prototype.__defineGetter__('signature', function() {
return this.signatures[0]; return this.signatures[0];
}); });
@ -105,12 +109,6 @@ Input.prototype.__defineGetter__('lock', function() {
return this.output.lock; return this.output.lock;
}); });
Input.prototype.__defineGetter__('lockType', function() {
if (!this.output)
return 'height';
return this.output.lockType;
});
Input.prototype.__defineGetter__('text', function() { Input.prototype.__defineGetter__('text', function() {
return this.data.text; return this.data.text;
}); });
@ -225,7 +223,7 @@ Input.getData = function getData(input) {
if (input.out && input.out.tx) { if (input.out && input.out.tx) {
output = input.out.tx.outputs[input.out.index]; output = input.out.tx.outputs[input.out.index];
if (output) { if (output) {
data = bcoin.script.getData(input.script, output.script); data = bcoin.script.getInputData(input.script, output.script);
data.value = output.value; data.value = output.value;
return utils.merge(def, data); return utils.merge(def, data);
} }
@ -245,14 +243,13 @@ Input.prototype.inspect = function inspect() {
return { return {
type: this.type, type: this.type,
subtype: this.data.subtype, subtype: this.subtype,
address: this.address, address: this.address,
addresses: this.addresses, addresses: this.addresses,
signatures: this.signatures.map(utils.toHex), signatures: this.signatures.map(utils.toHex),
keys: this.keys.map(utils.toHex), keys: this.keys.map(utils.toHex),
text: this.text, text: this.text,
lock: this.lock, lock: this.lock,
lockType: this.lockType,
value: utils.btc(output.value), value: utils.btc(output.value),
script: bcoin.script.format(this.script)[0], script: bcoin.script.format(this.script)[0],
redeem: this.redeem ? bcoin.script.format(this.redeem)[0] : null, redeem: this.redeem ? bcoin.script.format(this.redeem)[0] : null,

View File

@ -105,10 +105,6 @@ Output.prototype.__defineGetter__('lock', function() {
return bcoin.script.lockTime(this.script); return bcoin.script.lockTime(this.script);
}); });
Output.prototype.__defineGetter__('lockType', function() {
return this.lock < constants.locktimeThreshold ? 'height' : 'time';
});
Output.prototype.__defineGetter__('text', function() { Output.prototype.__defineGetter__('text', function() {
return this.data.text; return this.data.text;
}); });
@ -202,7 +198,6 @@ Output.prototype.inspect = function inspect() {
n: this.n, n: this.n,
text: this.text, text: this.text,
lock: this.lock, lock: this.lock,
lockType: this.lockType,
value: utils.btc(this.value), value: utils.btc(this.value),
script: bcoin.script.format(this.script)[0] script: bcoin.script.format(this.script)[0]
}; };

View File

@ -217,7 +217,7 @@ script.verify = function verify(input, output, tx, i, flags) {
res = script.execute(output, stack, tx, i, flags); res = script.execute(output, stack, tx, i, flags);
// Verify the script did not fail as well as the stack values // Verify the script did not fail as well as the stack values
if (!res || stack.length === 0 || script.num(stack.pop()).cmpn(0) === 0) if (!res || stack.length === 0 || !script.bool(stack.pop()))
return false; return false;
// If the script is P2SH, execute the real output script // If the script is P2SH, execute the real output script
@ -245,7 +245,7 @@ script.verify = function verify(input, output, tx, i, flags) {
res = script.execute(redeem, stack, tx, i, flags); res = script.execute(redeem, stack, tx, i, flags);
// Verify the script did not fail as well as the stack values // Verify the script did not fail as well as the stack values
if (!res || stack.length === 0 || script.num(stack.pop()).cmpn(0) === 0) if (!res || stack.length === 0 || !script.bool(stack.pop()))
return false; return false;
} }
@ -1248,13 +1248,15 @@ script.spendable = function spendable(s, lockTime) {
return true; return true;
}; };
script.getData = function getData(s, prev) { script.getInputData = function getData(s, prev) {
var output; var output;
if (prev && !script.isScripthash(prev)) { if (prev && !script.isScripthash(prev)) {
output = script.getOutputData(prev); output = script.getOutputData(prev);
output.side = 'input'; output.side = 'input';
// We could call getInputData, but
// we really only need the signatures.
if (output.type === 'pubkey') { if (output.type === 'pubkey') {
output.signatures = [s[0]]; output.signatures = [s[0]];
} else if (output.type === 'pubkeyhash') { } else if (output.type === 'pubkeyhash') {
@ -1262,15 +1264,17 @@ script.getData = function getData(s, prev) {
output.keys = [s[1]]; output.keys = [s[1]];
} else if (output.type === 'multisig') { } else if (output.type === 'multisig') {
output.signatures = s.slice(1); output.signatures = s.slice(1);
} else {
output.signatures = script.getUnknownData(s).signatures;
} }
return output; return output;
} }
return script.getInputData(s); return script._getInputData(s);
}; };
script.getInputData = function getInputData(s) { script._getInputData = function _getInputData(s) {
var sig, key, hash, raw, redeem, lock, hash, address, input, output; var sig, key, hash, raw, redeem, lock, hash, address, input, output;
if (script.isPubkeyInput(s)) { if (script.isPubkeyInput(s)) {
@ -1329,10 +1333,7 @@ script.getInputData = function getInputData(s) {
}); });
} }
return { return script.getUnknownData(s);
type: 'unknown',
none: true
};
}; };
script.getOutputData = function getOutputData(s) { script.getOutputData = function getOutputData(s) {
@ -1390,9 +1391,36 @@ script.getOutputData = function getOutputData(s) {
}; };
} }
return script.getUnknownData(s);
};
script.getUnknownData = function getUnknownData(s) {
var sig = [];
var key = [];
var hash, address, i;
for (i = 0; i < s.length; i++) {
if (script.isSignatureEncoding(s[i]))
sig.push(s[i]);
else if (script.isKeyEncoding(s[i]))
key.push(s[i]);
}
hash = key.map(function(key) {
return bcoin.wallet.key2hash(key);
});
address = hash.map(function(hash) {
return bcoin.wallet.hash2addr(hash, 'pubkey');
});
return { return {
type: 'unknown', type: 'unknown',
none: true signatures: sig,
keys: key,
hashes: hash,
addresses: address,
none: key.length === 0
}; };
}; };
@ -1488,8 +1516,6 @@ script.isMultisig = function isMultisig(s, keys) {
} }
if (keys) { if (keys) {
keys = utils.sortKeys(keys);
for (i = 1; i < n + 1; i++) { for (i = 1; i < n + 1; i++) {
for (j = 0; j < keys.length; j++) { for (j = 0; j < keys.length; j++) {
if (utils.isEqual(s[i], keys[j])) { if (utils.isEqual(s[i], keys[j])) {

View File

@ -18,11 +18,11 @@ var constants = bcoin.protocol.constants;
function TX(data, block) { function TX(data, block) {
if (!(this instanceof TX)) if (!(this instanceof TX))
return new TX(data, block); return new TX(data, block);
this.type = 'tx';
if (!data) if (!data)
data = {}; data = {};
this.type = 'tx';
this.version = data.version || 1; this.version = data.version || 1;
this.inputs = []; this.inputs = [];
this.outputs = []; this.outputs = [];
@ -36,7 +36,6 @@ function TX(data, block) {
this.network = data.network || false; this.network = data.network || false;
this.relayedBy = data.relayedBy || '0.0.0.0'; this.relayedBy = data.relayedBy || '0.0.0.0';
this.rbf = !!data.rbf;
this._chain = data.chain; this._chain = data.chain;
@ -1269,7 +1268,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
if (!input.out.tx) if (!input.out.tx)
return false; return false;
prev = input.out.tx[input.out.index]; prev = input.out.tx.outputs[input.out.index];
if (!prev) if (!prev)
return false; return false;