1
0
mirror of https://github.com/bigchaindb/js-bigchaindb-driver.git synced 2025-02-14 21:10:32 +01:00

Issue #44 Multiple inputs for transfer transaction

This commit is contained in:
Rashad Ibrahimov 2017-09-19 23:47:33 +04:00 committed by tim
parent a8250d632c
commit e0f11ec415
5 changed files with 35 additions and 49 deletions

View File

@ -5,45 +5,41 @@ import makeTransaction from './makeTransaction'
/** /**
* @public * @public
* Generate a `TRANSFER` transaction holding the `asset`, `metadata`, and `outputs`, that fulfills * Generate a `TRANSFER` transaction holding the `asset`, `metadata`, and `outputs`, that fulfills
* the `fulfilledOutputs` of `unspentTransaction`. * the `fulfilledOutputs` of each `unspentTransaction`.
* @param {object} unspentTransaction Previous Transaction you have control over (i.e. can fulfill * @param {object[]} unspentOutputs Array of unspent Transactions' Outputs.
* its Output Condition) * Each item contains Transaction itself
* @param {object} metadata Metadata for the Transaction * and index of unspent Output for that Transaction.
* @param {object[]} outputs Array of Output objects to add to the Transaction. * @param {object[]} outputs Array of Output objects to add to the Transaction.
* Think of these as the recipients of the asset after the transaction. * Think of these as the recipients of the asset after the transaction.
* For `TRANSFER` Transactions, this should usually just be a list of * For `TRANSFER` Transactions, this should usually just be a list of
* Outputs wrapping Ed25519 Conditions generated from the public keys of * Outputs wrapping Ed25519 Conditions generated from the public keys of
* the recipients. * the recipients.
* @param {...number} OutputIndices Indices of the Outputs in `unspentTransaction` that this * @param {object} metadata Metadata for the Transaction - optional
* Transaction fulfills.
* Note that listed public keys listed must be used (and in
* the same order) to sign the Transaction
* (`signTransaction()`).
* @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before * @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before
* sending it off! * sending it off!
*/ */
// TODO:
// - Make `metadata` optional argument
export default function makeTransferTransaction( export default function makeTransferTransaction(
unspentTransaction, unspentOutputs,
metadata,
outputs, outputs,
...outputIndices metadata
) { ) {
const inputs = outputIndices.map((outputIndex) => { const inputs = unspentOutputs.map((unspentOutput) => {
const fulfilledOutput = unspentTransaction.outputs[outputIndex] const { tx, output_index } = unspentOutput
const fulfilledOutput = tx.outputs[output_index]
const transactionLink = { const transactionLink = {
'output_index': outputIndex, 'output_index': output_index,
'transaction_id': unspentTransaction.id, 'transaction_id': tx.id,
} }
return makeInputTemplate(fulfilledOutput.public_keys, transactionLink) return makeInputTemplate(fulfilledOutput.public_keys, transactionLink)
}) })
const assetLink = { const assetLink = {
'id': unspentTransaction.operation === 'CREATE' ? unspentTransaction.id 'id': unspentOutputs[0].tx.operation === 'CREATE' ? unspentOutputs[0].tx.id
: unspentTransaction.asset.id : unspentOutputs[0].tx.asset.id
} }
return makeTransaction('TRANSFER', assetLink, metadata, outputs, inputs) const meta = metadata || null
return makeTransaction('TRANSFER', assetLink, meta, outputs, inputs)
} }

View File

@ -17,10 +17,9 @@ export const createTx = Transaction.makeCreateTransaction(
alice.publicKey alice.publicKey
) )
export const transferTx = Transaction.makeTransferTransaction( export const transferTx = Transaction.makeTransferTransaction(
createTx, [{ tx: createTx, output_index: 0 }],
metaData,
[aliceOutput], [aliceOutput],
0 metaData
) )
export const bob = new Ed25519Keypair() export const bob = new Ed25519Keypair()

View File

