When making a flash transaction, applyTransfer() results in NaNs being generated


When making a flash transaction, applyTransfer() results in NaNs being...
Author
Message
iotaNovice
i
Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)
Group: Forum Members
Posts: 3, Visits: 0
Hi Everyone!
I'm really new to Iota and specifically flash, so apologies if this is an obvious question!

I've been following the example in iota.flash.js under the examples folder, and want to modify this example to create an M of N multisig channel, where there will be three participants and only one signer.

I'm able to generate the signature for the signer, but once I call Helpers.createTransaction, I get an "undefined" error.

I poked around the code and it looks like the culprit is in multisigs.js. I get an error: invalid value transfer: The transaction does not require signatures.

I'm sending Iota from the signer (defined by oneFlash,) to one of the other two parties.

First, here is the error stack trace:
Error: Invalid value transfer: the transfer does not require a signature.
at Function.Multisig.initiateTransfer (C:\Users\munawar\syncoms\iota.flash.js\node_modules\iota.crypto.js\lib\multisig\multisig.js:253:25)
at Object.compose (C:\Users\munawar\syncoms\iota.flash.js\lib\transfer.js:133:23)
at Object.createTransaction (C:\Users\munawar\syncoms\iota.flash.js\examples\functions.js:44:24)
at sse (C:\Users\munawar\syncoms\iota.flash.js\examples\flash.js:222:25)
at proceed (C:\Users\munawar\syncoms\iota.flash.js\examples\flash.js:241:1)
at iota.api.sendTransfer (C:\Users\munawar\syncoms\iota.flash.js\examples\flash.js:26:3)
at C:\Users\munawar\syncoms\iota.flash.js\node_modules\iota.lib.js\lib\api\api.js:555:28
at makeRequest.prepareResult (C:\Users\munawar\syncoms\iota.flash.js\node_modules\iota.lib.js\lib\utils\makeRequest.js:190:12)
at exports.XMLHttpRequest.request.onreadystatechange (C:\Users\munawar\syncoms\iota.flash.js\node_modules\iota.lib.js\lib\utils\makeRequest.js:62:25)
at exports.XMLHttpRequest.dispatchEvent (C:\Users\munawar\syncoms\iota.flash.js\node_modules\xmlhttprequest\lib\XMLHttpRequest.js:591:25)


Next, here is my full code. Can someone please let me know if it's possible to do what I want to do (where only one signer is the authority, and whether or not I'm even doing this correctly?):


const IOTA = require("iota.lib.js");
require("isomorphic-fetch");

var iota = new IOTA({
//provider:
// Math.random() > 0.5
// ? "https://testnet.tangle.works:443"
// : "https://testnet2.tangle.works:443"
   provider: "http://p101.iotaledger.net:14700"
});
console.log(iota);
const fundChannel = async address => {
var transfers = [{ value: 2000, address:address }];

// Get your free seeeed
var response = await fetch("https://seeds.tangle.works/");
var wallet = await response.json();

return new Promise(function(resolve, reject) {
iota.api.sendTransfer(wallet.seed, 5, 9, transfers, (e, r) => {
if (e !== null) {
       console.log(e);
reject(e);
} else {
      console.log("Channel funded!");
      proceed();
resolve(r);
}
})
})
}

const IOTACrypto = require("iota.crypto.js")
const transfer = require("../lib/transfer")
const multisig = require("../lib/multisig")
var EventSource = require("eventsource");
const Helpers = require("./functions")
// Security level
const SECURITY = 1;
// Number of parties taking signing part in the channel
const SIGNERS_COUNT = 3;
// Flash tree depth
const TREE_DEPTH = 4;

var channels = [];
      channels["abc"] = {participants:[], userIndex: 0, deposits:[2000, 0, 0], balance:2000};
