api: rename methods, properties. add legacy support.
This commit is contained in:
parent
0e57bb36ff
commit
6ad621cace
140
README.md
140
README.md
@ -99,7 +99,7 @@ pool.on('watched', function(tx, peer) {
|
||||
|
||||
// Look for balance changes
|
||||
wallet.on('balance', function() {
|
||||
utils.print('Wallet balance updated: %s', utils.btc(wallet.balance()));
|
||||
utils.print('Wallet balance updated: %s', utils.btc(wallet.getBalance()));
|
||||
});
|
||||
|
||||
// Start the getheaders sync
|
||||
@ -135,7 +135,7 @@ fs.writeFileSync(process.env.HOME + '/my-new-wallet.json',
|
||||
var tx = bcoin.tx();
|
||||
|
||||
// Add an output, send some money to our new wallet
|
||||
tx.output({
|
||||
tx.addOutput({
|
||||
address: receiver.getAddress(),
|
||||
// Every satoshi value in bcoin is
|
||||
// a big number, so we can convert
|
||||
@ -148,8 +148,8 @@ tx.output({
|
||||
|
||||
// Fill the transaction inputs with the
|
||||
// necessary unspents (hopefully we have them!).
|
||||
tx.fillUnspent(
|
||||
wallet.unspent(), // Our unspents to choose from
|
||||
tx.fill(
|
||||
wallet.getUnspent(), // Our unspents to choose from
|
||||
wallet.getAddress(), // Our change address (warning: address re-use)
|
||||
null // We could put a hard fee here, but lets let bcoin figure it out
|
||||
);
|
||||
@ -252,7 +252,7 @@ utils.assert(buyer.getScriptAddress() === mediator.getScriptAddress());
|
||||
utils.print('Created 2-of-3 wallet with address: %s', buyer.getScriptAddress());
|
||||
|
||||
// Create a fake coinbase for buyer to use as his funds
|
||||
var coinbase = bcoin.tx().output(buyer.getKeyAddress(), utils.satoshi('50.0'));
|
||||
var coinbase = bcoin.tx().addOutput(buyer.getKeyAddress(), utils.satoshi('50.0'));
|
||||
buyer.addTX(coinbase);
|
||||
|
||||
// Now let's create a tx as the buyer.
|
||||
@ -261,13 +261,14 @@ var btx = bcoin.tx();
|
||||
|
||||
// Send 25 BTC to the shared wallet
|
||||
// to buy something from seller.
|
||||
btx.output({
|
||||
btx.addOutput({
|
||||
address: buyer.getScriptAddress(),
|
||||
value: utils.satoshi('25.0')
|
||||
});
|
||||
|
||||
// Fill the unspents and sign
|
||||
buyer.fillUnspent(btx);
|
||||
if (!buyer.fill(btx))
|
||||
throw new Error('Not enough funds');
|
||||
buyer.sign(btx);
|
||||
|
||||
// Buyer sends his funds to the 2-of-3 wallet
|
||||
@ -280,7 +281,7 @@ seller.addTX(btx);
|
||||
var stx = bcoin.tx();
|
||||
|
||||
// Seller wants to send the BTC to himself
|
||||
stx.output({
|
||||
stx.addOutput({
|
||||
address: seller.getKeyAddress(),
|
||||
value: utils.satoshi('25.0')
|
||||
// Subtract the fee
|
||||
@ -291,13 +292,13 @@ stx.output({
|
||||
|
||||
// Give the mediator a little something,
|
||||
// since he's such a cool guy.
|
||||
stx.output({
|
||||
stx.addOutput({
|
||||
address: mediator.getKeyAddress(),
|
||||
value: utils.satoshi('1.0')
|
||||
});
|
||||
|
||||
// Add the buyer's utxo as the input
|
||||
stx.input(btx, 0);
|
||||
stx.addInput(btx, 0);
|
||||
|
||||
// Add _one_ signature to the tx
|
||||
seller.sign(stx);
|
||||
@ -329,7 +330,7 @@ and human-writable. For example, a standard pay-to-pubkey script would look
|
||||
like:
|
||||
|
||||
``` js
|
||||
tx.output({
|
||||
tx.addOutput({
|
||||
value: new bn(100000),
|
||||
script: [
|
||||
'dup',
|
||||
@ -347,9 +348,9 @@ prefixes removed. Pushdata ops are represented with Arrays.
|
||||
The above script could be redeemed with:
|
||||
|
||||
``` js
|
||||
tx2.input({
|
||||
out: { tx: tx, hash: tx.hash('hex'), index: 0 },
|
||||
seq: 0xffffffff,
|
||||
tx2.addInput({
|
||||
prevout: { tx: tx, hash: tx.hash('hex'), index: 0 },
|
||||
sequence: 0xffffffff,
|
||||
script: [
|
||||
signature, // Byte Array
|
||||
publicKey // Byte Array
|
||||
@ -408,14 +409,14 @@ var wallet = bcoin.wallet({
|
||||
]
|
||||
});
|
||||
console.log(wallet.getScriptAddress());
|
||||
var tx1 = bcoin.tx().output(wallet.getScriptAddress(), new bn(100000));
|
||||
var tx1 = bcoin.tx().addOutput(wallet.getScriptAddress(), new bn(100000));
|
||||
```
|
||||
|
||||
Which would be redeemed with:
|
||||
|
||||
``` js
|
||||
tx2.input({
|
||||
out: { tx: tx1, hash: tx1.hash('hex'), index: 0 },
|
||||
tx2.addInput({
|
||||
prevout: { tx: tx1, hash: tx1.hash('hex'), index: 0 },
|
||||
script: [
|
||||
2,
|
||||
// Redeem script:
|
||||
@ -437,7 +438,7 @@ var bn = bcoin.bn;
|
||||
...
|
||||
|
||||
// Add an output with 100,000 satoshis as a value.
|
||||
tx.output(wallet.getKeyAddress(), new bn(100000));
|
||||
tx.addOutput(wallet.getKeyAddress(), new bn(100000));
|
||||
```
|
||||
|
||||
To make this easier to deal with, bcoin has two helper functions: `utils.btc()`
|
||||
@ -642,6 +643,7 @@ Subtype can be `block`, `merkleblock`, or `header`.
|
||||
validation will fail.
|
||||
- __isGenesis()__ - Returns true if block is the genesis block of the network.
|
||||
before the reference node.
|
||||
- __getSize()__ - Return block size in bytes.
|
||||
- __getHeight()__ - Returns height in the blockchain. Returns `-1` if block is
|
||||
not present in the chain.
|
||||
node.
|
||||
@ -933,7 +935,7 @@ Usage: `bcoin.input([options])`
|
||||
- __out.hash__ - Previous output's txid as a hex string.
|
||||
- __out.index__ - Previous output's index.
|
||||
- __script__ - Array of opcodes.
|
||||
- __seq__ - Input's nSequence, `0xffffffff` by default.
|
||||
- __sequence__ - Input's nSequence, `0xffffffff` by default.
|
||||
|
||||
##### Properties:
|
||||
|
||||
@ -968,8 +970,8 @@ which parse the script and grab the previous output data and cache it as
|
||||
- __scriptaddress__ - The p2sh address.
|
||||
- __m__ - `m` value (required signatures).
|
||||
- __n__ - `n` value (number of keys).
|
||||
- __lock__ - The OP_CHECKLOCKTIMEVERIFY locktime if present (NOTE: This will only
|
||||
grab the first value and not deal with OP_IF statements, etc).
|
||||
- __lockTime__ - The OP_CHECKLOCKTIMEVERIFY locktime if present (NOTE: This
|
||||
will only grab the first value and not deal with OP_IF statements, etc).
|
||||
- __flags__ - Coinbase flags if present.
|
||||
- __text__ - Coinbase flags converted to UTF-8, if present.
|
||||
- __output__ - Previous Output object.
|
||||
@ -1034,8 +1036,8 @@ script and cache it as `_data`.
|
||||
- __scriptaddress__ - The p2sh address.
|
||||
- __m__ - `m` value (required signatures).
|
||||
- __n__ - `n` value (number of keys).
|
||||
- __lock__ - The OP_CHECKLOCKTIMEVERIFY locktime if present (NOTE: This will only
|
||||
grab the first value and not deal with OP_IF statements, etc).
|
||||
- __lockTime__ - The OP_CHECKLOCKTIMEVERIFY locktime if present (NOTE: This
|
||||
will only grab the first value and not deal with OP_IF statements, etc).
|
||||
- __flags__ - `nulldata` data.
|
||||
- __text__ - `nulldata` data converted to UTF-8.
|
||||
|
||||
@ -1406,10 +1408,10 @@ Usage: `bcoin.txPool(wallet)`
|
||||
|
||||
- Inherits all from EventEmitter.
|
||||
- __add(tx)__ - Add TX to the pool.
|
||||
- __all()__ - Return all TXes in the pool owned by wallet.
|
||||
- __unspent()__ - Return all TXes with unspent outputs, owned by wallet.
|
||||
- __pending()__ - Return all 0-confirmation transactions.
|
||||
- __balance()__ - Return total balance of TX pool.
|
||||
- __getAll()__ - Return all TXes in the pool owned by wallet.
|
||||
- __getUnspent()__ - Return all TXes with unspent outputs, owned by wallet.
|
||||
- __getPending()__ - Return all 0-confirmation transactions.
|
||||
- __getBalance()__ - Return total balance of TX pool.
|
||||
- __toJSON()__ - Return TX pool in serialized JSON format.
|
||||
- __fromJSON()__ - Load TX pool from serialized JSON format.
|
||||
|
||||
@ -1427,9 +1429,9 @@ Usage: `bcoin.tx([options], [block])`
|
||||
##### Options:
|
||||
|
||||
- __version__ - Transaction version (default: 1).
|
||||
- __inputs__ - Array of input objects with `tx.input()` options.
|
||||
- __outputs__ - Array of output objects with `tx.output()` options.
|
||||
- __lock__ - nLockTime value.
|
||||
- __inputs__ - Array of input objects with `tx.addInput()` options.
|
||||
- __outputs__ - Array of output objects with `tx.addOutput()` options.
|
||||
- __lockTime__ - nLockTime value.
|
||||
- __ts__ - Timestamp (set by `block` if passed in arguments - spv-mode).
|
||||
- __block__ - Block hash (Set by `block` if passed in arguments - spv-mode).
|
||||
- __network__ - Should be `true` if TX came in from the network.
|
||||
@ -1468,34 +1470,35 @@ Usage: `bcoin.tx([options], [block])`
|
||||
- __render([force])__ - Serialize transaction. Returns raw byte array. Will
|
||||
return raw data passed in from the network if available. Set `force=true` to
|
||||
force serialization.
|
||||
- __size()__ - Return serializzed transaction size in bytes.
|
||||
- __input(options)__ - Add an input to the transaction. Options can be an Input
|
||||
object (see above), in the form of an Input object (containing properties
|
||||
`out.tx`, `out.hash`, `out.index`, `script`, and `seq`).
|
||||
- `input()` can handle many different arguments in the forms of:
|
||||
- `tx.input(tx, index)`
|
||||
- `tx.input(txHash, index)`
|
||||
- `tx.input(input)`
|
||||
- `tx.input({ hash: hash, index: index })`
|
||||
- `tx.input({ tx: tx, index: index })`
|
||||
- __getSize()__ - Return serializzed transaction size in bytes.
|
||||
- __addInput(options)__ - Add an input to the transaction. Options can be an
|
||||
Input object (see above), in the form of an Input object (containing
|
||||
properties `prevout.tx`, `prevout.hash`, `prevout.index`, `script`, and
|
||||
`sequence`).
|
||||
- `addInput()` can handle many different arguments in the forms of:
|
||||
- `tx.addInput(tx, index)`
|
||||
- `tx.addInput(txHash, index)`
|
||||
- `tx.addInput(input)`
|
||||
- `tx.addInput({ hash: hash, index: index })`
|
||||
- `tx.addInput({ tx: tx, index: index })`
|
||||
- __scriptInput(index/input, pub, redeem)__ - Initialize the input scripts
|
||||
based on previous output script type. `n` signatures will be added.
|
||||
Signatures will be null dummies (empty signature slots) until `signInput()`
|
||||
is called. `pub` (the public key) and `redeem` (raw redeem script) should
|
||||
always be passed in if there is a pubkeyhash or scripthash output being
|
||||
redeemed. Will not overwrite existing input scripts.
|
||||
- __signature(index/input, key, [type])__ - Create a signature for the desired
|
||||
input using `key` as the private key and `type` as the sighash type. Sighash
|
||||
type can be a number or a string (`all`, `single`, or `none`). Returns a DER
|
||||
signature byte array.
|
||||
- __createSignature(index/input, key, [type])__ - Create a signature for the
|
||||
desired input using `key` as the private key and `type` as the sighash type.
|
||||
Sighash type can be a number or a string (`all`, `single`, or `none`).
|
||||
Returns a DER signature byte array.
|
||||
- __signInput(index/input, key, [type])__ - Sign the desired input and place
|
||||
the signature in an empty signature slot. Finalize the input script and
|
||||
reduce signature slots to `m` once the minimum amount of signatures has been
|
||||
reached.
|
||||
- __scriptSig(index/input, key, pub, redeem, type)__ - Execute `scriptInput`
|
||||
_and_ `signInput`.
|
||||
- __output(options), output(output), output(address, value)__ - Add an output to the
|
||||
transaction.
|
||||
- __addOutput(options), addOutput(output), addOutput(address, value)__ - Add an
|
||||
output to the transaction.
|
||||
- `options` can be in the form of:
|
||||
|
||||
{
|
||||
@ -1507,11 +1510,11 @@ Usage: `bcoin.tx([options], [block])`
|
||||
n: [n value],
|
||||
flags: [nulldata],
|
||||
scripthash: [true or false],
|
||||
lock: [locktime for checklocktimeverify]
|
||||
lockTime: [locktime for checklocktimeverify]
|
||||
}
|
||||
|
||||
- __scriptOutput(index/output, options)__ - Compile an output script for the
|
||||
output based on the same options `output()` handles.
|
||||
output based on the same options `addOutput()` handles.
|
||||
- __signatureHash(index/input, s, type)__ - Return the to-be-signed hash of the
|
||||
transaction for the desired input. Must pass in previous output subscript as
|
||||
`s`, as well as the sighash type (number or string of `all`, `none`, or
|
||||
@ -1525,9 +1528,9 @@ Usage: `bcoin.tx([options], [block])`
|
||||
- __isCoinbase()__ - Returns true if TX is a coinbase.
|
||||
- __maxSize()__ - Estimate the size of the transaction in bytes (works before
|
||||
input scripts are compiled and signed). Useful for fee calculation.
|
||||
- __getUnspent(unspent, changeAddress, [fee])__ - Determine which unspents to
|
||||
- __getInputs(unspent, changeAddress, [fee])__ - Determine which unspents to
|
||||
use from `unspent` (an array of possible unspents, usually returned by
|
||||
`wallet.unspent()`). Calculates the fee and chooses unspents based on the
|
||||
`wallet.getUnspent()`). Calculates the fee and chooses unspents based on the
|
||||
total value required for the transaction. A hard `fee` can be passed in
|
||||
(satoshis/big number) which will skip the fee calculation. Calculates the
|
||||
necessary change. Returns an object in the form of:
|
||||
@ -1542,22 +1545,22 @@ Usage: `bcoin.tx([options], [block])`
|
||||
}
|
||||
|
||||
`inputs` will be `null` if not enough funds were available.
|
||||
__NOTE:__ `getUnspent()` should only be called once all outputs have been added.
|
||||
- __fillUnspent(unspent, [changeAddress], [fee])__ - Calls `getUnspent()` and
|
||||
__NOTE:__ `getInputs()` should only be called once all outputs have been added.
|
||||
- __fill(unspent, [changeAddress], [fee])__ - Calls `getInputs()` and
|
||||
adds the created inputs to the transaction. Adds a change output if
|
||||
necessary. Returns the same result value as `getUnspent()`. __NOTE:__ Should
|
||||
necessary. Returns the same result value as `getInputs()`. __NOTE:__ Should
|
||||
only be called once all outputs have been added.
|
||||
- __getFee()__ - Returns the fee for transaction.
|
||||
- __funds(side)__ - Returns the total funds for a side of the transaction
|
||||
`'in'` or `'out'`.
|
||||
- __setLockTime(lock)__ - Sets a locktime for the transaction. Will set the
|
||||
- __getFunds(side)__ - Returns the total funds for a side of the transaction
|
||||
`'input'` or `'output'`.
|
||||
- __setLockTime(lockTime)__ - Sets a locktime for the transaction. Will set the
|
||||
nSequences accordingly.
|
||||
- __increaseFee(fee)__ - Increase fee to a hard fee. Opts transaction in for
|
||||
replace-by-fee. __NOTE:__ Transaction must be rescripted and resigned before
|
||||
broadcasting.
|
||||
- __fill(wallet/txpool/object)__ - Fills all the transaction's inputs with the
|
||||
appropriate previous outputs using the available transactions in a wallet,
|
||||
txpool, or an object with txids as its keys and txs as its values.
|
||||
- __fillPrevout(wallet/txpool/object)__ - Fills all the transaction's inputs
|
||||
with the appropriate previous outputs using the available transactions in a
|
||||
wallet, txpool, or an object with txids as its keys and txs as its values.
|
||||
- __isFull()__ - Returns true if the TX has all previous output references.
|
||||
- __isFinal(height, ts)__ - Mimics the bitcoind `IsFinalTx()` function. Checks
|
||||
the locktime and input sequences. Returns true or false.
|
||||
@ -1616,7 +1619,7 @@ Usage: `bcoin.wallet(options)`
|
||||
|
||||
##### Events:
|
||||
|
||||
- __balance(balance)__ - Emitted when balance is updated. `balance` is in
|
||||
- __getBalance(balance)__ - Emitted when balance is updated. `balance` is in
|
||||
satoshis (big number).
|
||||
- __tx(tx)__ - Emitted when a TX is added to the wallet's TXPool.
|
||||
- __load(ts)__ - Emitted when the TXPool is finished loading. `ts` is the
|
||||
@ -1646,9 +1649,10 @@ Usage: `bcoin.wallet(options)`
|
||||
this wallet. If `index` is not present, all outputs will be tested.
|
||||
- __ownInput(tx, [index])__ - Check to see if input at `index` pertains to
|
||||
this wallet. If `index` is not present, all inputs will be tested.
|
||||
- __fillUnspent(tx, [changeAddress], [fee])__ - Fill tx with inputs necessary
|
||||
for total output value. Uses `wallet.unspent()` as the unspent list.
|
||||
- __fillTX(tx)__ - "Fill" a transactions' inputs with references to its
|
||||
- __fill(tx, [changeAddress], [fee])__ - Fill tx with inputs necessary for
|
||||
total output value. Uses `wallet.getUnspent()` as the unspent list. Returns true
|
||||
if successfully filled necessary funds.
|
||||
- __fillPrevout(tx)__ - "Fill" a transactions' inputs with references to its
|
||||
previous outputs if available.
|
||||
- __scriptInputs(tx)__ - Compile necessary scripts for inputs (with OP_0 where
|
||||
the signatures should be). Will not overwrite existing input scripts.
|
||||
@ -1657,13 +1661,11 @@ Usage: `bcoin.wallet(options)`
|
||||
- __sign(tx)__ - Equivalent to calling both `scriptInputs(tx)` and
|
||||
`signInputs(tx)` in one go.
|
||||
- __addTX(tx)__ - Add a transaction to the wallet's TXPool.
|
||||
- __all()__ - Returns all transactions from the TXPool.
|
||||
- __unspent()__ - Returns all TXes with unspent outputs from the TXPool.
|
||||
- __pending()__ - Returns all TXes in the TXPool that have yet to be included
|
||||
- __getAll()__ - Returns all transactions from the TXPool.
|
||||
- __getUnspent()__ - Returns all TXes with unspent outputs from the TXPool.
|
||||
- __getPending()__ - Returns all TXes in the TXPool that have yet to be included
|
||||
in a block.
|
||||
- __balance()__ - Returns total balance of the TXPool.
|
||||
- __fill(tx)__ - Attempt to `fillUnspent(tx)`. Return `null` if failed to reach
|
||||
total output value. Return `tx` if successful.
|
||||
- __getBalance()__ - Returns total balance of the TXPool.
|
||||
- __toAddress()__ - Return blockchain-explorer-like data in the format of:
|
||||
|
||||
{
|
||||
|
||||
@ -128,10 +128,13 @@ Block.prototype.render = function render() {
|
||||
return bcoin.protocol.framer.block(this, this.subtype);
|
||||
};
|
||||
|
||||
Block.prototype.size = function size() {
|
||||
Block.prototype.getSize = function getSize() {
|
||||
return this._size || this.render().length;
|
||||
};
|
||||
|
||||
// Legacy
|
||||
Block.prototype.size = Block.prototype.getSize;
|
||||
|
||||
Block.prototype.hasTX = function hasTX(hash) {
|
||||
return this.tx.indexOf(hash) !== -1;
|
||||
};
|
||||
@ -255,7 +258,7 @@ Block.prototype._verify = function _verify() {
|
||||
|
||||
// Size can't be bigger than MAX_BLOCK_SIZE
|
||||
if (this.txs.length > constants.block.maxSize
|
||||
|| this.size() > constants.block.maxSize) {
|
||||
|| this.getSize() > constants.block.maxSize) {
|
||||
utils.debug('Block is too large: %s', this.rhash);
|
||||
return false;
|
||||
}
|
||||
@ -456,10 +459,10 @@ Block.prototype.verifyContext = function verifyContext() {
|
||||
|
||||
// We need the previous output in order
|
||||
// to verify the script.
|
||||
if (!input.out.tx)
|
||||
if (!input.prevout.tx)
|
||||
continue;
|
||||
|
||||
assert(input.out.tx);
|
||||
assert(input.prevout.tx);
|
||||
|
||||
// Verify the script
|
||||
if (!tx.verify(j, true, flags)) {
|
||||
@ -468,7 +471,7 @@ Block.prototype.verifyContext = function verifyContext() {
|
||||
}
|
||||
|
||||
// Ensure tx is not double spending an output
|
||||
// if (this.chain.isSpent(input.out.hash, input.out.index)) {
|
||||
// if (this.chain.isSpent(input.prevout.hash, input.prevout.index)) {
|
||||
// utils.debug('Block is using spent inputs: %s', this.rhash);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
@ -519,7 +519,7 @@ Chain.prototype.hashRange = function hashRange(start, end) {
|
||||
return hashes;
|
||||
};
|
||||
|
||||
Chain.prototype.locatorHashes = function locatorHashes(start) {
|
||||
Chain.prototype.getLocator = function getLocator(start) {
|
||||
var hashes = [];
|
||||
var top = this.height();
|
||||
var step = 1;
|
||||
|
||||
@ -14,25 +14,50 @@ var constants = bcoin.protocol.constants;
|
||||
*/
|
||||
|
||||
function Input(options) {
|
||||
var prevout;
|
||||
|
||||
if (!(this instanceof Input))
|
||||
return new Input(options);
|
||||
|
||||
this.out = {
|
||||
tx: options.out.tx || null,
|
||||
hash: options.out.hash,
|
||||
index: options.out.index
|
||||
prevout = options.prevout || options.out;
|
||||
|
||||
this.prevout = {
|
||||
tx: prevout.tx || null,
|
||||
hash: prevout.hash,
|
||||
index: prevout.index
|
||||
};
|
||||
|
||||
if (typeof this.out.hash !== 'string')
|
||||
this.out.hash = utils.toHex(this.out.hash);
|
||||
if (utils.isBuffer(this.prevout.hash))
|
||||
this.prevout.hash = utils.toHex(this.prevout.hash);
|
||||
|
||||
this.script = options.script ? options.script.slice() : [];
|
||||
this.seq = options.seq === undefined ? 0xffffffff : options.seq;
|
||||
this.sequence = options.sequence == null ? 0xffffffff : options.sequence;
|
||||
|
||||
// Legacy
|
||||
if (options.seq != null)
|
||||
this.sequence = options.seq;
|
||||
|
||||
if (options.script && options.script._raw)
|
||||
utils.hidden(this.script, '_raw', options.script._raw);
|
||||
}
|
||||
|
||||
// Legacy
|
||||
Input.prototype.__defineSetter__('seq', function(sequence) {
|
||||
return this.sequence = sequence;
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('seq', function() {
|
||||
return this.sequence;
|
||||
});
|
||||
|
||||
Input.prototype.__defineSetter__('out', function(prevout) {
|
||||
return this.prevout = prevout;
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('out', function() {
|
||||
return this.prevout;
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('data', function() {
|
||||
var data;
|
||||
|
||||
@ -41,7 +66,7 @@ Input.prototype.__defineGetter__('data', function() {
|
||||
|
||||
data = Input.getData(this);
|
||||
|
||||
if (this.script.length && this.out.tx)
|
||||
if (this.script.length && this.prevout.tx)
|
||||
utils.hidden(this, '_data', data);
|
||||
|
||||
return data;
|
||||
@ -107,10 +132,10 @@ Input.prototype.__defineGetter__('n', function() {
|
||||
return this.data.n || this.m;
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('lock', function() {
|
||||
Input.prototype.__defineGetter__('lockTime', function() {
|
||||
if (!this.output)
|
||||
return 0;
|
||||
return this.output.lock;
|
||||
return this.output.lockTime;
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('flags', function() {
|
||||
@ -122,9 +147,9 @@ Input.prototype.__defineGetter__('text', function() {
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('output', function() {
|
||||
if (!this.out.tx)
|
||||
if (!this.prevout.tx)
|
||||
return;
|
||||
return this.out.tx.outputs[this.out.index];
|
||||
return this.prevout.tx.outputs[this.prevout.index];
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('value', function() {
|
||||
@ -134,7 +159,7 @@ Input.prototype.__defineGetter__('value', function() {
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('tx', function() {
|
||||
return this.out.tx;
|
||||
return this.prevout.tx;
|
||||
});
|
||||
|
||||
Input.prototype.__defineGetter__('addr', function() {
|
||||
@ -182,7 +207,7 @@ Input.prototype.__defineGetter__('scriptaddr', function() {
|
||||
// height: Number,
|
||||
// flags: Array,
|
||||
// text: String,
|
||||
// lock: Number,
|
||||
// lockTime: Number,
|
||||
// value: bn,
|
||||
// script: Array,
|
||||
// seq: Number,
|
||||
@ -204,12 +229,12 @@ Input.getData = function getData(input) {
|
||||
seq: input.seq
|
||||
};
|
||||
|
||||
if (input.out) {
|
||||
def.prev = input.out.hash;
|
||||
def.index = input.out.index;
|
||||
if (input.prevout) {
|
||||
def.prev = input.prevout.hash;
|
||||
def.index = input.prevout.index;
|
||||
}
|
||||
|
||||
if (input.out && +input.out.hash === 0) {
|
||||
if (input.prevout && +input.prevout.hash === 0) {
|
||||
data = bcoin.script.getCoinbaseData(input.script);
|
||||
return utils.merge(def, data, {
|
||||
type: 'coinbase',
|
||||
@ -217,8 +242,8 @@ Input.getData = function getData(input) {
|
||||
});
|
||||
}
|
||||
|
||||
if (input.out && input.out.tx) {
|
||||
output = input.out.tx.outputs[input.out.index];
|
||||
if (input.prevout && input.prevout.tx) {
|
||||
output = input.prevout.tx.outputs[input.prevout.index];
|
||||
if (output) {
|
||||
data = bcoin.script.getInputData(input.script, output.script);
|
||||
data.value = output.value;
|
||||
@ -229,6 +254,10 @@ Input.getData = function getData(input) {
|
||||
return utils.merge(def, bcoin.script.getInputData(input.script));
|
||||
};
|
||||
|
||||
Input.prototype.isFinal = function isFinal() {
|
||||
return this.sequence === 0xffffffff;
|
||||
};
|
||||
|
||||
Input.prototype.getID = function getID() {
|
||||
var data = bcoin.script.encode(this.script);
|
||||
var hash = utils.toHex(utils.ripesha(data));
|
||||
@ -240,9 +269,9 @@ Input.prototype.inspect = function inspect() {
|
||||
? this.output.inspect()
|
||||
: { type: 'unknown', value: '0.0' };
|
||||
|
||||
output.hash = this.out.hash;
|
||||
output.rhash = utils.revHex(this.out.hash);
|
||||
output.index = this.out.index;
|
||||
output.hash = this.prevout.hash;
|
||||
output.rhash = utils.revHex(this.prevout.hash);
|
||||
output.index = this.prevout.index;
|
||||
|
||||
return {
|
||||
type: this.type,
|
||||
@ -254,7 +283,7 @@ Input.prototype.inspect = function inspect() {
|
||||
scriptaddress: this.scriptaddress,
|
||||
signatures: this.signatures.map(utils.toHex),
|
||||
text: this.text,
|
||||
lock: this.lock,
|
||||
lockTime: this.lockTime,
|
||||
value: utils.btc(output.value),
|
||||
script: bcoin.script.format(this.script)[0],
|
||||
redeem: this.redeem ? bcoin.script.format(this.redeem)[0] : null,
|
||||
|
||||
@ -142,7 +142,7 @@ Miner.prototype.addTX = function addTX(tx) {
|
||||
var full, ts;
|
||||
|
||||
full = this.index.inputs.every(function(input) {
|
||||
return !!input.out.tx;
|
||||
return !!input.prevout.tx;
|
||||
});
|
||||
|
||||
// Cannot calculate fee if we don't have the prev_out.
|
||||
@ -200,7 +200,7 @@ Miner.prototype.createBlock = function createBlock(tx) {
|
||||
coinbase = bcoin.tx();
|
||||
|
||||
coinbase.input({
|
||||
out: {
|
||||
prevout: {
|
||||
hash: utils.toHex(constants.zeroHash),
|
||||
index: 0xffffffff
|
||||
},
|
||||
@ -226,7 +226,7 @@ Miner.prototype.createBlock = function createBlock(tx) {
|
||||
if (script.size(coinbase.inputs[0].script) > 100)
|
||||
throw new Error('Coinbase script is too large');
|
||||
|
||||
coinbase.output({
|
||||
coinbase.addOutput({
|
||||
address: this.address,
|
||||
value: new bn(0)
|
||||
});
|
||||
|
||||
@ -105,7 +105,7 @@ Output.prototype.__defineGetter__('n', function() {
|
||||
return this.data.n || this.m;
|
||||
});
|
||||
|
||||
Output.prototype.__defineGetter__('lock', function() {
|
||||
Output.prototype.__defineGetter__('lockTime', function() {
|
||||
return bcoin.script.getLockTime(this.script);
|
||||
});
|
||||
|
||||
@ -162,7 +162,7 @@ Output.prototype.__defineGetter__('scriptaddr', function() {
|
||||
// height: Number,
|
||||
// flags: Array,
|
||||
// text: String,
|
||||
// lock: Number,
|
||||
// lockTime: Number,
|
||||
// value: bn,
|
||||
// script: Array,
|
||||
// seq: Number,
|
||||
@ -203,7 +203,7 @@ Output.prototype.inspect = function inspect() {
|
||||
m: this.m,
|
||||
n: this.n,
|
||||
text: this.text,
|
||||
lock: this.lock,
|
||||
lockTime: this.lockTime,
|
||||
value: utils.btc(this.value),
|
||||
script: bcoin.script.format(this.script)[0]
|
||||
};
|
||||
|
||||
@ -1008,7 +1008,7 @@ Pool.prototype.isWatched = function(tx, bloom) {
|
||||
// 4. Test data elements in input scripts
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
prev = input.out.hash;
|
||||
prev = input.prevout.hash;
|
||||
|
||||
if (typeof prev === 'string')
|
||||
prev = utils.toArray(prev, 'hex');
|
||||
@ -1018,8 +1018,8 @@ Pool.prototype.isWatched = function(tx, bloom) {
|
||||
return true;
|
||||
|
||||
// Test the prev_out script
|
||||
if (input.out.tx) {
|
||||
prev = input.out.tx.outputs[input.out.index];
|
||||
if (input.prevout.tx) {
|
||||
prev = input.prevout.tx.outputs[input.prevout.index];
|
||||
if (testScript(prev.script))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -280,14 +280,14 @@ Framer.tx = function tx(tx) {
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
|
||||
off += utils.copy(utils.toArray(input.out.hash, 'hex'), p, off, true);
|
||||
off += utils.writeU32(p, input.out.index, off);
|
||||
off += utils.copy(utils.toArray(input.prevout.hash, 'hex'), p, off, true);
|
||||
off += utils.writeU32(p, input.prevout.index, off);
|
||||
|
||||
s = bcoin.script.encode(input.script);
|
||||
off += utils.writeIntv(p, s.length, off);
|
||||
off += utils.copy(s, p, off, true);
|
||||
|
||||
off += utils.writeU32(p, input.seq, off);
|
||||
off += utils.writeU32(p, input.sequence, off);
|
||||
}
|
||||
|
||||
off += utils.writeIntv(p, tx.outputs.length, off);
|
||||
@ -301,7 +301,7 @@ Framer.tx = function tx(tx) {
|
||||
off += utils.writeIntv(p, s.length, off);
|
||||
off += utils.copy(s, p, off, true);
|
||||
}
|
||||
off += utils.writeU32(p, tx.lock, off);
|
||||
off += utils.writeU32(p, tx.lockTime, off);
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
@ -373,12 +373,12 @@ Parser.prototype.parseTXIn = function parseTXIn(p) {
|
||||
|
||||
return {
|
||||
size: off + scriptLen + 4,
|
||||
out: {
|
||||
prevout: {
|
||||
hash: utils.toArray(p.slice(0, 32)),
|
||||
index: utils.readU32(p, 32)
|
||||
},
|
||||
script: bcoin.script.decode(utils.toArray(p.slice(off, off + scriptLen))),
|
||||
seq: utils.readU32(p, off + scriptLen)
|
||||
sequence: utils.readU32(p, off + scriptLen)
|
||||
};
|
||||
};
|
||||
|
||||
@ -461,7 +461,7 @@ Parser.prototype.parseTX = function parseTX(p) {
|
||||
version: utils.read32(p, 0),
|
||||
inputs: txIn,
|
||||
outputs: txOut,
|
||||
lock: utils.readU32(p, off),
|
||||
lockTime: utils.readU32(p, off),
|
||||
_off: off + 4,
|
||||
_size: p.length
|
||||
};
|
||||
|
||||
@ -386,7 +386,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
var key, sig, type, subscript, hash;
|
||||
var keys, i, j, m;
|
||||
var succ;
|
||||
var lock, threshold;
|
||||
var lockTime, threshold;
|
||||
var evalScript;
|
||||
|
||||
stack.alt = stack.alt || [];
|
||||
@ -934,28 +934,28 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
if (!tx || stack.length === 0)
|
||||
return false;
|
||||
|
||||
lock = stack[stack.length - 1];
|
||||
lockTime = stack[stack.length - 1];
|
||||
|
||||
if (!Array.isArray(lock))
|
||||
if (!Array.isArray(lockTime))
|
||||
return false;
|
||||
|
||||
if (lock.length > 6)
|
||||
if (lockTime.length > 6)
|
||||
return false;
|
||||
|
||||
lock = script.num(lock, true);
|
||||
lockTime = script.num(lockTime, true);
|
||||
|
||||
if (lock < 0)
|
||||
if (lockTime < 0)
|
||||
return false;
|
||||
|
||||
threshold = constants.locktimeThreshold;
|
||||
if (!(
|
||||
(tx.lock < threshold && lock < threshold)
|
||||
|| (tx.lock >= threshold && lock >= threshold)
|
||||
(tx.lockTime < threshold && lockTime < threshold)
|
||||
|| (tx.lockTime >= threshold && lockTime >= threshold)
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lock > tx.lock)
|
||||
if (lockTime > tx.lockTime)
|
||||
return false;
|
||||
|
||||
if (!tx.inputs[index] || tx.inputs[index].seq === 0xffffffff)
|
||||
@ -1312,7 +1312,7 @@ script.getInputData = function getData(s, prev) {
|
||||
};
|
||||
|
||||
script._getInputData = function _getInputData(s, type) {
|
||||
var sig, key, hash, raw, redeem, lock, hash, address, input, output;
|
||||
var sig, key, hash, raw, redeem, lockTime, hash, address, input, output;
|
||||
|
||||
assert(typeof type === 'string');
|
||||
|
||||
@ -1355,7 +1355,7 @@ script._getInputData = function _getInputData(s, type) {
|
||||
if (type === 'scripthash') {
|
||||
raw = s[s.length - 1];
|
||||
redeem = script.decode(raw);
|
||||
lock = script.getLockTime(redeem);
|
||||
lockTime = script.getLockTime(redeem);
|
||||
hash = bcoin.wallet.key2hash(raw);
|
||||
address = bcoin.wallet.hash2addr(hash, 'scripthash');
|
||||
output = script.getOutputData(script.getSubscript(redeem));
|
||||
@ -1368,7 +1368,7 @@ script._getInputData = function _getInputData(s, type) {
|
||||
redeem: redeem,
|
||||
scripthash: hash,
|
||||
scriptaddress: address,
|
||||
lock: lock
|
||||
lockTime: lockTime
|
||||
});
|
||||
}
|
||||
|
||||
@ -2063,8 +2063,8 @@ script.format = function format(input, output) {
|
||||
scripts.push(output);
|
||||
} else if (input) {
|
||||
scripts.push(input.script);
|
||||
if (input.out.tx && input.out.tx.outputs[input.out.index]) {
|
||||
prev = input.out.tx.outputs[input.out.index].script;
|
||||
if (input.prevout.tx && input.prevout.tx.outputs[input.prevout.index]) {
|
||||
prev = input.prevout.tx.outputs[input.prevout.index].script;
|
||||
scripts.push(prev);
|
||||
if (script.isScripthash(prev)) {
|
||||
redeem = script.decode(input.script[input.script.length - 1]);
|
||||
|
||||
@ -93,20 +93,20 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
||||
// Consume unspent money or add orphans
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
key = input.out.hash + '/' + input.out.index;
|
||||
key = input.prevout.hash + '/' + input.prevout.index;
|
||||
unspent = this._unspent[key];
|
||||
|
||||
if (!input.out.tx && this._all[input.out.hash])
|
||||
input.out.tx = this._all[input.out.hash];
|
||||
if (!input.prevout.tx && this._all[input.prevout.hash])
|
||||
input.prevout.tx = this._all[input.prevout.hash];
|
||||
|
||||
if (unspent) {
|
||||
// Add TX to inputs and spend money
|
||||
index = tx._inputIndex(unspent.tx.hash('hex'), unspent.index);
|
||||
assert(index !== -1);
|
||||
assert(tx.inputs[index] === input);
|
||||
assert(tx.inputs[index].out.hash === unspent.tx.hash('hex'));
|
||||
assert(tx.inputs[index].out.index === unspent.index);
|
||||
input.out.tx = unspent.tx;
|
||||
assert(tx.inputs[index].prevout.hash === unspent.tx.hash('hex'));
|
||||
assert(tx.inputs[index].prevout.index === unspent.index);
|
||||
input.prevout.tx = unspent.tx;
|
||||
|
||||
// Skip invalid transactions
|
||||
if (!tx.verify(index))
|
||||
@ -123,13 +123,13 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
||||
// signature checking code to ownInput for p2sh and p2pk,
|
||||
// we could in theory use ownInput here (and down below)
|
||||
// instead.
|
||||
if (input.out.tx) {
|
||||
if (!this._wallet.ownOutput(input.out.tx, input.out.index))
|
||||
if (input.prevout.tx) {
|
||||
if (!this._wallet.ownOutput(input.prevout.tx, input.prevout.index))
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add orphan, if no parent transaction is yet known
|
||||
orphan = { tx: tx, index: input.out.index };
|
||||
orphan = { tx: tx, index: input.prevout.index };
|
||||
if (this._orphans[key])
|
||||
this._orphans[key].push(orphan);
|
||||
else
|
||||
@ -149,9 +149,9 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
||||
function checkOrphan(orphan) {
|
||||
var index = orphan.tx._inputIndex(tx.hash('hex'), orphan.index);
|
||||
assert(index !== -1);
|
||||
assert(orphan.tx.inputs[index].out.hash === tx.hash('hex'));
|
||||
assert(orphan.tx.inputs[index].out.index === i);
|
||||
orphan.tx.inputs[index].out.tx = tx;
|
||||
assert(orphan.tx.inputs[index].prevout.hash === tx.hash('hex'));
|
||||
assert(orphan.tx.inputs[index].prevout.index === i);
|
||||
orphan.tx.inputs[index].prevout.tx = tx;
|
||||
|
||||
// Verify that input script is correct, if not - add output to unspent
|
||||
// and remove orphan from storage
|
||||
@ -225,7 +225,7 @@ TXPool.prototype._removeTX = function _removeTX(tx, noWrite) {
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.all = function all() {
|
||||
TXPool.prototype.getAll = function getAll() {
|
||||
return Object.keys(this._all).map(function(key) {
|
||||
return this._all[key];
|
||||
}, this).filter(function(tx) {
|
||||
@ -234,7 +234,7 @@ TXPool.prototype.all = function all() {
|
||||
}, this);
|
||||
};
|
||||
|
||||
TXPool.prototype.unspent = function unspent() {
|
||||
TXPool.prototype.getUnspent = function getUnspent() {
|
||||
return Object.keys(this._unspent).map(function(key) {
|
||||
return this._unspent[key];
|
||||
}, this).filter(function(item) {
|
||||
@ -246,7 +246,7 @@ TXPool.prototype.hasUnspent = function hasUnspent(hash, unspent) {
|
||||
var has;
|
||||
|
||||
if (utils.isBuffer(hash) && hash.length && typeof hash[0] !== 'number') {
|
||||
unspent = this.unspent();
|
||||
unspent = this.getUnspent();
|
||||
has = hash.map(function(hash) {
|
||||
var h = this.hasUnspent(hash, unspent);
|
||||
if (!h)
|
||||
@ -260,14 +260,14 @@ TXPool.prototype.hasUnspent = function hasUnspent(hash, unspent) {
|
||||
|
||||
if (utils.isBuffer(hash))
|
||||
hash = utils.toHex(hash);
|
||||
else if (hash.out)
|
||||
hash = hash.out.hash;
|
||||
else if (hash.prevout)
|
||||
hash = hash.prevout.hash;
|
||||
else if (hash.tx)
|
||||
hash = hash.tx.hash('hex');
|
||||
else if (hash instanceof bcoin.tx)
|
||||
hash = hash.hash('hex');
|
||||
|
||||
unspent = unspent || this.unspent();
|
||||
unspent = unspent || this.getUnspent();
|
||||
|
||||
has = unspent.filter(function(item) {
|
||||
return item.tx.hash('hex') === hash;
|
||||
@ -279,7 +279,7 @@ TXPool.prototype.hasUnspent = function hasUnspent(hash, unspent) {
|
||||
return has;
|
||||
};
|
||||
|
||||
TXPool.prototype.pending = function pending() {
|
||||
TXPool.prototype.getPending = function getPending() {
|
||||
return Object.keys(this._all).map(function(key) {
|
||||
return this._all[key];
|
||||
}, this).filter(function(tx) {
|
||||
@ -287,9 +287,9 @@ TXPool.prototype.pending = function pending() {
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.balance = function balance() {
|
||||
TXPool.prototype.getBalance = function getBalance() {
|
||||
var acc = new bn(0);
|
||||
var unspent = this.unspent();
|
||||
var unspent = this.getUnspent();
|
||||
if (unspent.length === 0)
|
||||
return acc;
|
||||
|
||||
@ -298,6 +298,12 @@ TXPool.prototype.balance = function balance() {
|
||||
}, acc);
|
||||
};
|
||||
|
||||
// Legacy
|
||||
TXPool.prototype.all = TXPool.prototype.getAll;
|
||||
TXPool.prototype.unspent = TXPool.prototype.getUnspent;
|
||||
TXPool.prototype.pending = TXPool.prototype.getPending;
|
||||
TXPool.prototype.balance = TXPool.prototype.getBalance;
|
||||
|
||||
TXPool.prototype.toJSON = function toJSON() {
|
||||
return {
|
||||
v: 1,
|
||||
|
||||
215
lib/bcoin/tx.js
215
lib/bcoin/tx.js
@ -26,11 +26,15 @@ function TX(data, block) {
|
||||
this.version = data.version || 1;
|
||||
this.inputs = [];
|
||||
this.outputs = [];
|
||||
this.lock = data.lock || 0;
|
||||
this.lockTime = data.lockTime || 0;
|
||||
this.ts = data.ts || 0;
|
||||
this.block = data.block || null;
|
||||
this._hash = null;
|
||||
|
||||
// Legacy
|
||||
if (data.lock != null)
|
||||
this.lockTime = data.lock;
|
||||
|
||||
this._raw = data._raw || null;
|
||||
this._size = data._size || 0;
|
||||
|
||||
@ -42,14 +46,14 @@ function TX(data, block) {
|
||||
if (data.inputs) {
|
||||
assert(this.inputs.length === 0);
|
||||
data.inputs.forEach(function(input) {
|
||||
this.input(input);
|
||||
this.addInput(input);
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (data.outputs) {
|
||||
assert(this.outputs.length === 0);
|
||||
data.outputs.forEach(function(output) {
|
||||
this.output(output);
|
||||
this.addOutput(output);
|
||||
}, this);
|
||||
}
|
||||
|
||||
@ -65,15 +69,25 @@ function TX(data, block) {
|
||||
this.subtractFee = data.subtractFee || null;
|
||||
this.changeAddress = data.changeAddress || null;
|
||||
this.changeIndex = data.changeIndex != null ? data.changeIndex : -1;
|
||||
this.total = data.total || null;
|
||||
|
||||
// ps = Pending Since
|
||||
this.ps = this.ts === 0 ? utils.now() : 0;
|
||||
|
||||
// Discourage fee snipping a la bitcoind
|
||||
// if (data.lock == null)
|
||||
// this._avoidFeeSnipping();
|
||||
// if (data.lockTime == null && data.lock == null)
|
||||
// this.avoidFeeSnipping();
|
||||
}
|
||||
|
||||
// Legacy
|
||||
TX.prototype.__defineSetter__('lock', function(lockTime) {
|
||||
return this.lockTime = lockTime;
|
||||
});
|
||||
|
||||
TX.prototype.__defineGetter__('lock', function() {
|
||||
return this.lockTime;
|
||||
});
|
||||
|
||||
TX.prototype.clone = function clone() {
|
||||
return new TX(this);
|
||||
};
|
||||
@ -89,22 +103,26 @@ TX.prototype.render = function render(force) {
|
||||
return bcoin.protocol.framer.tx(this);
|
||||
};
|
||||
|
||||
TX.prototype.size = function size() {
|
||||
TX.prototype.getSize = function getSize() {
|
||||
return this._size || this.render().length;
|
||||
};
|
||||
|
||||
TX.prototype.input = function input(i, index) {
|
||||
this._input(i, index);
|
||||
TX.prototype.size = TX.prototype.getSize;
|
||||
|
||||
TX.prototype.addInput = function addInput(i, index) {
|
||||
this._addInput(i, index);
|
||||
return this;
|
||||
};
|
||||
|
||||
// tx._input(tx, index)
|
||||
// tx._input(hash, index)
|
||||
// tx._input(input)
|
||||
// tx._input({ hash: hash, index: index })
|
||||
// tx._input({ tx: tx, index: index })
|
||||
TX.prototype._input = function _input(obj, index) {
|
||||
var options, hash, input, ex, i;
|
||||
TX.prototype.input = TX.prototype.addInput;
|
||||
|
||||
// tx._addInput(tx, index)
|
||||
// tx._addInput(hash, index)
|
||||
// tx._addInput(input)
|
||||
// tx._addInput({ hash: hash, index: index })
|
||||
// tx._addInput({ tx: tx, index: index })
|
||||
TX.prototype._addInput = function _addInput(obj, index) {
|
||||
var options, hash, input, ex, i, prevout;
|
||||
|
||||
if (obj instanceof TX)
|
||||
options = { tx: obj, index: index };
|
||||
@ -113,10 +131,12 @@ TX.prototype._input = function _input(obj, index) {
|
||||
else
|
||||
options = obj;
|
||||
|
||||
prevout = options.prevout || options.out;
|
||||
|
||||
if (options.tx)
|
||||
hash = options.tx.hash('hex');
|
||||
else if (options.out)
|
||||
hash = options.out.hash;
|
||||
else if (prevout)
|
||||
hash = prevout.hash;
|
||||
else
|
||||
hash = options.hash;
|
||||
|
||||
@ -125,21 +145,21 @@ TX.prototype._input = function _input(obj, index) {
|
||||
|
||||
input = bcoin.input({
|
||||
tx: this,
|
||||
out: {
|
||||
tx: options.out ? options.out.tx : options.tx,
|
||||
prevout: {
|
||||
tx: prevout ? prevout.tx : options.tx,
|
||||
hash: hash,
|
||||
index: options.out ? options.out.index : options.index
|
||||
index: prevout ? prevout.index : options.index
|
||||
},
|
||||
script: options.script,
|
||||
seq: options.seq
|
||||
sequence: options.sequence || options.seq
|
||||
});
|
||||
|
||||
// Try modifying existing input first
|
||||
i = this._inputIndex(input.out.hash, input.out.index);
|
||||
i = this._inputIndex(input.prevout.hash, input.prevout.index);
|
||||
if (i !== -1) {
|
||||
ex = this.inputs[i];
|
||||
input.out.tx = input.out.tx || ex.out.tx;
|
||||
input.seq = input.seq || ex.seq;
|
||||
input.prevout.tx = input.prevout.tx || ex.prevout.tx;
|
||||
input.sequence = input.sequence || ex.sequence;
|
||||
input.script = input.script.length ? input.script : ex.script;
|
||||
this.inputs[i] = input;
|
||||
} else {
|
||||
@ -150,6 +170,8 @@ TX.prototype._input = function _input(obj, index) {
|
||||
return i;
|
||||
};
|
||||
|
||||
TX.prototype._input = TX.prototype._addInput;
|
||||
|
||||
TX.prototype._inputIndex = function _inputIndex(hash, index) {
|
||||
var i, ex;
|
||||
|
||||
@ -158,7 +180,7 @@ TX.prototype._inputIndex = function _inputIndex(hash, index) {
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
ex = this.inputs[i];
|
||||
if (ex.out.hash === hash && ex.out.index === index)
|
||||
if (ex.prevout.hash === hash && ex.prevout.index === index)
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -176,14 +198,14 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
||||
assert(input);
|
||||
|
||||
// We should have previous outputs by now.
|
||||
assert(input.out.tx);
|
||||
assert(input.prevout.tx);
|
||||
|
||||
// Already has a script template (at least)
|
||||
if (input.script.length)
|
||||
return;
|
||||
|
||||
// Get the previous output's subscript
|
||||
s = input.out.tx.getSubscript(input.out.index);
|
||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
||||
|
||||
// P2SH
|
||||
if (bcoin.script.isScripthash(s)) {
|
||||
@ -236,7 +258,7 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
||||
}
|
||||
};
|
||||
|
||||
TX.prototype.signature = function signature(index, key, type) {
|
||||
TX.prototype.createSignature = function createSignature(index, key, type) {
|
||||
var input, s, hash, signature;
|
||||
|
||||
if (typeof index !== 'number')
|
||||
@ -253,10 +275,10 @@ TX.prototype.signature = function signature(index, key, type) {
|
||||
assert(input);
|
||||
|
||||
// We should have previous outputs by now.
|
||||
assert(input.out.tx);
|
||||
assert(input.prevout.tx);
|
||||
|
||||
// Get the previous output's subscript
|
||||
s = input.out.tx.getSubscript(input.out.index);
|
||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
||||
|
||||
// We need to grab the redeem script when
|
||||
// signing p2sh transactions.
|
||||
@ -278,6 +300,9 @@ TX.prototype.signature = function signature(index, key, type) {
|
||||
return signature;
|
||||
};
|
||||
|
||||
// Legacy
|
||||
TX.prototype.signature = TX.prototype.createSignature;
|
||||
|
||||
// Sign the now-built scriptSigs
|
||||
TX.prototype.signInput = function signInput(index, key, type) {
|
||||
var input, s, hash, signature;
|
||||
@ -291,13 +316,13 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
assert(input);
|
||||
|
||||
// We should have previous outputs by now.
|
||||
assert(input.out.tx);
|
||||
assert(input.prevout.tx);
|
||||
|
||||
// Create our signature.
|
||||
signature = this.signature(index, key, type);
|
||||
signature = this.createSignature(index, key, type);
|
||||
|
||||
// Get the previous output's subscript
|
||||
s = input.out.tx.getSubscript(input.out.index);
|
||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
||||
|
||||
// Script length, needed for multisig
|
||||
len = input.script.length;
|
||||
@ -484,7 +509,7 @@ TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) {
|
||||
return input.script;
|
||||
};
|
||||
|
||||
TX.prototype.output = function output(obj, value) {
|
||||
TX.prototype.addOutput = function addOutput(obj, value) {
|
||||
var options, output;
|
||||
|
||||
if (obj instanceof bcoin.wallet)
|
||||
@ -512,7 +537,8 @@ TX.prototype.output = function output(obj, value) {
|
||||
return this;
|
||||
};
|
||||
|
||||
TX.prototype.out = TX.prototype.output;
|
||||
TX.prototype.out = TX.prototype.addOutput;
|
||||
TX.prototype.output = TX.prototype.addOutput;
|
||||
|
||||
TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
var output, script, keys, m, n, hash, flags;
|
||||
@ -618,9 +644,9 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
// P2SH Transaction
|
||||
// hash160 [hash] eq
|
||||
if (options.scripthash) {
|
||||
if (options.lock != null) {
|
||||
if (options.lockTime != null) {
|
||||
script = [
|
||||
bcoin.script.array(options.lock),
|
||||
bcoin.script.array(options.lockTime),
|
||||
'checklocktimeverify',
|
||||
'drop',
|
||||
'codeseparator'
|
||||
@ -648,7 +674,7 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
|
||||
|
||||
if (!Array.isArray(s)) {
|
||||
type = s;
|
||||
s = this.inputs[index].out.tx.getSubscript(this.inputs[index].out.index);
|
||||
s = this.inputs[index].prevout.tx.getSubscript(this.inputs[index].prevout.index);
|
||||
if (bcoin.script.isScripthash(s)) {
|
||||
s = this.inputs[index].script[this.inputs[index.script.length - 1]];
|
||||
s = bcoin.script.getSubscript(bcoin.script.decode(s));
|
||||
@ -687,7 +713,7 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
|
||||
// Allow input sequence updates for other inputs.
|
||||
for (i = 0; i < copy.inputs.length; i++) {
|
||||
if (i !== index)
|
||||
copy.inputs[i].seq = 0;
|
||||
copy.inputs[i].sequence = 0;
|
||||
}
|
||||
} else if ((type & 0x1f) === constants.hashType.single) {
|
||||
// Bitcoind used to return 1 as an error code:
|
||||
@ -709,7 +735,7 @@ TX.prototype.signatureHash = function signatureHash(index, s, type) {
|
||||
// Allow input sequence updates for other inputs.
|
||||
for (i = 0; i < copy.inputs.length; i++) {
|
||||
if (i !== index)
|
||||
copy.inputs[i].seq = 0;
|
||||
copy.inputs[i].sequence = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -761,15 +787,15 @@ TX.prototype.verify = function verify(index, force, flags) {
|
||||
if (index != null && index !== i)
|
||||
return true;
|
||||
|
||||
if (!input.out.tx)
|
||||
if (!input.prevout.tx)
|
||||
return false;
|
||||
|
||||
// Somethis is very wrong if this is
|
||||
// not the case.
|
||||
assert.equal(input.out.tx.hash('hex'), input.out.hash);
|
||||
assert.equal(input.prevout.tx.hash('hex'), input.prevout.hash);
|
||||
|
||||
// Grab the previous output.
|
||||
output = input.out.tx.outputs[input.out.index];
|
||||
output = input.prevout.tx.outputs[input.prevout.index];
|
||||
|
||||
// Transaction is referencing an output
|
||||
// that does not exist.
|
||||
@ -777,7 +803,7 @@ TX.prototype.verify = function verify(index, force, flags) {
|
||||
return false;
|
||||
|
||||
// Transaction cannot reference itself.
|
||||
if (input.out.hash === this.hash('hex'))
|
||||
if (input.prevout.hash === this.hash('hex'))
|
||||
return false;
|
||||
|
||||
return bcoin.script.verify(input.script, output.script, this, i, flags);
|
||||
@ -785,7 +811,7 @@ TX.prototype.verify = function verify(index, force, flags) {
|
||||
};
|
||||
|
||||
TX.prototype.isCoinbase = function isCoinbase() {
|
||||
return this.inputs.length === 1 && +this.inputs[0].out.hash === 0;
|
||||
return this.inputs.length === 1 && +this.inputs[0].prevout.hash === 0;
|
||||
};
|
||||
|
||||
TX.prototype.maxSize = function maxSize() {
|
||||
@ -804,7 +830,7 @@ TX.prototype.maxSize = function maxSize() {
|
||||
size = 0;
|
||||
|
||||
// Get the previous output's subscript
|
||||
s = input.out.tx.getSubscript(input.out.index);
|
||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
||||
|
||||
// If we have access to the redeem script,
|
||||
// we can use it to calculate size much easier.
|
||||
@ -888,9 +914,9 @@ TX.prototype.maxSize = function maxSize() {
|
||||
return total;
|
||||
};
|
||||
|
||||
TX.prototype.getUnspent = function getUnspent(unspent, address, fee) {
|
||||
TX.prototype.getInputs = function getInputs(unspent, address, fee) {
|
||||
var tx = this.clone();
|
||||
var cost = tx.funds('out');
|
||||
var cost = tx.getFunds('output');
|
||||
var totalkb = 1;
|
||||
var total = cost.addn(constants.tx.fee);
|
||||
var inputs = [];
|
||||
@ -906,10 +932,10 @@ TX.prototype.getUnspent = function getUnspent(unspent, address, fee) {
|
||||
// Add new inputs until TX will have enough
|
||||
// funds to cover both minimum post cost
|
||||
// and fee.
|
||||
var index = tx._input(unspent);
|
||||
var index = tx._addInput(unspent);
|
||||
inputs.push(tx.inputs[index]);
|
||||
lastAdded++;
|
||||
return tx.funds('in').cmp(total) < 0;
|
||||
return tx.getFunds('input').cmp(total) < 0;
|
||||
}
|
||||
|
||||
// Transfer `total` funds maximum.
|
||||
@ -918,7 +944,7 @@ TX.prototype.getUnspent = function getUnspent(unspent, address, fee) {
|
||||
if (!fee) {
|
||||
// Add dummy output (for `change`) to
|
||||
// calculate maximum TX size.
|
||||
tx.output({
|
||||
tx.addOutput({
|
||||
address: address,
|
||||
value: new bn(0)
|
||||
});
|
||||
@ -931,7 +957,7 @@ TX.prototype.getUnspent = function getUnspent(unspent, address, fee) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// total = tx.funds('out');
|
||||
// total = tx.getFunds('output');
|
||||
// }
|
||||
|
||||
// Change fee value if it is more than 1024
|
||||
@ -945,17 +971,17 @@ TX.prototype.getUnspent = function getUnspent(unspent, address, fee) {
|
||||
totalkb += newkb;
|
||||
|
||||
// Failed to get enough funds, add more inputs.
|
||||
if (tx.funds('in').cmp(total) < 0)
|
||||
if (tx.getFunds('input').cmp(total) < 0)
|
||||
unspent.slice(lastAdded).every(addInput);
|
||||
} while (tx.funds('in').cmp(total) < 0 && lastAdded < unspent.length);
|
||||
} while (tx.getFunds('input').cmp(total) < 0 && lastAdded < unspent.length);
|
||||
}
|
||||
|
||||
if (tx.funds('in').cmp(total) < 0) {
|
||||
if (tx.getFunds('input').cmp(total) < 0) {
|
||||
// Still failing to get enough funds.
|
||||
inputs = null;
|
||||
} else {
|
||||
// How much money is left after filling outputs.
|
||||
change = tx.funds('in').sub(total);
|
||||
change = tx.getFunds('input').sub(total);
|
||||
}
|
||||
|
||||
// Return necessary inputs and change.
|
||||
@ -969,7 +995,7 @@ TX.prototype.getUnspent = function getUnspent(unspent, address, fee) {
|
||||
};
|
||||
};
|
||||
|
||||
TX.prototype.fillUnspent = function fillUnspent(unspent, address, fee) {
|
||||
TX.prototype.fill = function fill(unspent, address, fee) {
|
||||
var result;
|
||||
|
||||
if (unspent)
|
||||
@ -983,13 +1009,15 @@ TX.prototype.fillUnspent = function fillUnspent(unspent, address, fee) {
|
||||
|
||||
assert(this.changeAddress);
|
||||
|
||||
result = this.getUnspent(this.unspent, this.changeAddress, this.hardFee);
|
||||
result = this.getInputs(this.unspent, this.changeAddress, this.hardFee);
|
||||
|
||||
this.total = result.total;
|
||||
|
||||
if (!result.inputs)
|
||||
return result;
|
||||
|
||||
result.inputs.forEach(function(input) {
|
||||
this.input(input);
|
||||
this.addInput(input);
|
||||
}, this);
|
||||
|
||||
if (result.change.cmpn(constants.tx.dust) < 0) {
|
||||
@ -1000,7 +1028,7 @@ TX.prototype.fillUnspent = function fillUnspent(unspent, address, fee) {
|
||||
);
|
||||
this.changeIndex = -1;
|
||||
} else {
|
||||
this.output({
|
||||
this.addOutput({
|
||||
address: this.changeAddress,
|
||||
value: result.change
|
||||
});
|
||||
@ -1011,6 +1039,10 @@ TX.prototype.fillUnspent = function fillUnspent(unspent, address, fee) {
|
||||
return result;
|
||||
};
|
||||
|
||||
// Legacy
|
||||
TX.prototype.fillUnspent = TX.prototype.fill;
|
||||
TX.prototype.fillInputs = TX.prototype.fill;
|
||||
|
||||
TX.prototype._recalculateFee = function recalculateFee() {
|
||||
var output = this.outputs[this.changeIndex];
|
||||
var size, real, fee;
|
||||
@ -1019,7 +1051,7 @@ TX.prototype._recalculateFee = function recalculateFee() {
|
||||
return;
|
||||
|
||||
if (!output) {
|
||||
this.output({
|
||||
this.addOutput({
|
||||
address: this.changeAddress,
|
||||
value: new bn(0)
|
||||
});
|
||||
@ -1060,26 +1092,26 @@ TX.prototype._recalculateFee = function recalculateFee() {
|
||||
};
|
||||
|
||||
TX.prototype.getFee = function getFee() {
|
||||
if (this.funds('in').cmp(this.funds('out')) < 0)
|
||||
if (this.getFunds('input').cmp(this.getFunds('output')) < 0)
|
||||
return new bn(0);
|
||||
|
||||
return this.funds('in').sub(this.funds('out'));
|
||||
return this.getFunds('input').sub(this.getFunds('output'));
|
||||
};
|
||||
|
||||
TX.prototype.funds = function funds(side) {
|
||||
TX.prototype.getFunds = function getFunds(side) {
|
||||
var acc = new bn(0);
|
||||
var inputs;
|
||||
|
||||
if (side === 'in') {
|
||||
if (side === 'in' || side === 'input') {
|
||||
inputs = this.inputs.filter(function(input) {
|
||||
return input.out.tx;
|
||||
return input.prevout.tx;
|
||||
});
|
||||
|
||||
if (inputs.length === 0)
|
||||
return acc;
|
||||
|
||||
inputs.reduce(function(acc, input) {
|
||||
return acc.iadd(input.out.tx.outputs[input.out.index].value);
|
||||
return acc.iadd(input.prevout.tx.outputs[input.prevout.index].value);
|
||||
}, acc);
|
||||
|
||||
return acc;
|
||||
@ -1096,25 +1128,28 @@ TX.prototype.funds = function funds(side) {
|
||||
return acc;
|
||||
};
|
||||
|
||||
TX.prototype._avoidFeeSnipping = function _avoidFeeSnipping() {
|
||||
// Legacy
|
||||
TX.prototype.funds = TX.prototype.getFunds;
|
||||
|
||||
TX.prototype.avoidFeeSnipping = function avoidFeeSnipping() {
|
||||
if (!this.chain)
|
||||
return;
|
||||
|
||||
this.lock = this.chain.height();
|
||||
this.lockTime = this.chain.height();
|
||||
|
||||
if ((Math.random() * 10 | 0) === 0)
|
||||
this.lock = Math.max(0, this.lock - (Math.random() * 100 | 0));
|
||||
this.lockTime = Math.max(0, this.lockTime - (Math.random() * 100 | 0));
|
||||
};
|
||||
|
||||
TX.prototype.setLockTime = function setLockTime(lock) {
|
||||
TX.prototype.setLockTime = function setLockTime(lockTime) {
|
||||
var i, input;
|
||||
|
||||
this.lock = lock;
|
||||
this.lockTime = lockTime;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
if (input.seq === 0xffffffff)
|
||||
input.seq = 0;
|
||||
if (input.sequence === 0xffffffff)
|
||||
input.sequence = 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1122,11 +1157,11 @@ TX.prototype.increaseFee = function increaseFee(fee) {
|
||||
var i, input;
|
||||
|
||||
this.hardFee = fee || this.getFee().add(new bn(10000));
|
||||
this.fillUnspent();
|
||||
this.fill();
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
input.seq = 0xffffffff - 1;
|
||||
input.sequence = 0xffffffff - 1;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1134,11 +1169,11 @@ TX.prototype.isFull = function isFull() {
|
||||
if (this.inputs.length === 0)
|
||||
return false;
|
||||
return this.inputs.every(function(input) {
|
||||
return !!input.out.tx;
|
||||
return !!input.prevout.tx;
|
||||
});
|
||||
};
|
||||
|
||||
TX.prototype.fill = function fill(txs) {
|
||||
TX.prototype.fillPrevout = function fillPrevout(txs) {
|
||||
var inputs;
|
||||
|
||||
if (txs instanceof bcoin.txPool)
|
||||
@ -1154,9 +1189,9 @@ TX.prototype.fill = function fill(txs) {
|
||||
}
|
||||
|
||||
inputs = this.inputs.filter(function(input) {
|
||||
if (!input.out.tx && txs[input.out.hash])
|
||||
input.out.tx = txs[input.out.hash];
|
||||
return !!input.out.tx;
|
||||
if (!input.prevout.tx && txs[input.prevout.hash])
|
||||
input.prevout.tx = txs[input.prevout.hash];
|
||||
return !!input.prevout.tx;
|
||||
}, this);
|
||||
|
||||
return inputs.length === this.inputs.length;
|
||||
@ -1206,14 +1241,14 @@ TX.prototype.isFinal = function isFinal(height, ts) {
|
||||
if (!this.chain)
|
||||
return true;
|
||||
|
||||
if (this.lock === 0)
|
||||
if (this.lockTime === 0)
|
||||
return true;
|
||||
|
||||
if (this.lock < (this.lock < threshold ? height : ts))
|
||||
if (this.lockTime < (this.lockTime < threshold ? height : ts))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
if (this.inputs[i].seq !== 0xffffffff)
|
||||
if (this.inputs[i].sequence !== 0xffffffff)
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1290,10 +1325,10 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
|
||||
if (!input.out.tx)
|
||||
if (!input.prevout.tx)
|
||||
return false;
|
||||
|
||||
prev = input.out.tx.outputs[input.out.index];
|
||||
prev = input.prevout.tx.outputs[input.prevout.index];
|
||||
|
||||
if (!prev)
|
||||
return false;
|
||||
@ -1347,11 +1382,11 @@ TX.prototype.getPriority = function getPriority() {
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
|
||||
if (!input.out.tx)
|
||||
if (!input.prevout.tx)
|
||||
return constants.tx.freeThreshold.clone();
|
||||
|
||||
output = input.out.tx.outputs[input.out.index];
|
||||
age = input.out.tx.getConfirmations();
|
||||
output = input.prevout.tx.outputs[input.prevout.index];
|
||||
age = input.prevout.tx.getConfirmations();
|
||||
|
||||
if (age === -1)
|
||||
age = 0;
|
||||
@ -1399,7 +1434,7 @@ TX.prototype.getConfirmations = function getConfirmations() {
|
||||
};
|
||||
|
||||
TX.prototype.getValue = function getValue() {
|
||||
return this.funds('out');
|
||||
return this.getFunds('output');
|
||||
};
|
||||
|
||||
TX.prototype.__defineGetter__('chain', function() {
|
||||
|
||||
@ -148,7 +148,7 @@ Wallet.prototype._init = function init() {
|
||||
|
||||
// Notify owners about new accepted transactions
|
||||
this.tx.on('update', function(lastTs, tx) {
|
||||
var b = this.balance();
|
||||
var b = this.getBalance();
|
||||
if (prevBalance && prevBalance.cmp(b) !== 0)
|
||||
self.emit('balance', b);
|
||||
self.emit('update', tx);
|
||||
@ -453,8 +453,8 @@ Wallet.prototype.ownInput = function ownInput(tx, index) {
|
||||
var inputs = tx.inputs.filter(function(input, i) {
|
||||
var s;
|
||||
|
||||
if (!input.out.tx && this.tx._all[input.out.hash])
|
||||
input.out.tx = this.tx._all[input.out.hash];
|
||||
if (!input.prevout.tx && this.tx._all[input.prevout.hash])
|
||||
input.prevout.tx = this.tx._all[input.prevout.hash];
|
||||
|
||||
if (index != null && index !== i)
|
||||
return false;
|
||||
@ -473,10 +473,10 @@ Wallet.prototype.ownInput = function ownInput(tx, index) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!input.out.tx)
|
||||
if (!input.prevout.tx)
|
||||
return false;
|
||||
|
||||
s = input.out.tx.getSubscript(input.out.index);
|
||||
s = input.prevout.tx.getSubscript(input.prevout.index);
|
||||
|
||||
if (bcoin.script.isPubkey(s, key))
|
||||
return true;
|
||||
@ -501,27 +501,41 @@ Wallet.prototype.ownInput = function ownInput(tx, index) {
|
||||
return inputs;
|
||||
};
|
||||
|
||||
Wallet.prototype.fillUnspent = function fillUnspent(tx, address, fee) {
|
||||
Wallet.prototype.fill = function fill(tx, address, fee) {
|
||||
var result;
|
||||
|
||||
if (!address)
|
||||
address = this.changeAddress || this.getAddress();
|
||||
|
||||
return tx.fillUnspent(this.unspent(), address, fee);
|
||||
result = tx.fill(this.getUnspent(), address, fee);
|
||||
|
||||
if (!result.inputs)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
Wallet.prototype.fillTX = function fillTX(tx) {
|
||||
return tx.fill(this);
|
||||
// Legacy
|
||||
Wallet.prototype.fillUnspent = Wallet.prototype.fill;
|
||||
Wallet.prototype.fillInputs = Wallet.prototype.fill;
|
||||
|
||||
Wallet.prototype.fillPrevout = function fillPrevout(tx) {
|
||||
return tx.fillPrevout(this);
|
||||
};
|
||||
|
||||
// Legacy
|
||||
Wallet.prototype.fillTX = Wallet.prototype.fillPrevout;
|
||||
|
||||
Wallet.prototype.scriptInputs = function scriptInputs(tx) {
|
||||
var pub = this.getPublicKey();
|
||||
var redeem = this.getScript();
|
||||
var inputs = tx.inputs;
|
||||
|
||||
inputs = inputs.filter(function(input, i) {
|
||||
if (!input.out.tx && this.tx._all[input.out.hash])
|
||||
input.out.tx = this.tx._all[input.out.hash];
|
||||
if (!input.prevout.tx && this.tx._all[input.prevout.hash])
|
||||
input.prevout.tx = this.tx._all[input.prevout.hash];
|
||||
|
||||
if (!input.out.tx || !this.ownOutput(input.out.tx))
|
||||
if (!input.prevout.tx || !this.ownOutput(input.prevout.tx))
|
||||
return false;
|
||||
|
||||
tx.scriptInput(i, pub, redeem);
|
||||
@ -537,10 +551,10 @@ Wallet.prototype.signInputs = function signInputs(tx, type) {
|
||||
var inputs = tx.inputs;
|
||||
|
||||
inputs = inputs.filter(function(input, i) {
|
||||
if (!input.out.tx && this.tx._all[input.out.hash])
|
||||
input.out.tx = this.tx._all[input.out.hash];
|
||||
if (!input.prevout.tx && this.tx._all[input.prevout.hash])
|
||||
input.prevout.tx = this.tx._all[input.prevout.hash];
|
||||
|
||||
if (!input.out.tx || !this.ownOutput(input.out.tx))
|
||||
if (!input.prevout.tx || !this.ownOutput(input.prevout.tx))
|
||||
return false;
|
||||
|
||||
tx.signInput(i, key, type);
|
||||
@ -559,11 +573,11 @@ Wallet.prototype.sign = function sign(tx, type) {
|
||||
|
||||
// Add signature script to each input
|
||||
inputs = inputs.filter(function(input, i) {
|
||||
if (!input.out.tx && this.tx._all[input.out.hash])
|
||||
input.out.tx = this.tx._all[input.out.hash];
|
||||
if (!input.prevout.tx && this.tx._all[input.prevout.hash])
|
||||
input.prevout.tx = this.tx._all[input.prevout.hash];
|
||||
|
||||
// Filter inputs that this wallet own
|
||||
if (!input.out.tx || !this.ownOutput(input.out.tx))
|
||||
if (!input.prevout.tx || !this.ownOutput(input.prevout.tx))
|
||||
return false;
|
||||
|
||||
tx.scriptSig(i, key, pub, redeem, type);
|
||||
@ -578,28 +592,27 @@ Wallet.prototype.addTX = function addTX(tx, block) {
|
||||
return this.tx.add(tx);
|
||||
};
|
||||
|
||||
Wallet.prototype.all = function all() {
|
||||
return this.tx.all();
|
||||
Wallet.prototype.getAll = function getAll() {
|
||||
return this.tx.getAll();
|
||||
};
|
||||
|
||||
Wallet.prototype.unspent = function unspent() {
|
||||
return this.tx.unspent();
|
||||
Wallet.prototype.getUnspent = function getUnspent() {
|
||||
return this.tx.getUnspent();
|
||||
};
|
||||
|
||||
Wallet.prototype.pending = function pending() {
|
||||
return this.tx.pending();
|
||||
Wallet.prototype.getPending = function getPending() {
|
||||
return this.tx.getPending();
|
||||
};
|
||||
|
||||
Wallet.prototype.balance = function balance() {
|
||||
return this.tx.balance();
|
||||
Wallet.prototype.getBalance = function getBalance() {
|
||||
return this.tx.getBalance();
|
||||
};
|
||||
|
||||
Wallet.prototype.fill = function fill(tx, changeAddress, fee) {
|
||||
var result = this.fillUnspent(tx, changeAddress, fee);
|
||||
if (!result.inputs)
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
// Legacy
|
||||
Wallet.prototype.all = Wallet.prototype.getAll;
|
||||
Wallet.prototype.unspent = Wallet.prototype.getUnspent;
|
||||
Wallet.prototype.pending = Wallet.prototype.getPending;
|
||||
Wallet.prototype.balance = Wallet.prototype.getBalance;
|
||||
|
||||
Wallet.prototype.toAddress = function toAddress() {
|
||||
var self = this;
|
||||
@ -627,7 +640,7 @@ Wallet.prototype.toAddress = function toAddress() {
|
||||
hash: utils.toHex(this.getHash()),
|
||||
received: received,
|
||||
sent: sent,
|
||||
balance: this.balance(),
|
||||
balance: this.getBalance(),
|
||||
txs: txs
|
||||
};
|
||||
};
|
||||
@ -641,7 +654,7 @@ Wallet.prototype.toJSON = function toJSON(encrypt) {
|
||||
label: this.label,
|
||||
address: this.getKeyAddress(),
|
||||
scriptaddress: this.getScriptAddress(),
|
||||
balance: utils.toBTC(this.balance()),
|
||||
balance: utils.toBTC(this.getBalance()),
|
||||
pub: this.getPublicKey('hex'),
|
||||
priv: encrypt
|
||||
? encrypt(this.getPrivateKey('base58'))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user