diff --git a/lib/transactions/crypto.js b/lib/transactions/crypto.js index a005fc13b..ad0786837 100644 --- a/lib/transactions/crypto.js +++ b/lib/transactions/crypto.js @@ -40,7 +40,7 @@ var fixedPoint = Math.pow(10, 8); */ function getTransactionBytes (transaction) { - + /** * @method isSendTransaction * @return {object} @@ -172,18 +172,32 @@ function getTransactionBytes (transaction) { } /** - * @method isDappTransferTransaction + * @method isDappInTransferTransaction + * @return {object} + */ + + function isDappInTransferTransaction () { + var buf = Buffer.from(transaction.asset.inTransfer.dappId); + + return { + assetBytes: buf, + assetSize: buf.length + }; + } + + /** + * @method isDappOutTransferTransaction * @return {object} */ - function isDappTransferTransaction () { - var arrayBuf = new Buffer([]); - var dappBuffer = Buffer.from(transaction.asset.dapptransfer.dappid); - arrayBuf = Buffer.concat([arrayBuf, dappBuffer]); + function isDappOutTransferTransaction () { + var dappBuf = Buffer.from(transaction.asset.outTransfer.dappId); + var transactionBuf = Buffer.from(transaction.asset.outTransfer.transactionId); + var buf = Buffer.concat([dappBuf, transactionBuf]); return { - assetBytes: arrayBuf, - assetSize: arrayBuf.length + assetBytes: buf, + assetSize: buf.length }; } @@ -201,7 +215,8 @@ function getTransactionBytes (transaction) { '3': isVoteTransaction, '4': isMultisignatureTransaction, '5': isDappTransaction, - '6': isDappTransferTransaction + '6': isDappInTransferTransaction, + '7': isDappOutTransferTransaction, }; return transactionType[transaction.type](); @@ -282,7 +297,6 @@ function createTransactionBuffer (transaction, options) { transactionBuffer.writeByte(0); } } - transactionBuffer.writeLong(transaction.amount); if (assetSize > 0) { @@ -360,7 +374,8 @@ function getId (transaction) { */ function getHash (transaction) { - return crypto.createHash('sha256').update(getBytes(transaction)).digest(); + var bytes = getBytes(transaction); + return crypto.createHash('sha256').update(bytes).digest(); } /** diff --git a/lib/transactions/transfer.js b/lib/transactions/transfer.js index 4b1a3f2d2..67ba2ed3f 100644 --- a/lib/transactions/transfer.js +++ b/lib/transactions/transfer.js @@ -22,30 +22,31 @@ var constants = require('../constants.js'); var slots = require('../time/slots.js'); /** - * @method createTransfer + * @method createInTransfer + * @param dappId + * @param amount * @param secret * @param secondSecret - * @param dappId * @param timeOffset * * @return {Object} */ -function createTransfer (secret, secondSecret, dappId, timeOffset) { +function createInTransfer (dappId, amount, secret, secondSecret, timeOffset) { var now = new Date().getTime(); var time = timeOffset ? now - timeOffset : now; var keys = crypto.getKeys(secret); var transaction = { type: 6, - amount: 0, + amount: amount, fee: constants.fees.send, recipientId: null, senderPublicKey: keys.publicKey, timestamp: slots.getTime(time), asset: { - dapptransfer: { - dappid: dappId + inTransfer: { + dappId: dappId } } }; @@ -61,6 +62,50 @@ function createTransfer (secret, secondSecret, dappId, timeOffset) { return transaction; } +/** + * @method createOutTransfer + * @param dappId + * @param transactionId + * @param recipientId + * @param amount + * @param secret + * @param secondSecret + * @param timeOffset + * + * @return {Object} + */ + +function createOutTransfer (dappId, transactionId, recipientId, amount, secret, secondSecret, timeOffset) { + var now = new Date().getTime(); + var time = timeOffset ? now - timeOffset : now; + var keys = crypto.getKeys(secret); + + var transaction = { + type: 7, + amount: amount, + fee: constants.fees.send, + recipientId: recipientId, + senderPublicKey: keys.publicKey, + timestamp: slots.getTime(time), + asset: { + outTransfer: { + dappId: dappId, + transactionId: transactionId, + }, + }, + }; + + crypto.sign(transaction, keys); + + if (secondSecret) { + var secondKeys = crypto.getKeys(secondSecret); + crypto.secondSign(transaction, secondKeys); + } + + return transaction; +} + module.exports = { - createTransfer: createTransfer + createInTransfer: createInTransfer, + createOutTransfer: createOutTransfer }; diff --git a/test/transactions/transfer.js b/test/transactions/transfer.js index 17cb76d18..5fc7a752d 100644 --- a/test/transactions/transfer.js +++ b/test/transactions/transfer.js @@ -4,7 +4,6 @@ if (typeof module !== 'undefined' && module.exports) { var lisk = common.lisk; } describe('transfer.js', function () { - var transfer = lisk.transfer; it('should be ok', function () { @@ -16,42 +15,168 @@ describe('transfer.js', function () { }); it('should have properties', function () { - (transfer).should.have.property('createTransfer'); + (transfer).should.have.property('createInTransfer'); }); - describe('#createTransfer', function () { + describe('#createInTransfer', function () { + var createInTransfer = transfer.createInTransfer; + var dappId = '1234213'; + var amount = 10e8; + var secret = 'secret'; + var publicKey = '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + var secondSecret = 'secondSecret'; + var inTransferTransaction = createInTransfer(dappId, amount, secret, secondSecret); - var createTransfer = lisk.transfer.createTransfer; - var transferTransaction = createTransfer('secret', 'secondSecret', '1234213'); + it('should be a function', function () { + (createInTransfer).should.be.type('function'); + }); + + it('should create an in transfer dapp transaction', function () { + (inTransferTransaction).should.be.type('object'); + }); + + it('should create an in transfer dapp transaction type 6', function () { + (inTransferTransaction).should.have.property('type').be.equal(6); + }); + + it('should create an in transfer dapp transaction with dapp id in asset', function () { + (inTransferTransaction) + .should.have.property('asset') + .with.property('inTransfer') + .with.property('dappId') + .equal(dappId); + }); + + it('should create an in transfer dapp transaction with a provided amount', function () { + (inTransferTransaction).should.have.property('amount').equal(amount); + }); + + it('should create an in transfer dapp transaction with a default fee', function () { + (inTransferTransaction).should.have.property('fee').equal(0.1e8); + }); + + it('should create an in transfer dapp transaction with no recipient', function () { + (inTransferTransaction).should.have.property('recipientId').be.null(); + }); + + it('should create an in transfer dapp transaction with senderPublicKey', function () { + (inTransferTransaction).should.have.property('senderPublicKey').equal(publicKey); + }); + + it('should create an in transfer dapp transaction with first signature', function () { + (inTransferTransaction).should.have.property('signature').and.be.ok(); + }); + + it('should create an in transfer dapp transaction with second signature', function () { + (inTransferTransaction).should.have.property('signSignature').and.be.ok(); + }); + + it('should create an in transfer dapp transaction with just one signature', function () { + var inTransferTransactionOneSignature = createInTransfer(dappId, amount, secret); + (inTransferTransactionOneSignature).should.have.property('signature').and.be.ok(); + (inTransferTransactionOneSignature).should.not.have.property('secondSignature'); + }); + + it('should use time slots to get the time for the timestamp', function () { + var now = new Date(); + var clock = sinon.useFakeTimers(now, 'Date'); + var time = 36174862; + var stub = sinon.stub(slots, 'getTime').returns(time); + + var trs = createInTransfer(dappId, amount, secret); + + (trs).should.have.property('timestamp').and.be.equal(time); + (stub.calledWithExactly(now.getTime())).should.be.true(); + + stub.restore(); + clock.restore(); + }); + + it('should use time slots with an offset to get the time for the timestamp', function () { + var now = new Date(); + var clock = sinon.useFakeTimers(now, 'Date'); + var offset = 10e3; + var time = 36174862; + var stub = sinon.stub(slots, 'getTime').returns(time); + + var trs = createInTransfer(dappId, amount, secret, null, offset); + + (trs).should.have.property('timestamp').and.be.equal(time); + (stub.calledWithExactly(now.getTime() - offset)).should.be.true(); + + stub.restore(); + clock.restore(); + }); + + }); + + describe('#createOutTransfer', function () { + var createOutTransfer = transfer.createOutTransfer; + var dappId = '1234213'; + var transactionId = '9876567'; + var recipientId = '989234L'; + var amount = 10e8; + var secret = 'secret'; + var publicKey = '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + var secondSecret = 'secondSecret'; + var outTransferTransaction = createOutTransfer(dappId, transactionId, recipientId, amount, secret, secondSecret); it('should be a function', function () { - (createTransfer).should.be.type('function'); + (createOutTransfer).should.be.type('function'); + }); + + it('should create an out transfer dapp transaction', function () { + (outTransferTransaction).should.be.type('object'); + }); + + it('should create an out transfer dapp transaction type 7', function () { + (outTransferTransaction).should.have.property('type').equal(7); + }); + + it('should create an out transfer dapp transaction with dapp id in asset', function () { + (outTransferTransaction) + .should.have.property('asset') + .with.property('outTransfer') + .with.property('dappId') + .equal(dappId); + }); + + it('should create an out transfer dapp transaction with transaction id in asset', function () { + (outTransferTransaction) + .should.have.property('asset') + .with.property('outTransfer') + .with.property('transactionId') + .equal(transactionId); + }); + + it('should create an out transfer dapp transaction with a provided amount', function () { + (outTransferTransaction).should.have.property('amount').equal(amount); }); - it('should create a transfer dapp transaction', function () { - (transferTransaction).should.be.type('object'); + it('should create an out transfer dapp transaction with a default fee', function () { + (outTransferTransaction).should.have.property('fee').equal(0.1e8); }); - it('should create a transfer dapp transaction type 6', function () { - (transferTransaction.type).should.be.equal(6); + it('should create an out transfer dapp transaction with a provided recipient', function () { + (outTransferTransaction).should.have.property('recipientId').equal(recipientId); }); - it('should create a transfer dapp transaction with dapp id in asset', function () { - (transferTransaction.asset.dapptransfer.dappid).should.be.equal('1234213'); + it('should create an out transfer dapp transaction with senderPublicKey', function () { + (outTransferTransaction).should.have.property('senderPublicKey').equal(publicKey); }); - it('should create a transfer dapp transaction with first signature', function () { - (transferTransaction.signature).should.be.ok; + it('should create an out transfer dapp transaction with first signature', function () { + (outTransferTransaction).should.have.property('signature').be.ok(); }); - it('should create a transfer dapp transaction with second signature', function () { - (transferTransaction.signSignature).should.be.ok; + it('should create an out transfer dapp transaction with second signature', function () { + (outTransferTransaction).should.have.property('signSignature').be.ok(); }); - it('should create a transfer dapp transaction with just one signature', function () { - var transferTransactionOneSignature = createTransfer('secret', '', '1234213'); - (transferTransactionOneSignature.signature).should.be.ok; - expect(transferTransactionOneSignature.secondSignature).to.be.undefined; + it('should create an out transfer dapp transaction with just one signature', function () { + var outTransferTransactionOneSignature = createOutTransfer(dappId, transactionId, recipientId, amount, secret); + (outTransferTransactionOneSignature).should.have.property('signature').be.ok(); + (outTransferTransactionOneSignature).should.not.have.property('secondSignature'); }); it('should use time slots to get the time for the timestamp', function () { @@ -60,7 +185,7 @@ describe('transfer.js', function () { var time = 36174862; var stub = sinon.stub(slots, 'getTime').returns(time); - var trs = createTransfer('secret', null, '1234213'); + var trs = createOutTransfer(dappId, transactionId, recipientId, amount, secret); (trs).should.have.property('timestamp').and.be.equal(time); (stub.calledWithExactly(now.getTime())).should.be.true(); @@ -76,7 +201,7 @@ describe('transfer.js', function () { var time = 36174862; var stub = sinon.stub(slots, 'getTime').returns(time); - var trs = createTransfer('secret', null, '1234213', offset); + var trs = createOutTransfer(dappId, transactionId, recipientId, amount, secret, null, offset); (trs).should.have.property('timestamp').and.be.equal(time); (stub.calledWithExactly(now.getTime() - offset)).should.be.true();