const platform = "def";
const platformSeed = "BGYFYVQSGZDRLJLTPOFCTPAMMU9TCPMSR9TTTAQLNXOUS9LEIHYNWKBUHSZMIWIYQH9PEMSNDPPHSSXEZ"
const platformSettlement = "AKTFFZCMUZVPX9VBHIBPSUKMJDLVNFGTW9ZYMHTXAEYIQBZEBDZUAONIKVKZBZPIVFOPRTYKITIIPPQHD";
var addresses = [];
addresses.push(platformSettlement);
addresses.push("JEYP9TTIQJVVBQZP9OZQQHNCUDWKGIUQQB9HOQYQTQPSYOSKFLTDGXOI9ICCIKSUXVHZ9BPL9EBXDHSTB");
addresses.push("SXD9NNQFKRS9XYKGYN9GYCUDSWMRHRYAEJVDHMEQRDSU9JPULOZFVPSB9VUZGVRUSE9GL9FFABJOESWD9");
      oneFlash = {
         userIndex: channels["abc"].userIndex,
         partialDigests:[],
         index: 0,
         bundles: [],
         settlementAddress: addresses[0],
         userSeed: platformSeed,
         flash: {
            signersCount: 3,
            balance: channels["abc"].balance,
            deposit: channels["abc"].deposits.slice(),
            settlementAddresses: addresses,
            remainderAddress: null,
            outputs: {},
            transfers: []
         }
      };
      // Create digests for the start of the channel
for (let i = 0; i < TREE_DEPTH + 1; i++) {
// Create new digest
const digest = multisig.getDigest(
platformSeed,
oneFlash.index,
SECURITY
);
// Increment key index
oneFlash.index++;
oneFlash.partialDigests.push(digest);
}

console.log("Initial digests generated!");
// INITAL MULTISIG

// Make an array of digests
let allDigests = []
allDigests[oneFlash.userIndex] = oneFlash.partialDigests;

// Generate the first addresses
var oneMultisigs = oneFlash.partialDigests.map((digest, index) => {
// Create address
let addy = multisig.composeAddress(
allDigests.map(userDigests => userDigests[index])
);
// Add key index in
addy.index = digest.index;
// Add the signing index to the object IMPORTANT
addy.signingIndex = oneFlash.userIndex * digest.security;
// Get the sum of all digest security to get address security sum
addy.securitySum = allDigests
.map(userDigests => userDigests[index])
.reduce((acc, v) => acc + v.security, 0)
// Add Security
addy.security = digest.security
return addy
})

console.log("Multisigs generated!");
var remainderAddress = oneMultisigs.shift();
      oneFlash.flash.remainderAddress = remainderAddress;
// Nest trees
for (let i = 1; i < oneMultisigs.length; i++) {
oneMultisigs[i - 1].children.push(oneMultisigs[i])
}
// Set Flash root
var root = oneMultisigs.shift();
var depositAddress = iota.utils.addChecksum(oneMultisigs[0].address);
oneFlash.flash.root = root;
oneFlash.flash.depositAddress = depositAddress;
console.log("Waiting for funding...");
fundChannel(depositAddress);
function proceed() {
   console.log("Resuming");
// Set digest/key index
var index = oneFlash.index = oneFlash.partialDigests.length;

console.log("Channel Setup!")
console.log(
"Transactable tokens: ",
oneFlash.flash.deposit.reduce((acc, v) => acc + v)
)


      twoFlash = {
         userIndex: channels["abc"].userIndex,
         index: 0,
         bundles: [],
         settlementAddress: addresses[channels["abc"].userIndex],
         flash: {
            signersCount: 3,
            balance: channels["abc"].balance,
            deposit: channels["abc"].deposits.slice(),
            settlementAddresses: addresses,
            remainderAddress: remainderAddress,
            root: root,
            depositAddress: depositAddress,
            outputs: {},
            transfers: []
         }
      };
channels["abc"].userIndex++;
      
            threeFlash = {
         userIndex: channels["abc"].userIndex,
         index: 0,
         bundles: [],
         settlementAddress: addresses[channels["abc"].userIndex],
         flash: {
            signersCount: 3,
            balance: channels["abc"].balance,
            deposit: channels["abc"].deposits.slice(),
            settlementAddresses: addresses,
            remainderAddress: remainderAddress,
            root: root,
            depositAddress:depositAddress,
            outputs: {},
            transfers: []
         }
      };
twoFlash.index = threeFlash.index = index;

      console.log("Sending 5 tokens to twoFlash");
      var transfers = [{value: 5, address: twoFlash.settlementAddress}];
      //console.log(theChannel.participants[fromUid]);
// *** THIS IS WHERE CODE FAILS***
      var bundles = Helpers.createTransaction(oneFlash, transfers, false);
      //console.log("Then: ");
      //console.log(theChannel.participants[fromUid]);
      console.log(bundles.length);
      var theSignatures = Helpers.signTransaction(oneFlash, bundles);
      var signedBundles = transfer.appliedSignatures(bundles, theSignatures);
      oneFlash = Helpers.applyTransfers(oneFlash, signedBundles);
      twoFlash = Helpers.applyTransfers(twoFlash, signedBundles);
      threeFlash = Helpers.applyTransfers(threeFlash, signedBundles);
      oneFlash.bundles = signedBundles;
      twoFlash.bundles = signedBundles;
      threeFlash.bundles = signedBundles;

      console.log("Transaction Applied!");
      console.log(oneFlash.flash.deposit);
      console.log("Transactable tokens: ", theChannel.participants[platform].flash.deposit.reduce((acc, v) => acc + v));



Thanks for any assistance! I've been playing with it for a few days now but haven't had any success.
Winston
Winston
Forum Admin (33K reputation)Forum Admin (33K reputation)Forum Admin (33K reputation)Forum Admin (33K reputation)Forum Admin (33K reputation)Forum Admin (33K reputation)Forum Admin (33K reputation)Forum Admin (33K reputation)Forum Admin (33K reputation)
Group: Administrators
Posts: 3.6K, Visits: 6.8K
@iotaNovice
Hey, thanks for the post and welcome to the community. If you don't get an answer here, there are a bunch of devs in the IOTA slack. Check out some of the dedicated flash channels on slack.
https://join.slack.com/t/iotatangle/shared_invite/enQtMjg0ODgwNjgwMTM0LTdjOTg4MmRjNmE2ZWQwMDE3OWVkYjZkZGVmODA2ZDA0MDlkNzkxZjIyNTE2M2VhZGJlYThiZjlkYTU5ZTVhMzY
iotaNovice
i
Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)
Group: Forum Members
Posts: 3, Visits: 0
Hi,
Thanks so much for the additional resources and for the quick response; it's much appreciated!
iotaNovice
i
Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)Attaching to Tangle (27 reputation)
Group: Forum Members
Posts: 3, Visits: 0
Hi,
I've cleaned up the code a bit. Here it is:
const IOTA = require("iota.lib.js");
require("isomorphic-fetch");

