1
0
mirror of https://github.com/bigchaindb/js-bigchaindb-driver.git synced 2024-11-22 01:36:56 +01:00

Merge pull request #125 from bigchaindb/transfer-multiple-inputs-rebase

Transfer multiple inputs rebase
This commit is contained in:
Manolo 2017-12-20 12:53:04 +01:00 committed by GitHub
commit 879ae68d0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 209 additions and 90 deletions

3
.gitignore vendored
View File

@ -19,5 +19,6 @@ coverage
coverage.lcov coverage.lcov
.nyc_output .nyc_output
yarn.lock yarn.lock
docs/build/
docs/_build/
docs/build/ docs/build/

View File

@ -16,8 +16,11 @@
| BigchainDB Server | BigchainDB JavaScript Driver | | BigchainDB Server | BigchainDB JavaScript Driver |
| ----------------- |------------------------------| | ----------------- |------------------------------|
| `0.10` | `0.1.x` | | `0.10` | `0.1.x` |
| `>= 1.0.0` | `0.3.x` | | `1.0.0` | `0.3.x` |
| `>= 1.3.0` | `3.x.x` |
## Breaking changes
Version 3.2 of BigchainDB JavaScript Driver introduces a new way of creating transfer transactions. Check [older versions](https://docs.bigchaindb.com/projects/js-driver/en/latest/readme.html#features)
## Contents ## Contents

BIN
docs/source/.conf.py.swp Normal file

Binary file not shown.

View File

@ -14,7 +14,7 @@ First, we create an asset registering the bicycle:
const txCreateAliceSimple = driver.Transaction.makeCreateTransaction( const txCreateAliceSimple = driver.Transaction.makeCreateTransaction(
{'asset': 'bicycle'}, {'asset': 'bicycle'},
{'purchase_price': '€240'}, {'purchase_price': '€240'},
[ [
driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(alice.publicKey)) driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(alice.publicKey))
], ],
alice.publicKey alice.publicKey
@ -29,10 +29,10 @@ So, Alice needs a crypto conditions that defines that she or her daughter can si
We need to define a threshold as well. This defines how many persons have to sign the transaction to ``TRANSFER`` it. We need to define a threshold as well. This defines how many persons have to sign the transaction to ``TRANSFER`` it.
In this case, we define two subconditions with the public keys from Alice and Carly. Next, we set the threshold to **one**. In this case, we define two subconditions with the public keys from Alice and Carly. Next, we set the threshold to **one**.
This means that just one of the subconditions has to sign the transaction to transfer it. This means that just one of the subconditions has to sign the transaction to transfer it.
This can be the mother Alice, or Carly herself. This can be the mother Alice, or Carly herself.
.. code-block:: js .. code-block:: js
// Create condition for Alice and Carly // Create condition for Alice and Carly
let subConditionFrom = driver.Transaction.makeEd25519Condition(alice.publicKey, false) let subConditionFrom = driver.Transaction.makeEd25519Condition(alice.publicKey, false)
let subConditionTo = driver.Transaction.makeEd25519Condition(carly.publicKey, false) let subConditionTo = driver.Transaction.makeEd25519Condition(carly.publicKey, false)
@ -47,11 +47,10 @@ This can be the mother Alice, or Carly herself.
output.public_keys = [carly.publicKey] output.public_keys = [carly.publicKey]
let transaction = driver.Transaction.makeTransferTransaction( let transaction = driver.Transaction.makeTransferTransaction(
txCreateAliceSimpleSigned, [{ tx: txCreateAliceSimpleSigned, output_index: 0 }],
{'meta': 'Transfer to new user with conditions'}, [output],
[output], {'meta': 'Transfer to new user with conditions'}
0 );
);
// Add alice as previous owner // Add alice as previous owner
transaction.inputs[0].owners_before = [alice.publicKey] transaction.inputs[0].owners_before = [alice.publicKey]

View File

@ -3,7 +3,7 @@ BigchainDB Javascript Driver Documentation
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
← Back to All BigchainDB Docs <https://bigchaindb.readthedocs.io/en/latest/index.html> ← Back to All BigchainDB Docs <https://bigchaindb.readthedocs.io/en/latest/index.html>
readme readme
quickstart quickstart

View File

@ -34,3 +34,49 @@ Compatibility Matrix
+-----------------------+----------------------------------+ +-----------------------+----------------------------------+
| ``1.0`` | ``0.3.x`` | | ``1.0`` | ``0.3.x`` |
+-----------------------+----------------------------------+ +-----------------------+----------------------------------+
| ``1.3`` | ``3.x.x`` |
+-----------------------+----------------------------------+
Older versions
--------------------
For versions below 3.2, a transfer transaction looked like:
.. code-block:: js
const createTranfer = BigchainDB.Transaction.makeTransferTransaction(
txCreated,
metadata, [BigchainDB.Transaction.makeOutput(
BigchainDB.Transaction.makeEd25519Condition(alice.publicKey))],
0
)
const signedTransfer = BigchainDB.Transaction.signTransaction(createTranfer, keypair.privateKey)
In order to upgrade and do it compatible with the new driver version, this transaction should be now:
.. code-block:: js
const createTranfer = BigchainDB.Transaction.makeTransferTransaction(
[{ tx: txCreated, output_index: 0 }],
[aliceOutput],
metaData
)
const signedTransfer = BigchainDB.Transaction.signTransaction(createTranfer, keypair.privateKey)
The upgrade allows to create transfer transaction spending outputs that belong to different transactions.
So for instance is now possible to create a transfer transaction spending two outputs from two different create transactions:
.. code-block:: js
const createTranfer = BigchainDB.Transaction.makeTransferTransaction(
[{ tx: txCreated1, output_index: 0 }, { tx: txCreated2, output_index: 0 }],
[aliceOutput],
metaData
)
const signedTransfer = BigchainDB.Transaction.signTransaction(createTranfer, keypair.privateKey)

View File

@ -173,22 +173,20 @@ First, let's prepare the transaction to be transferred.
.. code-block:: js .. code-block:: js
const txTransferBob = driver.Transaction.makeTransferTransaction( const txTransferBob = driver.Transaction.makeTransferTransaction(
// signedTx to transfer // signedTx to transfer and output index
txCreateAliceSimpleSigned, [{ tx: txCreateAliceSimpleSigned, output_index: 0 }],
// metadata
{price: '100 euro'},
[driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey))], [driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey))],
0
// metadata
{price: '100 euro'}
); );
The function ``makeTransferTransaction()`` needs following parameters: The function ``makeTransferTransaction()`` needs following parameters:
- Unspent transaction: Previous transaction you have control over (i.e. can fulfill its Output Condition) - Unspent outputs: Array of `unspent transactions outputs`. Each item contains `Transaction` itself and index of `unspent output` for that `Transaction`.
- Metadata for transaction (e.g. price of sold bike)
- Array of output objects to add to 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 outputs wrapping Ed25519 conditions generated from the public keys of the recipients. - Array of output objects to add to 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 outputs wrapping Ed25519 conditions generated from the public keys of the recipients.
- Indices of the outputs in `unspent transaction` that this transaction fulfills. - Metadata for transaction (e.g. price of sold bike)
Fulfill transaction by signing it with Alice's private key. Fulfill transaction by signing it with Alice's private key.
@ -377,12 +375,12 @@ Recap: Asset Creation & Transfer
// Transfer bicycle to Bob // Transfer bicycle to Bob
.then(() => { .then(() => {
const txTransferBob = driver.Transaction.makeTransferTransaction( const txTransferBob = driver.Transaction.makeTransferTransaction(
// signedTx to transfer // signedTx to transfer and output index
txCreateAliceSimpleSigned, [{ tx: txCreateAliceSimpleSigned, output_index: 0 }],
// metadata
{price: '100 euro'},
[driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey))], [driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey))],
0) // metadata
{price: '100 euro'}
)
// Sign with alice's private key // Sign with alice's private key
let txTransferBobSigned = driver.Transaction.signTransaction(txTransferBob, alice.privateKey) let txTransferBobSigned = driver.Transaction.signTransaction(txTransferBob, alice.privateKey)
@ -617,10 +615,10 @@ and further we transfer it from Bob to Chris. Expectations:
// Transfer bicycle from Alice to Bob // Transfer bicycle from Alice to Bob
.then(() => { .then(() => {
const txTransferBob = driver.Transaction.makeTransferTransaction( const txTransferBob = driver.Transaction.makeTransferTransaction(
txCreateAliceSimpleSigned, [{ tx: txCreateAliceSimpleSigned, output_index: 0 }],
{'newOwner': 'Bob'},
[driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey))], [driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey))],
0) {'newOwner': 'Bob'}
)
// Sign with alice's private key // Sign with alice's private key
txTransferBobSigned = driver.Transaction.signTransaction(txTransferBob, alice.privateKey) txTransferBobSigned = driver.Transaction.signTransaction(txTransferBob, alice.privateKey)
@ -634,10 +632,10 @@ and further we transfer it from Bob to Chris. Expectations:
// Second transfer of bicycle from Bob to Chris // Second transfer of bicycle from Bob to Chris
.then(tx => { .then(tx => {
const txTransferChris = driver.Transaction.makeTransferTransaction( const txTransferChris = driver.Transaction.makeTransferTransaction(
txTransferBobSigned, [{ tx: txTransferBobSigned, output_index: 0 }],
{'newOwner': 'Chris'},
[driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(chris.publicKey))], [driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(chris.publicKey))],
0) {'newOwner': 'Chris'}
)
// Sign with bob's private key // Sign with bob's private key
let txTransferChrisSigned = driver.Transaction.signTransaction(txTransferChris, bob.privateKey) let txTransferChrisSigned = driver.Transaction.signTransaction(txTransferChris, bob.privateKey)
@ -722,15 +720,16 @@ This gives us 4 tokens to transfer.
.. code-block:: js .. code-block:: js
const txTransferDivisible = driver.Transaction.makeTransferTransaction( const txTransferDivisible = driver.Transaction.makeTransferTransaction(
txCreateAliceDivisibleSigned, [{ tx: txCreateAliceDivisibleSigned, output_index: 0 }],
{
metaDataMessage: 'I am specific to this transfer transaction'
},
[ [
driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(carly.publicKey), '2'), driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(carly.publicKey), '2'),
driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey), '1'), driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(bob.publicKey), '1'),
driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(alice.publicKey), '1') driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(alice.publicKey), '1')
], 0); ],
{
metaDataMessage: 'I am specific to this transfer transaction'
}
);
To make the use of the last parameter of ``makeTransferTransaction()`` function more clear, we will do another transfer. To make the use of the last parameter of ``makeTransferTransaction()`` function more clear, we will do another transfer.
We will fulfill the first and second output of the create transaction (0, 1) because Carly and Bob decide to redistribute some money. We will fulfill the first and second output of the create transaction (0, 1) because Carly and Bob decide to redistribute some money.
@ -741,16 +740,16 @@ We will fulfill the first and second output of the create transaction (0, 1) bec
This gives us 3 tokens to redistribute. I want to give 1 token to Carly and 2 tokens Alice. This gives us 3 tokens to redistribute. I want to give 1 token to Carly and 2 tokens Alice.
.. code-block:: js .. code-block:: js
const txTransferDivisibleInputs = driver.Transaction.makeTransferTransaction( const txTransferDivisibleInputs = driver.Transaction.makeTransferTransaction(
txTransferDivisibleSigned, [{ tx: txTransferDivisibleSigned, output_index: 0 }, { tx: txTransferDivisibleSigned, output_index: 1 }],
{
metaDataMessage: 'I am specific to this transfer transaction'
},
[ [
driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(carly.publicKey), '1'), driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(carly.publicKey), '1'),
driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(alice.publicKey), '2') driver.Transaction.makeOutput(driver.Transaction.makeEd25519Condition(alice.publicKey), '2')
], 0, 1) ],
{
metaDataMessage: 'I am specific to this transfer transaction'
}
);
Because we want to fulfill two outputs (Carly and Bob), we have to sign the transfer transaction in the same order: Because we want to fulfill two outputs (Carly and Bob), we have to sign the transfer transaction in the same order:

