diff --git a/src/transaction.js b/src/transaction.js index 1e585a61d..58b3bb5b0 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -74,6 +74,7 @@ class Transaction { } if (appArgs !== undefined) { if (!Array.isArray(appArgs)) throw Error("appArgs must be an Array of Uint8Array."); + appArgs = appArgs.slice(); appArgs.forEach((arg) => { if (arg.constructor !== Uint8Array) throw Error("each element of AppArgs must be a Uint8Array."); }); @@ -81,16 +82,19 @@ class Transaction { appArgs = new Uint8Array(0); } if (appAccounts !== undefined) { - appAccounts.forEach((addressAsString, index) => { - appAccounts[index] = address.decodeAddress(addressAsString); - }) + if (!Array.isArray(appAccounts)) throw Error("appAccounts must be an Array of addresses."); + appAccounts = appAccounts.map(addressAsString => address.decodeAddress(addressAsString)); } if (appForeignApps !== undefined) { + if (!Array.isArray(appForeignApps)) throw Error("appForeignApps must be an Array of integers."); + appForeignApps = appForeignApps.slice(); appForeignApps.forEach((foreignAppIndex) => { if (!Number.isSafeInteger(foreignAppIndex) || foreignAppIndex < 0) throw Error("each foreign application index must be a positive number and smaller than 2^53-1"); }); } if (appForeignAssets !== undefined) { + if (!Array.isArray(appForeignAssets)) throw Error("appForeignAssets must be an Array of integers."); + appForeignAssets = appForeignAssets.slice(); appForeignAssets.forEach((foreignAssetIndex) => { if (!Number.isSafeInteger(foreignAssetIndex) || foreignAssetIndex < 0) throw Error("each foreign asset index must be a positive number and smaller than 2^53-1"); }); @@ -396,16 +400,10 @@ class Transaction { txn.apsu = Buffer.from(this.appClearProgram); } if (this.appArgs !== undefined) { - txn.apaa = []; - this.appArgs.forEach((arg) => { - txn.apaa.push(Buffer.from(arg)); - }); + txn.apaa = this.appArgs.map(arg => Buffer.from(arg)); } if (this.appAccounts !== undefined) { - txn.apat = []; - this.appAccounts.forEach((decodedAddress) => { - txn.apat.push(Buffer.from(decodedAddress.publicKey)); - }); + txn.apat = this.appAccounts.map(decodedAddress => Buffer.from(decodedAddress.publicKey)); } // allowed zero values if (!txn.note.length) delete txn.note; @@ -524,16 +522,10 @@ class Transaction { txn.appClearProgram = new Uint8Array(txnForEnc.apsu); } if (txnForEnc.apaa !== undefined) { - txn.appArgs = []; - txnForEnc.apaa.forEach((arg) => { - txn.appArgs.push(new Uint8Array(arg)); - }); + txn.appArgs = txnForEnc.apaa.map(arg => new Uint8Array(arg)); } if (txnForEnc.apat !== undefined) { - txn.appAccounts = []; - txnForEnc.apat.forEach((addressBytes) => { - txn.appAccounts.push(address.decodeAddress(address.encodeAddress(new Uint8Array(addressBytes)))); - }); + txn.appAccounts = txnForEnc.apat.map(addressBytes => address.decodeAddress(address.encodeAddress(new Uint8Array(addressBytes)))); } if (txnForEnc.apfa !== undefined) { txn.appForeignApps = txnForEnc.apfa; diff --git a/tests/5.Transaction.js b/tests/5.Transaction.js index 7615a8e12..bef2fad6d 100644 --- a/tests/5.Transaction.js +++ b/tests/5.Transaction.js @@ -5,6 +5,36 @@ const algosdk = require('../index'); const group = require('../src/group'); describe('Sign', function () { + it('should not modify input arrays', function () { + const appArgs = [Uint8Array.from([1, 2]), Uint8Array.from([3, 4])]; + const appAccounts = ["7ZUECA7HFLZTXENRV24SHLU4AVPUTMTTDUFUBNBD64C73F3UHRTHAIOF6Q", "UCE2U2JC4O4ZR6W763GUQCG57HQCDZEUJY4J5I6VYY4HQZUJDF7AKZO5GM"]; + const appForeignApps = [17, 200]; + const appForeignAssets = [7, 8, 9]; + const o = { + "from": "7ZUECA7HFLZTXENRV24SHLU4AVPUTMTTDUFUBNBD64C73F3UHRTHAIOF6Q", + "fee": 10, + "firstRound": 51, + "lastRound": 61, + "genesisHash": "JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=", + "note": new Uint8Array(0), + "type": "appl", + "appIndex": 5, + "appArgs": appArgs, + "appAccounts": appAccounts, + "appForeignApps": appForeignApps, + "appForeignAssets": appForeignAssets, + }; + const txn = new algosdk.Transaction(o); + assert.deepStrictEqual(appArgs, [Uint8Array.from([1, 2]), Uint8Array.from([3, 4])]); + assert.deepStrictEqual(appAccounts, ["7ZUECA7HFLZTXENRV24SHLU4AVPUTMTTDUFUBNBD64C73F3UHRTHAIOF6Q", "UCE2U2JC4O4ZR6W763GUQCG57HQCDZEUJY4J5I6VYY4HQZUJDF7AKZO5GM"]); + assert.deepStrictEqual(appForeignApps, [17, 200]); + assert.deepStrictEqual(appForeignAssets, [7, 8, 9]); + assert.ok(txn.appArgs !== appArgs); + assert.ok(txn.appAccounts !== appAccounts); + assert.ok(txn.appForeignApps !== appForeignApps); + assert.ok(txn.appForeignAssets !== appForeignAssets); + }); + it('should not complain on a missing note', function () { let o = { "from": "7ZUECA7HFLZTXENRV24SHLU4AVPUTMTTDUFUBNBD64C73F3UHRTHAIOF6Q",