@ -59,10 +59,9 @@ test('Valid TRANSFER transaction with single Ed25519 input', t => {
.then(({ id }) => conn.pollStatusAndFetchTransaction(id)) .then(({ id }) => conn.pollStatusAndFetchTransaction(id))
.then(() => { .then(() => {
const transferTx = Transaction.makeTransferTransaction( const transferTx = Transaction.makeTransferTransaction(
createTxSigned, [{ tx: createTxSigned, output_index: 0 }],
metaData,
[aliceOutput], [aliceOutput],
0 metaData
) )
const transferTxSigned = Transaction.signTransaction( const transferTxSigned = Transaction.signTransaction(
transferTx, transferTx,
@ -92,11 +91,9 @@ test('Valid TRANSFER transaction with multiple Ed25519 inputs', t => {
.then(({ 'id': txId }) => conn.pollStatusAndFetchTransaction(txId)) .then(({ 'id': txId }) => conn.pollStatusAndFetchTransaction(txId))
.then(() => { .then(() => {
const transferTx = Transaction.makeTransferTransaction( const transferTx = Transaction.makeTransferTransaction(
createTxSigned, [{ tx: createTxSigned, output_index: 0 }, { tx: createTxSigned, output_index: 1 }],
metaData,
[Transaction.makeOutput(aliceCondition, '2')], [Transaction.makeOutput(aliceCondition, '2')],
0, metaData
1
) )
const transferTxSigned = Transaction.signTransaction( const transferTxSigned = Transaction.signTransaction(
transferTx, transferTx,
@ -134,10 +131,9 @@ test('Search for spent and unspent outputs of a given public key', t => {
// We spent output 1 (of 0, 1) // We spent output 1 (of 0, 1)
const transferTx = Transaction.makeTransferTransaction( const transferTx = Transaction.makeTransferTransaction(
createTxSigned, [{ tx: createTxSigned, output_index: 1 }],
metaData,
[trentOutput], [trentOutput],
1 metaData
) )
const transferTxSigned = Transaction.signTransaction( const transferTxSigned = Transaction.signTransaction(
transferTx, transferTx,
@ -177,10 +173,9 @@ test('Search for unspent outputs for a given public key', t => {
// We spent output 1 (of 0, 1, 2) // We spent output 1 (of 0, 1, 2)
const transferTx = Transaction.makeTransferTransaction( const transferTx = Transaction.makeTransferTransaction(
createTxSigned, [{ tx: createTxSigned, output_index: 1 }],
metaData,
[trentOutput], [trentOutput],
1 metaData
) )
const transferTxSigned = Transaction.signTransaction( const transferTxSigned = Transaction.signTransaction(
transferTx, transferTx,
@ -220,10 +215,9 @@ test('Search for spent outputs for a given public key', t => {
// We spent output 1 (of 0, 1, 2) // We spent output 1 (of 0, 1, 2)
const transferTx = Transaction.makeTransferTransaction( const transferTx = Transaction.makeTransferTransaction(
createTxSigned, [{ tx: createTxSigned, output_index: 1 }],
metaData,
[trentOutput], [trentOutput],
1 metaData
) )
const transferTxSigned = Transaction.signTransaction( const transferTxSigned = Transaction.signTransaction(
transferTx, transferTx,

View File

@ -56,10 +56,9 @@ test('Fulfillment correctly formed', t => {
alice.publicKey alice.publicKey
) )
const txTransfer = Transaction.makeTransferTransaction( const txTransfer = Transaction.makeTransferTransaction(
txCreate, [{ tx: txCreate, output_index: 0 }],
{},
[Transaction.makeOutput(Transaction.makeEd25519Condition(alice.publicKey))], [Transaction.makeOutput(Transaction.makeEd25519Condition(alice.publicKey))],
[0] {}
) )
const msg = Transaction.serializeTransactionIntoCanonicalString(txTransfer) const msg = Transaction.serializeTransactionIntoCanonicalString(txTransfer)
const txSigned = Transaction.signTransaction(txTransfer, alice.privateKey) const txSigned = Transaction.signTransaction(txTransfer, alice.privateKey)

View File

@ -73,10 +73,9 @@ test('Create TRANSFER transaction based on CREATE transaction', t => {
sinon.spy(makeTransaction, 'default') sinon.spy(makeTransaction, 'default')
Transaction.makeTransferTransaction( Transaction.makeTransferTransaction(
createTx, [{ tx: createTx, output_index: 0 }],
metaData,
[aliceOutput], [aliceOutput],
0 metaData
) )
const expected = [ const expected = [
'TRANSFER', 'TRANSFER',
@ -101,10 +100,9 @@ test('Create TRANSFER transaction based on TRANSFER transaction', t => {
sinon.spy(makeTransaction, 'default') sinon.spy(makeTransaction, 'default')
Transaction.makeTransferTransaction( Transaction.makeTransferTransaction(
transferTx, [{ tx: transferTx, output_index: 0 }],
metaData,
[aliceOutput], [aliceOutput],
0 metaData
) )
const expected = [ const expected = [
'TRANSFER', 'TRANSFER',