add locktime docs and Transaction#getLockTime

This commit is contained in:
Manuel Araoz 2015-02-10 13:03:07 -03:00
parent f8974b383a
commit 986264e181
3 changed files with 50 additions and 3 deletions

View File

@ -140,6 +140,26 @@ var multiSigTx = new Transaction(serialized)
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
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.

View File

@ -323,6 +323,23 @@ Transaction.prototype.lockUntilBlockHeight = function(height) {
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() {
return JSON.stringify(this.toObject());
};

View File

@ -135,7 +135,7 @@ describe('Transaction', function() {
describe('adding inputs', function() {
it('it only adds once one utxo', function() {
it('only adds once one utxo', function() {
var tx = new Transaction();
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 timestamp = 1423504946;
var blockHeight = 342734;
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() {
var transaction = new Transaction()
.lockUntilDate(date);
transaction.nLockTime.should.equal(timestamp);
transaction.getLockTime().should.deep.equal(date);
});
it('accepts a number instance with a timestamp', function() {
var transaction = new Transaction()
.lockUntilDate(timestamp);
transaction.nLockTime.should.equal(timestamp);
transaction.getLockTime().should.deep.equal(new Date(timestamp*1000));
});
it('accepts a block height', function() {
var transaction = new Transaction()
.lockUntilBlockHeight(blockHeight);
transaction.nLockTime.should.equal(blockHeight);
transaction.getLockTime().should.deep.equal(blockHeight);
});
it('fails if the block height is too high', function() {
expect(function() {
@ -441,7 +451,7 @@ describe('Transaction', function() {
return new Transaction().lockUntilDate(499999999);
}).to.throw(errors.Transaction.LockTimeTooEarly);
});
it('fails if the date is negative', function() {
it('fails if the block height is negative', function() {
expect(function() {
return new Transaction().lockUntilBlockHeight(-1);
}).to.throw(errors.Transaction.NLockTimeOutOfRange);