var iota = new IOTA({
    //provider:
    //  Math.random() > 0.5
    //  ? "https://testnet.tangle.works:443"
    //  : "https://testnet2.tangle.works:443"
    provider: "http://p101.iotaledger.net:14700"
});
console.log(iota);
const fundChannel = async address => {
var transfers = [{ value: 2000, address:address }];

// Get your free seeeed
var response = await fetch("https://seeds.tangle.works/");
var wallet = await response.json();

return new Promise(function(resolve, reject) {
  iota.api.sendTransfer(wallet.seed, 5, 9, transfers, (e, r) => {
  if (e !== null) {
         console.log(e);
   reject(e);
  } else {
        console.log("Channel funded!");
        proceed();
   resolve(r);
  }
  })
})
}

const IOTACrypto = require("iota.crypto.js")
const transfer = require("../lib/transfer")
const multisig = require("../lib/multisig")
const Helpers = require("./functions")
// Security level
const SECURITY = 1;
// Number of parties taking signing part in the channel
const SIGNERS_COUNT = 1;
// Flash tree depth
const TREE_DEPTH = 4;

var channels = [];
channels["abc"] = {participants:[], userIndex: 0, deposits:[2000, 0, 0], balance:2000};
const platform = "def";
const platformSeed = "BGYFYVQSGZDRLJLTPOFCTPAMMU9TCPMSR9TTTAQLNXOUS9LEIHYNWKBUHSZMIWIYQH9PEMSNDPPHSSXEZ"
const platformSettlement = "AKTFFZCMUZVPX9VBHIBPSUKMJDLVNFGTW9ZYMHTXAEYIQBZEBDZUAONIKVKZBZPIVFOPRTYKITIIPPQHD";
var addresses = [];
addresses.push(platformSettlement);
addresses.push("JEYP9TTIQJVVBQZP9OZQQHNCUDWKGIUQQB9HOQYQTQPSYOSKFLTDGXOI9ICCIKSUXVHZ9BPL9EBXDHSTB");
addresses.push("SXD9NNQFKRS9XYKGYN9GYCUDSWMRHRYAEJVDHMEQRDSU9JPULOZFVPSB9VUZGVRUSE9GL9FFABJOESWD9");
oneFlash = {
    userIndex: channels["abc"].userIndex,
    partialDigests:[],
    index: 0,
    bundles: [],
    settlementAddress: addresses[0],
    userSeed: platformSeed,
    flash: {
        signersCount: 1,
        balance: channels["abc"].balance,
        deposit: channels["abc"].deposits.slice(),
        settlementAddresses: addresses,
        remainderAddress: null,
        outputs: {},
        transfers: []
    }
};
// Create digests for the start of the channel
for (let i = 0; i < TREE_DEPTH + 1; i++) {
    // Create new digest
    const digest = multisig.getDigest(
        platformSeed,
        oneFlash.index,
        SECURITY
    Wink;
    // Increment key index
    oneFlash.index++;
    oneFlash.partialDigests.push(digest);
}

console.log("Initial digests generated!");
// INITAL MULTISIG

// Make an array of digests
let allDigests = [];
allDigests[oneFlash.userIndex] = oneFlash.partialDigests;

// Generate the first addresses
var oneMultisigs = oneFlash.partialDigests.map((digest, index) => {
    // Create address
    let addy = multisig.composeAddress(
        allDigests.map(userDigests => userDigests[index])
    Wink;
    // Add key index in
    addy.index = digest.index;
    // Add the signing index to the object IMPORTANT
    addy.signingIndex = oneFlash.userIndex * digest.security;
    // Get the sum of all digest security to get address security sum
    addy.securitySum = allDigests
        .map(userDigests => userDigests[index])
        .reduce((acc, v) => acc + v.security, 0)
    // Add Security
    addy.security = digest.security
    return addy
});

console.log("Multisigs generated!");
var remainderAddress = oneMultisigs.shift();
oneFlash.flash.remainderAddress = remainderAddress;
// Nest trees
for (let i = 1; i < oneMultisigs.length; i++) {
    oneMultisigs[i - 1].children.push(oneMultisigs[i])
}
// Set Flash root
var root = oneMultisigs.shift();
var depositAddress = iota.utils.addChecksum(oneMultisigs[0].address);
oneFlash.flash.root = root;
oneFlash.flash.depositAddress = depositAddress;
console.log("Waiting for funding...");
fundChannel(depositAddress);
function proceed() {
    console.log("Resuming");
    // Set digest/key index
    var index = oneFlash.index = oneFlash.partialDigests.length;

    console.log("Channel Setup!")
    console.log(
        "Transactable tokens: ",
        oneFlash.flash.deposit.reduce((acc, v) => acc + v)
    Wink


    twoFlash = {
        userIndex: channels["abc"].userIndex,
        index: 0,
        bundles: [],
        settlementAddress: addresses[channels["abc"].userIndex],
        flash: {
            signersCount: 1,
            balance: channels["abc"].balance,
            deposit: channels["abc"].deposits.slice(),
            settlementAddresses: addresses,
            remainderAddress: remainderAddress,
            root: root,
            depositAddress: depositAddress,
            outputs: {},
            transfers: []
        }
    };
    channels["abc"].userIndex++;

    threeFlash = {
        userIndex: channels["abc"].userIndex,
        index: 0,
        bundles: [],
        settlementAddress: addresses[channels["abc"].userIndex],
        flash: {
            signersCount: 1,
            balance: channels["abc"].balance,
            deposit: channels["abc"].deposits.slice(),
            settlementAddresses: addresses,
            remainderAddress: remainderAddress,
            root: root,
            depositAddress:depositAddress,
            outputs: {},
            transfers: []
        }
    };
    twoFlash.index = threeFlash.index = index;

    console.log("Sending 5 tokens to twoFlash");
    var transfers = [{value: 5, address: twoFlash.settlementAddress}];
    //console.log(theChannel.participants[fromUid]);
    // *** THIS IS WHERE CODE FAILS***
    var bundles = Helpers.createTransaction(oneFlash, transfers, false);
    //console.log("Then: ");
    //console.log(theChannel.participants[fromUid]);
    console.log(bundles.length);
    var theSignatures = Helpers.signTransaction(oneFlash, bundles);
    var signedBundles = transfer.appliedSignatures(bundles, theSignatures);
    oneFlash = Helpers.applyTransfers(oneFlash, signedBundles);
    twoFlash = Helpers.applyTransfers(twoFlash, signedBundles);
    threeFlash = Helpers.applyTransfers(threeFlash, signedBundles);
    oneFlash.bundles = signedBundles;
    twoFlash.bundles = signedBundles;
    threeFlash.bundles = signedBundles;
    console.log("Transaction Applied!");
    console.log(oneFlash.flash.deposit);
    console.log("Transactable tokens: ", theChannel.participants[platform].flash.deposit.reduce((acc, v) => acc + v));
}
GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Reading This Topic

Login

Explore
Messages
Mentions
Search