add locktime docs and Transaction#getLockTime
This commit is contained in:
parent
f8974b383a
commit
986264e181
|
@ -140,6 +140,26 @@ var multiSigTx = new Transaction(serialized)
|
||||||
assert(multiSigTx.isFullySigned());
|
assert(multiSigTx.isFullySigned());
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Time-Locking transaction
|
||||||
|
All bitcoin transactions contain a locktime field.
|
||||||
|
The locktime indicates the earliest time a transaction can be added to the blockchain.
|
||||||
|
Locktime allows signers to create time-locked transactions which will only become valid in the future, giving the signers a chance to change their minds.
|
||||||
|
Locktime can be set in the form of a bitcoin block height (the transaction can only be included in a block with a higher height than specified) or a linux timestamp (transaction can only be confirmed after that time).
|
||||||
|
For more information see [bitcoin's development guide section on locktime](https://bitcoin.org/en/developer-guide#locktime-and-sequence-number).
|
||||||
|
|
||||||
|
In bitcore, you can set a `Transaction`'s locktime by using the methods `Transaction#lockUntilDate` and `Transaction#lockUntilBlockHeight`. You can also get a friendly version of the locktime field via `Transaction#getLockTime`;
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```javascript
|
||||||
|
var future = new Date(2025,10,30); // Sun Nov 30 2025
|
||||||
|
var transaction = new Transaction()
|
||||||
|
.lockUntilDate(future);
|
||||||
|
console.log(transaction.getLockTime());
|
||||||
|
// output similar to: Sun Nov 30 2025 00:00:00 GMT-0300 (ART)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Upcoming changes
|
## Upcoming changes
|
||||||
|
|
||||||
We're debating an API for Merge Avoidance, CoinJoin, Smart contracts, CoinSwap, and Stealth Addresses. We're expecting to have all of them by some time in 2015. Payment channel creation is avaliable in the [bitcore-channel](https://github.com/bitpay/bitcore-channel) module.
|
We're debating an API for Merge Avoidance, CoinJoin, Smart contracts, CoinSwap, and Stealth Addresses. We're expecting to have all of them by some time in 2015. Payment channel creation is avaliable in the [bitcore-channel](https://github.com/bitpay/bitcore-channel) module.
|
||||||
|
|
|
@ -323,6 +323,23 @@ Transaction.prototype.lockUntilBlockHeight = function(height) {
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a semantic version of the transaction's nLockTime.
|
||||||
|
* @return {Number|Date}
|
||||||
|
* If nLockTime is 0, it returns null,
|
||||||
|
* if it is < 500000000, it returns a block height (number)
|
||||||
|
* else it returns a Date object.
|
||||||
|
*/
|
||||||
|
Transaction.prototype.getLockTime = function() {
|
||||||
|
if (!this.nLockTime) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (this.nLockTime < Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT) {
|
||||||
|
return this.nLockTime;
|
||||||
|
}
|
||||||
|
return new Date(1000*this.nLockTime);
|
||||||
|
};
|
||||||
|
|
||||||
Transaction.prototype.toJSON = function toJSON() {
|
Transaction.prototype.toJSON = function toJSON() {
|
||||||
return JSON.stringify(this.toObject());
|
return JSON.stringify(this.toObject());
|
||||||
};
|
};
|
||||||
|
|
|
@ -135,7 +135,7 @@ describe('Transaction', function() {
|
||||||
|
|
||||||
describe('adding inputs', function() {
|
describe('adding inputs', function() {
|
||||||
|
|
||||||
it('it only adds once one utxo', function() {
|
it('only adds once one utxo', function() {
|
||||||
var tx = new Transaction();
|
var tx = new Transaction();
|
||||||
tx.from(simpleUtxoWith1BTC);
|
tx.from(simpleUtxoWith1BTC);
|
||||||
tx.from(simpleUtxoWith1BTC);
|
tx.from(simpleUtxoWith1BTC);
|
||||||
|
@ -408,25 +408,35 @@ describe('Transaction', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setting the nLockTime', function() {
|
describe('handling the nLockTime', function() {
|
||||||
var MILLIS_IN_SECOND = 1000;
|
var MILLIS_IN_SECOND = 1000;
|
||||||
var timestamp = 1423504946;
|
var timestamp = 1423504946;
|
||||||
var blockHeight = 342734;
|
var blockHeight = 342734;
|
||||||
var date = new Date(timestamp * MILLIS_IN_SECOND);
|
var date = new Date(timestamp * MILLIS_IN_SECOND);
|
||||||
|
it('handles a simple example', function() {
|
||||||
|
var future = new Date(2025,10,30); // Sun Nov 30 2025
|
||||||
|
var transaction = new Transaction()
|
||||||
|
.lockUntilDate(future);
|
||||||
|
transaction.nLockTime.should.equal(future.getTime()/1000);
|
||||||
|
transaction.getLockTime().should.deep.equal(future);
|
||||||
|
});
|
||||||
it('accepts a date instance', function() {
|
it('accepts a date instance', function() {
|
||||||
var transaction = new Transaction()
|
var transaction = new Transaction()
|
||||||
.lockUntilDate(date);
|
.lockUntilDate(date);
|
||||||
transaction.nLockTime.should.equal(timestamp);
|
transaction.nLockTime.should.equal(timestamp);
|
||||||
|
transaction.getLockTime().should.deep.equal(date);
|
||||||
});
|
});
|
||||||
it('accepts a number instance with a timestamp', function() {
|
it('accepts a number instance with a timestamp', function() {
|
||||||
var transaction = new Transaction()
|
var transaction = new Transaction()
|
||||||
.lockUntilDate(timestamp);
|
.lockUntilDate(timestamp);
|
||||||
transaction.nLockTime.should.equal(timestamp);
|
transaction.nLockTime.should.equal(timestamp);
|
||||||
|
transaction.getLockTime().should.deep.equal(new Date(timestamp*1000));
|
||||||
});
|
});
|
||||||
it('accepts a block height', function() {
|
it('accepts a block height', function() {
|
||||||
var transaction = new Transaction()
|
var transaction = new Transaction()
|
||||||
.lockUntilBlockHeight(blockHeight);
|
.lockUntilBlockHeight(blockHeight);
|
||||||
transaction.nLockTime.should.equal(blockHeight);
|
transaction.nLockTime.should.equal(blockHeight);
|
||||||
|
transaction.getLockTime().should.deep.equal(blockHeight);
|
||||||
});
|
});
|
||||||
it('fails if the block height is too high', function() {
|
it('fails if the block height is too high', function() {
|
||||||
expect(function() {
|
expect(function() {
|
||||||
|
@ -441,7 +451,7 @@ describe('Transaction', function() {
|
||||||
return new Transaction().lockUntilDate(499999999);
|
return new Transaction().lockUntilDate(499999999);
|
||||||
}).to.throw(errors.Transaction.LockTimeTooEarly);
|
}).to.throw(errors.Transaction.LockTimeTooEarly);
|
||||||
});
|
});
|
||||||
it('fails if the date is negative', function() {
|
it('fails if the block height is negative', function() {
|
||||||
expect(function() {
|
expect(function() {
|
||||||
return new Transaction().lockUntilBlockHeight(-1);
|
return new Transaction().lockUntilBlockHeight(-1);
|
||||||
}).to.throw(errors.Transaction.NLockTimeOutOfRange);
|
}).to.throw(errors.Transaction.NLockTimeOutOfRange);
|
||||||
|
|
Loading…
Reference in New Issue