tx: add tbsHash method.

This commit is contained in:
Christopher Jeffrey 2016-01-14 00:47:50 -08:00
parent f8ec64d46f
commit 8f037ea430
3 changed files with 68 additions and 2 deletions

View File

@ -437,7 +437,8 @@ Block.prototype.postVerify = function postVerify() {
// BIP30 - Ensure there are no duplicate txids
if (this.chain.index[tx.hash('hex')]) {
// Blocks 91842 and 91880 created duplicate
// txids by carefully crafting the coinbases.
// txids by using the same exact output script
// and extraNonce.
this.chain.emit('debug', 'Block is overwriting txids: %s', this.rhash);
if (!(network.type === 'main' && (height === 91842 || height === 91880)))
return false;

View File

@ -205,8 +205,17 @@ Miner.prototype.createBlock = function createBlock(tx) {
index: 0xffffffff
},
script: [
// Height (required in v2+ blocks)
new bn(this.last.height + 1).toArray().reverse(),
// extraNonce - incremented when
// the nonce overflows.
[],
// Add a nonce to ensure we don't
// collide with a previous coinbase
// of ours.
utils.nonce().toArray(),
// Let the world know this little
// miner succeeded.
utils.ascii2array(this.msg || 'mined by bcoin')
],
seq: 0xffffffff

View File

@ -653,6 +653,62 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
return hash;
};
TX.prototype.tbsHash = function tbsHash(enc) {
var copy = this.clone();
var i, j, input, s, raw, redeem, m;
if (this.isCoinbase())
return this.hash(enc);
if (this._tbsHash) {
return enc === 'hex'
? utils.toHex(this._tbsHash)
: this._tbsHash.slice();
}
for (i = 0; i < copy.inputs.length; i++) {
input = copy.inputs[i];
input.out.tx = this.inputs[i].out.tx;
assert(input.out.tx);
s = input.script;
redeem = input.out.tx.getSubscript(input.out.index);
if (bcoin.script.isScripthash(redeem)) {
raw = s[s.length - 1];
assert(Array.isArray(raw) && raw.length);
redeem = bcoin.script.subscript(bcoin.script.decode(raw));
} else {
raw = null;
}
if (bcoin.script.isPubkey(redeem)) {
input.script = [[]];
} else if (bcoin.script.isPubkeyhash(redeem)) {
assert(Array.isArray(s[1]) && s[1].length);
input.script = [[], s[1]];
} else if (bcoin.script.isMultisig(redeem)) {
m = s[0];
if (Array.isArray(m))
m = m[0];
input.script = [[]];
for (i = 0; i < m; i++)
input.script.push([]);
} else {
input.script = [];
}
if (raw)
input.script.push(raw);
}
this._tbsHash = utils.dsha256(copy.render(true));
return enc === 'hex'
? utils.toHex(this._tbsHash)
: this._tbsHash.slice();
};
TX.prototype.verify = function verify(index, force, flags) {
// Valid if included in block
if (!force && this.ts !== 0)
@ -1202,7 +1258,7 @@ TX.prototype.__defineGetter__('fee', function() {
});
TX.prototype.__defineGetter__('value', function() {
return this.funds('in');
return this.funds('out');
});
TX.prototype.__defineGetter__('height', function() {