View File

@ -5,45 +5,42 @@ 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 = unspentOutput.tx
const outputIndex = unspentOutput.output_index
const fulfilledOutput = tx.outputs[outputIndex]
const transactionLink = { const transactionLink = {
'output_index': outputIndex, 'output_index': outputIndex,
'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,
@ -110,6 +107,74 @@ test('Valid TRANSFER transaction with multiple Ed25519 inputs', t => {
}) })
test('Valid TRANSFER transaction with multiple Ed25519 inputs from different transactions', t => {
const conn = new Connection(API_PATH)
const carol = new Ed25519Keypair()
const carolCondition = Transaction.makeEd25519Condition(carol.publicKey)
const carolOutput = Transaction.makeOutput(carolCondition)
const trent = new Ed25519Keypair()
const trentCondition = Transaction.makeEd25519Condition(trent.publicKey)
const trentOutput = Transaction.makeOutput(trentCondition)
const eli = new Ed25519Keypair()
const eliCondition = Transaction.makeEd25519Condition(eli.publicKey)
const createTx = Transaction.makeCreateTransaction(
asset(),
metaData,
[aliceOutput, bobOutput],
alice.publicKey
)
const createTxSigned = Transaction.signTransaction(
createTx,
alice.privateKey
)
return conn.postTransaction(createTxSigned)
.then(({ 'id': txId }) => conn.pollStatusAndFetchTransaction(txId))
.then(() => {
const transferTx1 = Transaction.makeTransferTransaction(
[{ tx: createTxSigned, output_index: 0 }],
[carolOutput],
metaData
)
const transferTxSigned1 = Transaction.signTransaction(
transferTx1,
alice.privateKey
)
const transferTx2 = Transaction.makeTransferTransaction(
[{ tx: createTxSigned, output_index: 1 }],
[trentOutput],
metaData
)
const transferTxSigned2 = Transaction.signTransaction(
transferTx2,
bob.privateKey
)
return conn.postTransaction(transferTxSigned1)
.then(({ id }) => conn.pollStatusAndFetchTransaction(id))
.then(conn.postTransaction(transferTxSigned2))
.then(({ id }) => conn.pollStatusAndFetchTransaction(id))
.then(() => {
const transferTxMultipleInputs = Transaction.makeTransferTransaction(
[{ tx: transferTxSigned1, output_index: 0 },
{ tx: transferTxSigned2, output_index: 0 }],
[Transaction.makeOutput(eliCondition, '2')],
metaData
)
const transferTxSignedMultipleInputs = Transaction.signTransaction(
transferTxMultipleInputs,
carol.privateKey,
trent.privateKey
)
return conn.postTransaction(transferTxSignedMultipleInputs)
.then(({ id }) => conn.pollStatusAndFetchTransaction(id))
.then(resTx => t.truthy(resTx))
})
})
})
test('Search for spent and unspent outputs of a given public key', t => { test('Search for spent and unspent outputs of a given public key', t => {
const conn = new Connection(API_PATH) const conn = new Connection(API_PATH)
const carol = new Ed25519Keypair() const carol = new Ed25519Keypair()
@ -134,10 +199,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 +241,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 +283,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)
@ -69,6 +68,22 @@ test('Fulfillment correctly formed', t => {
}) })
test('CryptoConditions JSON load', t => {
const cond = Transaction.ccJsonLoad({
type: 'threshold-sha-256',
threshold: 1,
subconditions: [{
type: 'ed25519-sha-256',
public_key: 'a'
},
{
hash: 'a'
}],
})
t.truthy(cond.subconditions.length === 2)
})
test('CryptoConditions JSON load', t => { test('CryptoConditions JSON load', t => {
const cond = Transaction.ccJsonLoad({ const cond = Transaction.ccJsonLoad({
type: 'threshold-sha-256', type: 'threshold-sha-256',

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',