improve tx building. minor style fixes. utils.uniq.

This commit is contained in:
Christopher Jeffrey 2015-12-23 16:21:49 -08:00
parent d32a951f37
commit 389ee296b0
4 changed files with 40 additions and 11 deletions

View File

@ -1021,6 +1021,8 @@ script.isMultisig = function isMultisig(s, pubs) {
}; };
script.isScripthash = function isScripthash(s, hash) { script.isScripthash = function isScripthash(s, hash) {
var res;
s = script.subscript(s); s = script.subscript(s);
if (script.lockTime(s)) if (script.lockTime(s))
@ -1029,7 +1031,7 @@ script.isScripthash = function isScripthash(s, hash) {
if (s.length !== 3) if (s.length !== 3)
return false; return false;
var res = s[0] === 'hash160' res = s[0] === 'hash160'
&& Array.isArray(s[1]) && Array.isArray(s[1])
&& s[1].length === 20 && s[1].length === 20
&& s[2] === 'eq'; && s[2] === 'eq';

View File

@ -64,6 +64,7 @@ function TX(data, block) {
this.ps = this.ts === 0 ? +new Date() / 1000 : 0; this.ps = this.ts === 0 ? +new Date() / 1000 : 0;
this.changeAddress = data.changeAddress || null; this.changeAddress = data.changeAddress || null;
this.changeOutput = data.changeOutput || null;
} }
TX.fee = 10000; TX.fee = 10000;
@ -283,11 +284,13 @@ TX.prototype.signInput = function signInput(input, key, type) {
break; break;
} }
// Public key is not in the prev_out script
if (ki === keys.length) if (ki === keys.length)
throw new Error('Public key is not in the prev_out script'); return;
// No signature slot available
if (ki + 1 > len - 1) if (ki + 1 > len - 1)
throw new Error('No signature slot available'); return;
// Add our signature to the correct slot // Add our signature to the correct slot
// and count the total number of signatures. // and count the total number of signatures.
@ -729,13 +732,15 @@ TX.prototype.utxos = function utxos(unspent) {
TX.prototype.fillUnspent = function fillUnspent(unspent, changeAddress) { TX.prototype.fillUnspent = function fillUnspent(unspent, changeAddress) {
var result = unspent.utxos ? unspent : this.utxos(unspent); var result = unspent.utxos ? unspent : this.utxos(unspent);
this.changeAddress = changeAddress || this.changeAddress; this.changeAddress = changeAddress
|| this.changeAddress
|| utxos[0].output.addr;
if (!result) if (!result)
return result; return result;
result.utxos.forEach(function(utxo) { result.utxos.forEach(function(input) {
this.input(utxo, null); this.input(input);
}, this); }, this);
if (result.change.cmpn(TX.dust) < 0) { if (result.change.cmpn(TX.dust) < 0) {
@ -743,6 +748,8 @@ TX.prototype.fillUnspent = function fillUnspent(unspent, changeAddress) {
assert(this.getFee().cmp(result.fee.add(result.change)) === 0); assert(this.getFee().cmp(result.fee.add(result.change)) === 0);
this.changeOutput = null; this.changeOutput = null;
} else { } else {
if (!this.changeAddress)
throw new Error('No change address');
this.output({ this.output({
address: this.changeAddress, address: this.changeAddress,
value: result.change value: result.change

View File

@ -798,3 +798,15 @@ utils.writeIntv = function writeIntv(arr, value, off) {
utils.writeU64(arr, value, off + 1); utils.writeU64(arr, value, off + 1);
return 9; return 9;
}; };
utils.uniq = function(obj) {
var out = [];
var i = 0;
for (; i < obj.length; i++) {
if (!~out.indexOf(obj[i]))
out.push(obj[i]);
}
return out;
};

View File

@ -41,6 +41,7 @@ function Wallet(options, passphrase) {
this.key = null; this.key = null;
this.loaded = false; this.loaded = false;
this.lastTs = 0; this.lastTs = 0;
this.changeAddress = options.changeAddress || null;
if (options.priv instanceof bcoin.hd.priv) { if (options.priv instanceof bcoin.hd.priv) {
this.hd = options.priv; this.hd = options.priv;
@ -459,8 +460,9 @@ Wallet.prototype.scriptOutputs = function scriptOutputs(tx, options, outputs) {
return outputs.length; return outputs.length;
}; };
Wallet.prototype.fillUnspent = function fillUnspent(tx, change) { Wallet.prototype.fillUnspent = function fillUnspent(tx, changeAddress) {
return tx.fillUnspent(this.unspent(), change || this.getFullAddress()); changeAddress = changeAddress || this.changeAddress || this.getFullAddress();
return tx.fillUnspent(this.unspent(), changeAddress);
}; };
Wallet.prototype.scriptInputs = function scriptInputs(tx, inputs) { Wallet.prototype.scriptInputs = function scriptInputs(tx, inputs) {
@ -544,12 +546,18 @@ Wallet.prototype.balance = function balance() {
return this.tx.balance(); return this.tx.balance();
}; };
Wallet.prototype.fill = function fill(tx, cb) { Wallet.prototype.fill = function fill(tx, changeAddress, cb) {
var result = tx.fillUnspent(this.unspent(), this.getAddress()); var result, err;
var err;
if (typeof changeAddress === 'function') {
cb = changeAddress;
changeAddress = null;
}
cb = utils.asyncify(cb); cb = utils.asyncify(cb);
result = this.fillUnspent(tx, changeAddress);
if (!result) { if (!result) {
err = new Error('Not enough funds'); err = new Error('Not enough funds');
err.minBalance = tx.total; err.minBalance = tx.total;