refactor tx.
This commit is contained in:
parent
7de73c670c
commit
18f0a55779
@ -7,6 +7,7 @@
|
|||||||
var bn = require('bn.js');
|
var bn = require('bn.js');
|
||||||
var bcoin = require('../bcoin');
|
var bcoin = require('../bcoin');
|
||||||
var utils = bcoin.utils;
|
var utils = bcoin.utils;
|
||||||
|
var assert = utils.assert;
|
||||||
var constants = bcoin.protocol.constants;
|
var constants = bcoin.protocol.constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,10 +69,8 @@ Input.prototype.__defineGetter__('data', function() {
|
|||||||
|
|
||||||
data = Input.getData(this);
|
data = Input.getData(this);
|
||||||
|
|
||||||
if (!this.tx || this.tx.ps === 0) {
|
if (this.script.length && this.output)
|
||||||
if (this.script.length && this.prevout.tx)
|
utils.hidden(this, '_data', data);
|
||||||
utils.hidden(this, '_data', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
@ -96,8 +95,12 @@ Input.prototype.__defineGetter__('hash', function() {
|
|||||||
return this.data.scriptHash || this.hashes[0];
|
return this.data.scriptHash || this.hashes[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Input.prototype.__defineGetter__('id', function() {
|
||||||
|
return this.address || this.getID();
|
||||||
|
});
|
||||||
|
|
||||||
Input.prototype.__defineGetter__('address', function() {
|
Input.prototype.__defineGetter__('address', function() {
|
||||||
return this.data.scriptAddress || this.addresses[0] || this.getID();
|
return this.data.scriptAddress || this.addresses[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
Input.prototype.__defineGetter__('signatures', function() {
|
Input.prototype.__defineGetter__('signatures', function() {
|
||||||
@ -158,7 +161,7 @@ Input.prototype.__defineGetter__('output', function() {
|
|||||||
|
|
||||||
Input.prototype.__defineGetter__('value', function() {
|
Input.prototype.__defineGetter__('value', function() {
|
||||||
if (!this.output)
|
if (!this.output)
|
||||||
return new bn(0);
|
return;
|
||||||
return this.output.value;
|
return this.output.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -221,10 +224,9 @@ Input.prototype.__defineGetter__('scriptaddr', function() {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
Input.getData = function getData(input) {
|
Input.getData = function getData(input) {
|
||||||
var def, data, output;
|
var def, data;
|
||||||
|
|
||||||
if (!input || !input.script)
|
assert(input instanceof Input);
|
||||||
return;
|
|
||||||
|
|
||||||
def = {
|
def = {
|
||||||
side: 'input',
|
side: 'input',
|
||||||
@ -233,12 +235,10 @@ Input.getData = function getData(input) {
|
|||||||
seq: input.seq
|
seq: input.seq
|
||||||
};
|
};
|
||||||
|
|
||||||
if (input.prevout) {
|
def.prev = input.prevout.hash;
|
||||||
def.prev = input.prevout.hash;
|
def.index = input.prevout.index;
|
||||||
def.index = input.prevout.index;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.prevout && +input.prevout.hash === 0) {
|
if (+input.prevout.hash === 0) {
|
||||||
data = bcoin.script.getCoinbaseData(input.script);
|
data = bcoin.script.getCoinbaseData(input.script);
|
||||||
return utils.merge(def, data, {
|
return utils.merge(def, data, {
|
||||||
type: 'coinbase',
|
type: 'coinbase',
|
||||||
@ -246,18 +246,40 @@ Input.getData = function getData(input) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.prevout && input.prevout.tx) {
|
if (input.output) {
|
||||||
output = input.prevout.tx.outputs[input.prevout.index];
|
data = bcoin.script.getInputData(input.script, input.output.script);
|
||||||
if (output) {
|
data.value = input.output.value;
|
||||||
data = bcoin.script.getInputData(input.script, output.script);
|
return utils.merge(def, data);
|
||||||
data.value = output.value;
|
|
||||||
return utils.merge(def, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.merge(def, bcoin.script.getInputData(input.script));
|
return utils.merge(def, bcoin.script.getInputData(input.script));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Input.prototype.getData = function getData() {
|
||||||
|
return Input.getData(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
Input.prototype.getAddresses = function getAddresses() {
|
||||||
|
return this.getData().addresses;
|
||||||
|
};
|
||||||
|
|
||||||
|
Input.prototype.getScriptAddress = function getScriptAddress() {
|
||||||
|
return this.getData().scriptAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
Input.prototype.getKeyAddress = function getKeyAddress() {
|
||||||
|
return this.getData().addresses[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
Input.prototype.getAddress = function getAddress() {
|
||||||
|
var data = this.getData();
|
||||||
|
|
||||||
|
if (data.scriptAddress)
|
||||||
|
return data.scriptAddress;
|
||||||
|
|
||||||
|
return data.addresses[0];
|
||||||
|
};
|
||||||
|
|
||||||
Input.prototype.isFinal = function isFinal() {
|
Input.prototype.isFinal = function isFinal() {
|
||||||
return this.sequence === 0xffffffff;
|
return this.sequence === 0xffffffff;
|
||||||
};
|
};
|
||||||
@ -271,9 +293,9 @@ Input.prototype.getID = function getID() {
|
|||||||
Input.prototype.getLocktime = function getLocktime() {
|
Input.prototype.getLocktime = function getLocktime() {
|
||||||
var output, redeem, lock, type;
|
var output, redeem, lock, type;
|
||||||
|
|
||||||
assert(this.prevout.tx);
|
assert(this.output);
|
||||||
|
|
||||||
output = this.prevout.tx.outputs[this.prevout.index];
|
output = this.output;
|
||||||
redeem = output.script;
|
redeem = output.script;
|
||||||
|
|
||||||
if (bcoin.script.isScripthash(redeem))
|
if (bcoin.script.isScripthash(redeem))
|
||||||
@ -349,8 +371,8 @@ Input.prototype.inspect = function inspect() {
|
|||||||
text: this.text,
|
text: this.text,
|
||||||
locktime: this.locktime,
|
locktime: this.locktime,
|
||||||
value: utils.btc(output.value),
|
value: utils.btc(output.value),
|
||||||
script: bcoin.script.format(this.script)[0],
|
script: bcoin.script.format(this.script),
|
||||||
redeem: this.redeem ? bcoin.script.format(this.redeem)[0] : null,
|
redeem: this.redeem ? bcoin.script.format(this.redeem) : null,
|
||||||
seq: this.seq,
|
seq: this.seq,
|
||||||
output: output
|
output: output
|
||||||
};
|
};
|
||||||
|
|||||||
@ -48,10 +48,8 @@ Output.prototype.__defineGetter__('data', function() {
|
|||||||
|
|
||||||
data = Output.getData(this);
|
data = Output.getData(this);
|
||||||
|
|
||||||
if (!this.tx || this.tx.ps === 0) {
|
if (this.script.length)
|
||||||
if (this.script.length && this.value.cmpn(0) > 0)
|
utils.hidden(this, '_data', data);
|
||||||
utils.hidden(this, '_data', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
@ -72,8 +70,12 @@ Output.prototype.__defineGetter__('hash', function() {
|
|||||||
return this.data.scriptHash || this.hashes[0];
|
return this.data.scriptHash || this.hashes[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Output.prototype.__defineGetter__('id', function() {
|
||||||
|
return this.address || this.getID();
|
||||||
|
});
|
||||||
|
|
||||||
Output.prototype.__defineGetter__('address', function() {
|
Output.prototype.__defineGetter__('address', function() {
|
||||||
return this.data.scriptAddress || this.addresses[0] || this.getID();
|
return this.data.scriptAddress || this.addresses[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
Output.prototype.__defineGetter__('signatures', function() {
|
Output.prototype.__defineGetter__('signatures', function() {
|
||||||
@ -178,8 +180,7 @@ Output.prototype.__defineGetter__('scriptaddr', function() {
|
|||||||
Output.getData = function getData(output) {
|
Output.getData = function getData(output) {
|
||||||
var def;
|
var def;
|
||||||
|
|
||||||
if (!output || !output.script)
|
assert(output instanceof Output);
|
||||||
return;
|
|
||||||
|
|
||||||
def = {
|
def = {
|
||||||
side: 'output',
|
side: 'output',
|
||||||
@ -190,6 +191,31 @@ Output.getData = function getData(output) {
|
|||||||
return utils.merge(def, bcoin.script.getOutputData(output.script));
|
return utils.merge(def, bcoin.script.getOutputData(output.script));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Output.prototype.getData = function getData() {
|
||||||
|
return Output.getData(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
Output.prototype.getAddresses = function getAddresses() {
|
||||||
|
return this.getData().addresses;
|
||||||
|
};
|
||||||
|
|
||||||
|
Output.prototype.getScriptAddress = function getScriptAddress() {
|
||||||
|
return this.getData().scriptAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
Output.prototype.getKeyAddress = function getKeyAddress() {
|
||||||
|
return this.getData().addresses[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
Output.prototype.getAddress = function getAddress() {
|
||||||
|
var data = this.getData();
|
||||||
|
|
||||||
|
if (data.scriptAddress)
|
||||||
|
return data.scriptAddress;
|
||||||
|
|
||||||
|
return data.addresses[0];
|
||||||
|
};
|
||||||
|
|
||||||
Output.prototype.getID = function getID() {
|
Output.prototype.getID = function getID() {
|
||||||
var data = bcoin.script.encode(this.script);
|
var data = bcoin.script.encode(this.script);
|
||||||
var hash = utils.toHex(utils.ripesha(data));
|
var hash = utils.toHex(utils.ripesha(data));
|
||||||
@ -221,7 +247,7 @@ Output.prototype.inspect = function inspect() {
|
|||||||
text: this.text,
|
text: this.text,
|
||||||
locktime: this.locktime,
|
locktime: this.locktime,
|
||||||
value: utils.btc(this.value),
|
value: utils.btc(this.value),
|
||||||
script: bcoin.script.format(this.script)[0]
|
script: bcoin.script.format(this.script)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -999,7 +999,7 @@ Pool.prototype.unwatch = function unwatch(id) {
|
|||||||
// See "Filter matching algorithm":
|
// See "Filter matching algorithm":
|
||||||
// https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
// https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki
|
||||||
Pool.prototype.isWatched = function(tx, bloom) {
|
Pool.prototype.isWatched = function(tx, bloom) {
|
||||||
var i, input, output, prev;
|
var i, input, output;
|
||||||
|
|
||||||
if (!bloom)
|
if (!bloom)
|
||||||
bloom = this.bloom;
|
bloom = this.bloom;
|
||||||
@ -1039,9 +1039,8 @@ Pool.prototype.isWatched = function(tx, bloom) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Test the prev_out script
|
// Test the prev_out script
|
||||||
if (input.prevout.tx) {
|
if (input.output) {
|
||||||
prev = input.prevout.tx.outputs[input.prevout.index];
|
if (testScript(input.output.script))
|
||||||
if (testScript(prev.script))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -278,6 +278,20 @@ script.getSubscript = function getSubscript(s, lastSep) {
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script.concat = function concat(scripts) {
|
||||||
|
var s = [];
|
||||||
|
var i;
|
||||||
|
|
||||||
|
s.push(scripts[0]);
|
||||||
|
|
||||||
|
for (i = 1; i < scripts.length; i++) {
|
||||||
|
s.push('codeseparator');
|
||||||
|
s = s.concat(scripts[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
};
|
||||||
|
|
||||||
script.checksig = function checksig(msg, sig, key) {
|
script.checksig = function checksig(msg, sig, key) {
|
||||||
if (key.getPublic)
|
if (key.getPublic)
|
||||||
key = key.getPublic();
|
key = key.getPublic();
|
||||||
@ -2067,26 +2081,20 @@ script.isLowDER = function isLowDER(sig) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
script.format = function format(input, output) {
|
script.format = function format(s) {
|
||||||
var scripts = [];
|
var scripts = [];
|
||||||
var prev, redeem;
|
|
||||||
|
|
||||||
if (Array.isArray(input)) {
|
if (Array.isArray(s)) {
|
||||||
scripts.push(input);
|
scripts.push(s);
|
||||||
} else if (Array.isArray(output)) {
|
} else if (s instanceof bcoin.input) {
|
||||||
scripts.push(output);
|
scripts.push(s.script);
|
||||||
} else if (input) {
|
if (s.output) {
|
||||||
scripts.push(input.script);
|
scripts.push(s.output.script);
|
||||||
if (input.prevout.tx && input.prevout.tx.outputs[input.prevout.index]) {
|
if (script.isScripthash(s.output.script))
|
||||||
prev = input.prevout.tx.outputs[input.prevout.index].script;
|
scripts.push(script.getRedeem(s.script));
|
||||||
scripts.push(prev);
|
|
||||||
if (script.isScripthash(prev)) {
|
|
||||||
redeem = script.decode(input.script[input.script.length - 1]);
|
|
||||||
scripts.push(redeem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (output) {
|
} else if (s instanceof bcoin.output) {
|
||||||
scripts.push(output.script);
|
scripts.push(s.script);
|
||||||
}
|
}
|
||||||
|
|
||||||
scripts = scripts.map(function(script) {
|
scripts = scripts.map(function(script) {
|
||||||
@ -2102,7 +2110,7 @@ script.format = function format(input, output) {
|
|||||||
}).join(' ');
|
}).join(' ');
|
||||||
});
|
});
|
||||||
|
|
||||||
return scripts;
|
return script.concat(scripts);
|
||||||
};
|
};
|
||||||
|
|
||||||
script.isPushOnly = function isPushOnly(s) {
|
script.isPushOnly = function isPushOnly(s) {
|
||||||
@ -2111,8 +2119,6 @@ script.isPushOnly = function isPushOnly(s) {
|
|||||||
op = s[i];
|
op = s[i];
|
||||||
if (Array.isArray(op) || op === '1negate' || (op >= 1 && op <= 16))
|
if (Array.isArray(op) || op === '1negate' || (op >= 1 && op <= 16))
|
||||||
continue;
|
continue;
|
||||||
if (constants.opcodes[op] == null)
|
|
||||||
return false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -286,33 +286,28 @@ TXPool.prototype.getAll = function getAll(address) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TXPool.prototype._addOutput = function _addOutput(tx, i, remove) {
|
TXPool.prototype._addOutput = function _addOutput(tx, i, remove) {
|
||||||
var i, data, address, addr, output;
|
var output = tx.outputs[i];
|
||||||
|
var address;
|
||||||
output = tx.outputs[i];
|
|
||||||
data = bcoin.script.getOutputData(output.script);
|
|
||||||
|
|
||||||
if (!this._wallet.ownOutput(tx, i))
|
if (!this._wallet.ownOutput(tx, i))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (data.scriptAddress)
|
address = output.getAddress();
|
||||||
data.addresses = [data.scriptAddress];
|
|
||||||
|
|
||||||
for (i = 0; i < data.addresses.length; i++) {
|
if (!this._addresses[address]) {
|
||||||
addr = data.addresses[i];
|
this._addresses[address] = {
|
||||||
if (!this._addresses[addr]) {
|
received: new bn(0),
|
||||||
this._addresses[addr] = {
|
sent: new bn(0),
|
||||||
received: new bn(0),
|
balance: new bn(0)
|
||||||
sent: new bn(0),
|
};
|
||||||
balance: new bn(0)
|
}
|
||||||
};
|
|
||||||
}
|
if (!remove) {
|
||||||
if (!remove) {
|
this._addresses[address].balance.iadd(output.value);
|
||||||
this._addresses[addr].balance.iadd(output.value);
|
this._addresses[address].received.iadd(output.value);
|
||||||
this._addresses[addr].received.iadd(output.value);
|
} else {
|
||||||
} else {
|
this._addresses[address].balance.isub(output.value);
|
||||||
this._addresses[addr].balance.isub(output.value);
|
this._addresses[address].received.isub(output.value);
|
||||||
this._addresses[addr].received.isub(output.value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!remove) {
|
if (!remove) {
|
||||||
@ -329,36 +324,31 @@ TXPool.prototype._removeOutput = function _removeOutput(tx, i) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TXPool.prototype._addInput = function _addInput(tx, i, remove) {
|
TXPool.prototype._addInput = function _addInput(tx, i, remove) {
|
||||||
var i, input, prev, data, address, addr, output;
|
var input = tx.inputs[i];
|
||||||
|
var prev, address;
|
||||||
input = tx.inputs[i];
|
|
||||||
assert(input.prevout.tx);
|
|
||||||
|
|
||||||
if (!this._wallet.ownOutput(input.prevout.tx, input.prevout.index))
|
if (!this._wallet.ownOutput(input.prevout.tx, input.prevout.index))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
prev = input.prevout.tx.outputs[input.prevout.index];
|
assert(input.output);
|
||||||
data = bcoin.script.getInputData(input.script, prev.script);
|
|
||||||
|
|
||||||
if (data.scriptAddress)
|
prev = input.output;
|
||||||
data.addresses = [data.scriptAddress];
|
address = prev.getAddress();
|
||||||
|
|
||||||
for (i = 0; i < data.addresses.length; i++) {
|
if (!this._addresses[address]) {
|
||||||
addr = data.addresses[i];
|
this._addresses[address] = {
|
||||||
if (!this._addresses[addr]) {
|
received: new bn(0),
|
||||||
this._addresses[addr] = {
|
sent: new bn(0),
|
||||||
received: new bn(0),
|
balance: new bn(0)
|
||||||
sent: new bn(0),
|
};
|
||||||
balance: new bn(0)
|
}
|
||||||
};
|
|
||||||
}
|
if (!remove) {
|
||||||
if (!remove) {
|
this._addresses[address].balance.isub(prev.value);
|
||||||
this._addresses[addr].balance.isub(prev.value);
|
this._addresses[address].sent.iadd(prev.value);
|
||||||
this._addresses[addr].sent.iadd(prev.value);
|
} else {
|
||||||
} else {
|
this._addresses[address].balance.iadd(prev.value);
|
||||||
this._addresses[addr].balance.iadd(prev.value);
|
this._addresses[address].sent.isub(prev.value);
|
||||||
this._addresses[addr].sent.isub(prev.value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!remove) {
|
if (!remove) {
|
||||||
|
|||||||
141
lib/bcoin/tx.js
141
lib/bcoin/tx.js
@ -206,16 +206,16 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
|||||||
// return;
|
// return;
|
||||||
|
|
||||||
// We should have previous outputs by now.
|
// We should have previous outputs by now.
|
||||||
assert(input.prevout.tx);
|
assert(input.output);
|
||||||
|
|
||||||
// Get the previous output's subscript
|
// Get the previous output's subscript
|
||||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
s = input.output.script;
|
||||||
|
|
||||||
// P2SH
|
// P2SH
|
||||||
if (bcoin.script.isScripthash(s)) {
|
if (bcoin.script.isScripthash(s)) {
|
||||||
if (!redeem)
|
if (!redeem)
|
||||||
return false;
|
return false;
|
||||||
s = bcoin.script.getSubscript(bcoin.script.decode(redeem));
|
s = bcoin.script.decode(redeem);
|
||||||
} else {
|
} else {
|
||||||
redeem = null;
|
redeem = null;
|
||||||
}
|
}
|
||||||
@ -316,17 +316,15 @@ TX.prototype.createSignature = function createSignature(index, key, type) {
|
|||||||
assert(input);
|
assert(input);
|
||||||
|
|
||||||
// We should have previous outputs by now.
|
// We should have previous outputs by now.
|
||||||
assert(input.prevout.tx);
|
assert(input.output);
|
||||||
|
|
||||||
// Get the previous output's subscript
|
// Get the previous output's subscript
|
||||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
s = input.output.script;
|
||||||
|
|
||||||
// We need to grab the redeem script when
|
// We need to grab the redeem script when
|
||||||
// signing p2sh transactions.
|
// signing p2sh transactions.
|
||||||
if (bcoin.script.isScripthash(s)) {
|
if (bcoin.script.isScripthash(s))
|
||||||
s = bcoin.script.decode(input.script[input.script.length - 1]);
|
s = bcoin.script.getRedeem(input.script);
|
||||||
s = bcoin.script.getSubscript(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the hash of the current tx, minus the other
|
// Get the hash of the current tx, minus the other
|
||||||
// inputs, plus the sighash type.
|
// inputs, plus the sighash type.
|
||||||
@ -357,13 +355,13 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
assert(input);
|
assert(input);
|
||||||
|
|
||||||
// We should have previous outputs by now.
|
// We should have previous outputs by now.
|
||||||
assert(input.prevout.tx);
|
assert(input.output);
|
||||||
|
|
||||||
// Create our signature.
|
// Create our signature.
|
||||||
signature = this.createSignature(index, key, type);
|
signature = this.createSignature(index, key, type);
|
||||||
|
|
||||||
// Get the previous output's subscript
|
// Get the previous output's subscript
|
||||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
s = input.output.script;
|
||||||
|
|
||||||
// Script length, needed for multisig
|
// Script length, needed for multisig
|
||||||
len = input.script.length;
|
len = input.script.length;
|
||||||
@ -371,8 +369,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
// We need to grab the redeem script when
|
// We need to grab the redeem script when
|
||||||
// signing p2sh transactions.
|
// signing p2sh transactions.
|
||||||
if (bcoin.script.isScripthash(s)) {
|
if (bcoin.script.isScripthash(s)) {
|
||||||
s = bcoin.script.decode(input.script[input.script.length - 1]);
|
s = bcoin.script.getRedeem(input.script);
|
||||||
s = bcoin.script.getSubscript(s);
|
|
||||||
// Decrement `len` to avoid the redeem script
|
// Decrement `len` to avoid the redeem script
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
@ -571,10 +568,10 @@ TX.prototype.isSigned = function isSigned(index, required) {
|
|||||||
|
|
||||||
// We can't check for signatures unless
|
// We can't check for signatures unless
|
||||||
// we have the previous output.
|
// we have the previous output.
|
||||||
assert(input.prevout.tx);
|
assert(input.output);
|
||||||
|
|
||||||
// Get the prevout's subscript
|
// Get the prevout's subscript
|
||||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
s = input.output.script;
|
||||||
|
|
||||||
// Script length, needed for multisig
|
// Script length, needed for multisig
|
||||||
len = input.script.length;
|
len = input.script.length;
|
||||||
@ -642,7 +639,7 @@ TX.prototype.isSigned = function isSigned(index, required) {
|
|||||||
TX.prototype.addOutput = function addOutput(obj, value) {
|
TX.prototype.addOutput = function addOutput(obj, value) {
|
||||||
var options, output;
|
var options, output;
|
||||||
|
|
||||||
if (obj.getAddress)
|
if ((obj instanceof bcoin.wallet) || (obj instanceof bcoin.address))
|
||||||
obj = obj.getAddress();
|
obj = obj.getAddress();
|
||||||
|
|
||||||
if (typeof obj === 'string') {
|
if (typeof obj === 'string') {
|
||||||
@ -770,11 +767,9 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
|
|||||||
|
|
||||||
if (!Array.isArray(s)) {
|
if (!Array.isArray(s)) {
|
||||||
type = s;
|
type = s;
|
||||||
s = this.inputs[index].prevout.tx.getSubscript(this.inputs[index].prevout.index);
|
s = this.inputs[index].output.script;
|
||||||
if (bcoin.script.isScripthash(s)) {
|
if (bcoin.script.isScripthash(s))
|
||||||
s = this.inputs[index].script[this.inputs[index.script.length - 1]];
|
s = bcoin.script.getRedeem(this.inputs[index].script);
|
||||||
s = bcoin.script.getSubscript(bcoin.script.decode(s));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof index !== 'number')
|
if (typeof index !== 'number')
|
||||||
@ -886,31 +881,17 @@ TX.prototype.verify = function verify(index, force, flags) {
|
|||||||
assert(this.inputs[index]);
|
assert(this.inputs[index]);
|
||||||
|
|
||||||
return this.inputs.every(function(input, i) {
|
return this.inputs.every(function(input, i) {
|
||||||
var output;
|
|
||||||
|
|
||||||
if (index != null && i !== index)
|
if (index != null && i !== index)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!input.prevout.tx)
|
if (!input.output)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Somethis is very wrong if this is
|
// Somethis is very wrong if this is
|
||||||
// not the case.
|
// not the case.
|
||||||
assert.equal(input.prevout.tx.hash('hex'), input.prevout.hash);
|
assert.equal(input.prevout.tx.hash('hex'), input.prevout.hash);
|
||||||
|
|
||||||
// Grab the previous output.
|
return bcoin.script.verify(input.script, input.output.script, this, i, flags);
|
||||||
output = input.prevout.tx.outputs[input.prevout.index];
|
|
||||||
|
|
||||||
// Transaction is referencing an output
|
|
||||||
// that does not exist.
|
|
||||||
if (!output)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Transaction cannot reference itself.
|
|
||||||
if (input.prevout.hash === this.hash('hex'))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return bcoin.script.verify(input.script, output.script, this, i, flags);
|
|
||||||
}, this);
|
}, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -933,19 +914,20 @@ TX.prototype.maxSize = function maxSize() {
|
|||||||
input = copy.inputs[i];
|
input = copy.inputs[i];
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
|
assert(input.output);
|
||||||
|
|
||||||
// Get the previous output's subscript
|
// Get the previous output's subscript
|
||||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
s = input.output.script;
|
||||||
|
|
||||||
// If we have access to the redeem script,
|
// If we have access to the redeem script,
|
||||||
// we can use it to calculate size much easier.
|
// we can use it to calculate size much easier.
|
||||||
if (this.inputs[i].script.length && bcoin.script.isScripthash(s)) {
|
if (this.inputs[i].script.length && bcoin.script.isScripthash(s)) {
|
||||||
s = this.inputs[i].script[this.inputs[i].script.length - 1];
|
s = bcoin.script.getRedeem(this.inputs[i].script);
|
||||||
// Need to add the redeem script size
|
// Need to add the redeem script size
|
||||||
// here since it will be ignored by
|
// here since it will be ignored by
|
||||||
// the isMultisig clause.
|
// the isMultisig clause.
|
||||||
// OP_PUSHDATA2 [redeem]
|
// OP_PUSHDATA2 [redeem]
|
||||||
size += 3 + s.length;
|
size += 3 + bcoin.script.getSize(s);
|
||||||
s = bcoin.script.getSubscript(bcoin.script.decode(s));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bcoin.script.isPubkey(s)) {
|
if (bcoin.script.isPubkey(s)) {
|
||||||
@ -1244,18 +1226,15 @@ TX.prototype.getFee = function getFee() {
|
|||||||
TX.prototype.getInputValue = function getInputValue() {
|
TX.prototype.getInputValue = function getInputValue() {
|
||||||
var acc = new bn(0);
|
var acc = new bn(0);
|
||||||
|
|
||||||
var inputs = this.inputs.filter(function(input) {
|
if (this.inputs.length === 0)
|
||||||
return input.prevout.tx;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (inputs.length === 0)
|
|
||||||
return acc;
|
return acc;
|
||||||
|
|
||||||
inputs.reduce(function(acc, input) {
|
if (!this.hasPrevout())
|
||||||
return acc.iadd(input.prevout.tx.outputs[input.prevout.index].value);
|
return acc;
|
||||||
}, acc);
|
|
||||||
|
|
||||||
return acc;
|
return this.inputs.reduce(function(acc, input) {
|
||||||
|
return acc.iadd(input.output.value);
|
||||||
|
}, acc);
|
||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.getOutputValue = function getOutputValue() {
|
TX.prototype.getOutputValue = function getOutputValue() {
|
||||||
@ -1264,11 +1243,9 @@ TX.prototype.getOutputValue = function getOutputValue() {
|
|||||||
if (this.outputs.length === 0)
|
if (this.outputs.length === 0)
|
||||||
return acc;
|
return acc;
|
||||||
|
|
||||||
this.outputs.reduce(function(acc, output) {
|
return this.outputs.reduce(function(acc, output) {
|
||||||
return acc.iadd(output.value);
|
return acc.iadd(output.value);
|
||||||
}, acc);
|
}, acc);
|
||||||
|
|
||||||
return acc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.getFunds = function getFunds(side) {
|
TX.prototype.getFunds = function getFunds(side) {
|
||||||
@ -1313,7 +1290,7 @@ TX.prototype.getTargetLocktime = function getTargetLocktime() {
|
|||||||
|
|
||||||
TX.prototype.testInputs = function testInputs(addressTable, index, collect) {
|
TX.prototype.testInputs = function testInputs(addressTable, index, collect) {
|
||||||
var inputs = [];
|
var inputs = [];
|
||||||
var i, input, prev, data, j;
|
var i, input, j, addresses, scriptAddress;
|
||||||
|
|
||||||
if (typeof addressTable === 'string')
|
if (typeof addressTable === 'string')
|
||||||
addressTable = [addressTable];
|
addressTable = [addressTable];
|
||||||
@ -1337,16 +1314,10 @@ TX.prototype.testInputs = function testInputs(addressTable, index, collect) {
|
|||||||
|
|
||||||
input = this.inputs[i];
|
input = this.inputs[i];
|
||||||
|
|
||||||
if (input.prevout.tx)
|
addresses = input.getAddresses();
|
||||||
prev = input.prevout.tx.outputs[input.prevout.index].script;
|
if (addresses) {
|
||||||
else
|
for (j = 0; j < addresses.length; j++) {
|
||||||
prev = null;
|
if (addressTable[addresses[j]] != null) {
|
||||||
|
|
||||||
data = bcoin.script.getInputData(input.script, prev);
|
|
||||||
|
|
||||||
if (data.addresses) {
|
|
||||||
for (j = 0; j < data.addresses.length; j++) {
|
|
||||||
if (addressTable[data.addresses[j]] != null) {
|
|
||||||
if (!collect)
|
if (!collect)
|
||||||
return true;
|
return true;
|
||||||
inputs.push(input);
|
inputs.push(input);
|
||||||
@ -1354,8 +1325,9 @@ TX.prototype.testInputs = function testInputs(addressTable, index, collect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.scriptAddress) {
|
scriptAddress = input.getScriptAddress();
|
||||||
if (addressTable[data.scriptAddress] != null) {
|
if (scriptAddress) {
|
||||||
|
if (addressTable[scriptAddress] != null) {
|
||||||
if (!collect)
|
if (!collect)
|
||||||
return true;
|
return true;
|
||||||
inputs.push(input);
|
inputs.push(input);
|
||||||
@ -1374,7 +1346,7 @@ TX.prototype.testInputs = function testInputs(addressTable, index, collect) {
|
|||||||
|
|
||||||
TX.prototype.testOutputs = function testOutputs(addressTable, index, collect) {
|
TX.prototype.testOutputs = function testOutputs(addressTable, index, collect) {
|
||||||
var outputs = [];
|
var outputs = [];
|
||||||
var i, output, data, j;
|
var i, output, data, j, addresses, scriptAddress;
|
||||||
|
|
||||||
if (typeof addressTable === 'string')
|
if (typeof addressTable === 'string')
|
||||||
addressTable = [addressTable];
|
addressTable = [addressTable];
|
||||||
@ -1398,11 +1370,10 @@ TX.prototype.testOutputs = function testOutputs(addressTable, index, collect) {
|
|||||||
|
|
||||||
output = this.outputs[i];
|
output = this.outputs[i];
|
||||||
|
|
||||||
data = bcoin.script.getOutputData(output.script);
|
addresses = output.getAddresses();
|
||||||
|
if (addresses) {
|
||||||
if (data.addresses) {
|
for (j = 0; j < addresses.length; j++) {
|
||||||
for (j = 0; j < data.addresses.length; j++) {
|
if (addressTable[addresses[j]] != null) {
|
||||||
if (addressTable[data.addresses[j]] != null) {
|
|
||||||
if (!collect)
|
if (!collect)
|
||||||
return true;
|
return true;
|
||||||
outputs.push(output);
|
outputs.push(output);
|
||||||
@ -1410,8 +1381,9 @@ TX.prototype.testOutputs = function testOutputs(addressTable, index, collect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.scriptAddress) {
|
scriptAddress = output.getScriptAddress();
|
||||||
if (addressTable[data.scriptAddress] != null) {
|
if (scriptAddress) {
|
||||||
|
if (addressTable[scriptAddress] != null) {
|
||||||
if (!collect)
|
if (!collect)
|
||||||
return true;
|
return true;
|
||||||
outputs.push(output);
|
outputs.push(output);
|
||||||
@ -1465,6 +1437,7 @@ TX.prototype.increaseFee = function increaseFee(fee) {
|
|||||||
TX.prototype.hasPrevout = function hasPrevout() {
|
TX.prototype.hasPrevout = function hasPrevout() {
|
||||||
if (this.inputs.length === 0)
|
if (this.inputs.length === 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return this.inputs.every(function(input) {
|
return this.inputs.every(function(input) {
|
||||||
return !!input.prevout.tx;
|
return !!input.prevout.tx;
|
||||||
});
|
});
|
||||||
@ -1614,7 +1587,7 @@ TX.prototype.isStandard = function isStandard() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
||||||
var i, input, prev, args, stack, res, s, targs;
|
var i, input, args, stack, res, s, targs;
|
||||||
|
|
||||||
if (this.isCoinbase())
|
if (this.isCoinbase())
|
||||||
return true;
|
return true;
|
||||||
@ -1622,15 +1595,10 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
|||||||
for (i = 0; i < this.inputs.length; i++) {
|
for (i = 0; i < this.inputs.length; i++) {
|
||||||
input = this.inputs[i];
|
input = this.inputs[i];
|
||||||
|
|
||||||
if (!input.prevout.tx)
|
if (!input.output)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
prev = input.prevout.tx.outputs[input.prevout.index];
|
args = bcoin.script.getArgs(input.output.script);
|
||||||
|
|
||||||
if (!prev)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
args = bcoin.script.getArgs(prev.script);
|
|
||||||
|
|
||||||
if (args < 0)
|
if (args < 0)
|
||||||
return false;
|
return false;
|
||||||
@ -1642,7 +1610,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
|||||||
if (!res)
|
if (!res)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (bcoin.script.isScripthash(prev.script)) {
|
if (bcoin.script.isScripthash(input.output.script)) {
|
||||||
if (stack.length === 0)
|
if (stack.length === 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1651,7 +1619,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
|||||||
if (!Array.isArray(s))
|
if (!Array.isArray(s))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
s = bcoin.script.getSubscript(bcoin.script.decode(s));
|
s = bcoin.script.decode(s);
|
||||||
|
|
||||||
if (bcoin.script.getType(s) !== 'unknown') {
|
if (bcoin.script.getType(s) !== 'unknown') {
|
||||||
targs = bcoin.script.getArgs(s);
|
targs = bcoin.script.getArgs(s);
|
||||||
@ -1671,7 +1639,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.getPriority = function getPriority() {
|
TX.prototype.getPriority = function getPriority() {
|
||||||
var size, value, i, input, output, age;
|
var size, value, i, input, age;
|
||||||
|
|
||||||
size = this.maxSize();
|
size = this.maxSize();
|
||||||
value = new bn(0);
|
value = new bn(0);
|
||||||
@ -1682,7 +1650,6 @@ TX.prototype.getPriority = function getPriority() {
|
|||||||
if (!input.prevout.tx)
|
if (!input.prevout.tx)
|
||||||
return constants.tx.freeThreshold.clone();
|
return constants.tx.freeThreshold.clone();
|
||||||
|
|
||||||
output = input.prevout.tx.outputs[input.prevout.index];
|
|
||||||
age = input.prevout.tx.getConfirmations();
|
age = input.prevout.tx.getConfirmations();
|
||||||
|
|
||||||
if (age === -1)
|
if (age === -1)
|
||||||
@ -1691,7 +1658,7 @@ TX.prototype.getPriority = function getPriority() {
|
|||||||
if (age !== 0)
|
if (age !== 0)
|
||||||
age += 1;
|
age += 1;
|
||||||
|
|
||||||
value.iadd(output.value.muln(age));
|
value.iadd(input.output.value.muln(age));
|
||||||
}
|
}
|
||||||
|
|
||||||
return priority.divn(size);
|
return priority.divn(size);
|
||||||
|
|||||||
@ -763,17 +763,35 @@ Wallet.prototype.createKey = function createKey(change, index) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.setAddressDepth = function setAddressDepth(depth) {
|
Wallet.prototype.setAddressDepth = function setAddressDepth(depth) {
|
||||||
|
var i;
|
||||||
|
|
||||||
assert(this.derivation !== 'normal');
|
assert(this.derivation !== 'normal');
|
||||||
for (var i = this.addressDepth; i < depth; i++)
|
|
||||||
|
if (depth <= this.addressDepth)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = this.addressDepth; i < depth; i++)
|
||||||
this.currentAddress = this.createAddress(false, i);
|
this.currentAddress = this.createAddress(false, i);
|
||||||
|
|
||||||
this.addressDepth = depth;
|
this.addressDepth = depth;
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.setChangeDepth = function setChangeDepth(depth) {
|
Wallet.prototype.setChangeDepth = function setChangeDepth(depth) {
|
||||||
|
var i;
|
||||||
|
|
||||||
assert(this.derivation !== 'normal');
|
assert(this.derivation !== 'normal');
|
||||||
for (var i = this.addressDepth; i < depth; i++)
|
|
||||||
|
if (depth <= this.changeDepth)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = this.changeDepth; i < depth; i++)
|
||||||
this.changeAddress = this.createAddress(true, i);
|
this.changeAddress = this.createAddress(true, i);
|
||||||
|
|
||||||
this.changeDepth = depth;
|
this.changeDepth = depth;
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.getKeyHash =
|
Wallet.prototype.getKeyHash =
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user