Creating Asset with multiple signatures JS

Hi,

I’m trying to create an asset with multiple signatures using javascript. I was following the examples on the github page and also from the documentation area, but I’ve been getting the following error: Error: The transaction sender address and multisig preimage do not match.

I used the same mnemonics to retrieve the respective addresses and private keys when I created the assets with single signatures and there were no problems with that. Is there some other issue that I still would need to consider, besides making sure that the mnemonics and sk’s match? Thanks.

Can you provide the relevant source code? (You can write it between triple backquotes ``` code ```)

Hi Fabrice,
Yes, these are the lines related to the multisignature part:

let createmultisignature = {
version: 1,
threshold: 3,
addrs: [processedmnemonic1.addr, processedmnemonic2.addr, processedmnemonic3.addr],
};

var multisignatureaddr = algosdk.multisigAddress(createmultisignature); // This is the address that I’m using in the makeAssetCreateTxn parameters

let rawSignedTxn = algosdk.signMultisigTransaction(txn, createmultisignature, processedmnemonic1.sk); // first signature

let secondSignature = algosdk.signMultisigTransaction(rawSignedTxn, createmultisignature, processedmnemonic2.sk); // second signature

let thirdSignature = algosdk.signMultisigTransaction(secondSignature, createmultisignature, processedmnemonic3.sk); // third signature

let tx = (await algodclient.sendRawTransaction(thirdSignature, postHeader));  

That looks ok. Did you check that the asset creator address matches the multisignature?
Can you print and post here the obtained signature instead of sending it (last line)

console.log(Buffer.from(thirdSignature.blob).toString('base64'));

Otherwise, can you provide a full minimum example that we can fully run? (Obviously using mnemonics that are not secret, just generate fresh ones)

Hi Fabrice,

I tried adding the line you indicated, but apparently it isn’t executed because the error comes at the point when I sign the transaction for the first time. Which ways are there for me to check if the asset creator address does match the signature? or is there a specific order I should follow or missing extension? Anyway, this is the line where I create the asset and the first parameter is the multisignature address:

let txn = algosdk.makeAssetCreateTxn(multisignatureaddr, cp.fee, cp.firstRound, cp.lastRound, note, cp.genHash, cp.genID, totalIssuance, decims, defaultFrozen, manager, reserve, freeze, clawback, unitName, certificateName, certificateURL, assetMetadataHash);

What confuses me is that I have used the same mnemonics for single signature operations that have worked correctly. Maybe I should also mention that I’m connecting through the purestake api, I don’t know whether there is a parameter that I’m skipping for that case. Thanks.

This looks like a bug in the multisig signing in the V2 JavaScript SDK. You may have to revert to the V1 API until this is fixed. Here is how multisigs are built in V1 (You can get V2 to work if you do not use the transaction builder similar to the way txn is built in V1):

const algosdk = require('algosdk');
const token = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const server = "http://localhost";
const port = 4001;


const keypress = async() => {
    process.stdin.setRawMode(true)
    return new Promise(resolve => process.stdin.once('data', () => {
        process.stdin.setRawMode(false)
        resolve()
    }))
}


(async() => {
    //create an account
    var account1 = algosdk.generateAccount();
    console.log(account1.addr);
    //create an account
    var account2 = algosdk.generateAccount();
    console.log(account2.addr);
    //create an account
    var account3 = algosdk.generateAccount();
    console.log(account3.addr);

    //Setup teh parameters for the multisig account
    const mparams = {
        version: 1,
        threshold: 2,
        addrs: [
            account1.addr,
            account2.addr,
            account3.addr,
        ],
    };

    var multsigaddr = algosdk.multisigAddress(mparams);
    console.log("Multisig Address: " + multsigaddr);
    //Pause execution to allow using the dispenser on testnet to put tokens in account
    console.log('Make sure address above has tokens using the dispenser');
    await keypress();
    try {
        let algodclient = new algosdk.Algod(token, server, port);

        //Get the relevant params from the algod
        let params = await algodclient.getTransactionParams();
        let endRound = params.lastRound + parseInt(1000);
        //example of how to write an object into the notefield

        //create a transaction
        let txn = {
            "from": multsigaddr,
            "to": "AEC4WDHXCDF4B5LBNXXRTB3IJTVJSWUZ4VJ4THPU2QGRJGTA3MIDFN3CQA",
            "fee": params.fee,
            "amount": 200000,
            "firstRound": params.lastRound,
            "lastRound": endRound,
            "genesisID": params.genesisID,
            "genesisHash": params.genesishashb64,
            "note": new Uint8Array(0)
        };
        //Sign wiith first signature
        let rawSignedTxn = algosdk.signMultisigTransaction(txn, mparams, account1.sk).blob;
        //sign with second account
        let twosigs = algosdk.appendSignMultisigTransaction(rawSignedTxn, mparams, account2.sk).blob;
        //submit the transaction
        let tx = (await algodclient.sendRawTransaction(twosigs));
        console.log("Transaction : " + tx.txId);

    } catch (err) {
        console.log(err);
    }
})().then(process.exit)

Issue logged here: https://github.com/algorand/js-algorand-sdk/issues/188
I think this has to do with using the transaction builders.

Hi Jason,

That’s very useful information, I appreciate it. Just one thing, I was using node.js for the sdk installation. Does that automatically install the latest version of the sdk? And if so, would I have to use the minified library of v1 so that the multisignature works? Thanks!

It does install the latest sdk. That said it still supports both v1 and v2 for at least the next 6mo, maybe longer. Look at the migration guide to see how to instantiate the instance. https://developer.algorand.org/docs/reference/sdks/migration/