Quras Multi-sig
What is Multisig
Multisignature (multisig) requires multiple keys to authorize a quras transaction, rather than a single signature from one key. It has many keys.
- Dividing up responsibility for possession of quras coins among multiple people.
- Avoiding a single-point of failure, making it substantially more difficult for the wallet to be compromised.
- M-of-N backup where loss of a single seed doesn't lead to loss of the wallet. Quras multisig mode: m = floor(n/2) + 1, which means if among n keys, more than m keys signed a transaction, the transaction viewed as valid.
Create and push a Multisig address
Multisig address is generated by public keys, after generating a multisig address, you can choose to push it to quras blockchain, if you push it, you can search this multisig address by one of its public keys or search which keys consist of this multisig address.
var tx = Quras.tx.Transaction.createRegisterMultiSignTx('03e969e677c8049a04d814ba72759a77fa4fa79d24e84cc145b178b0976dfeb503'); tx = Quras.tx.Transaction.joinMultiSignWallet(tx, '03b6c601a4b4528abf2a05d9f40b81482498058c1f9da034e1f241eceb557d23eb'); const scriptHash = Quras.tx.Transaction.getMultiSignScriptHash(tx); const multisigAddress = Quras.wallet.getAddressFromScriptHash(scriptHash); tx.sign('bb0e2a6e667dd396c77d13398e4886fed7d31c14e48fc471896a7200ba2e6358'); // Sign the transaction using private key const rpcServer = new Quras.rpc.RPCClient(Quras.CONST.QURAS_NETWORK.MAIN); rpcServer.sendRawTransaction(tx.serialize()) // Send the transaction to RPC Server. .then((data) => { console.log(data); }) .catch ((error) => { console.log("error"); });
Transfer XQC/XQG from a multisig address
Transfer coins from multisig address is similar to transfer coins from a normal quras address, difference is sign a multisig transaction needs at least m = floor(n/2) + 1 of keys.
Quras.api.qurasDB.getBalance(Quras.CONST.QURAS_NETWORK.DEV, 'DWrtupLj3fTsx19Zp5PjVneSrsvKdDdstS') // Get the balance of from address. .then((data) => { const balance = new Quras.wallet.Balance(data) var scriptHash = Quras.wallet.getScriptHashFromAddress('DWiDEG5kfyQC9gt7kJT86qXL5fp2TA5B4M'); // To address. const outputs = [{assetId: Quras.CONST.ASSET_ID["XQC"], // The type of coins that you want to send. value: 100 , // Coin amount to send. fee: 0.5, // fee. scriptHash: scriptHash}] // The scripthash of "To address". var testTx = Quras.tx.Transaction.createContractTx(balance, outputs) // create a transaction. Quras.api.qurasDB.getMyMultiSignMemberPubkeys(Quras.CONST.QURAS_NETWORK.DEV, 'DWrtupLj3fTsx19Zp5PjVneSrsvKdDdstS') .then((data) => { if (data.length < 1) throw new Error("There is no members"); testTx.createMultiSign(data, 'f6647ec531c4938ea477aa5c99f367820fdefdcff6f24c96aa83cfa2ab1b9e97'); // Sign the transaction using private key testTx = new Quras.tx.Transaction(JSON.parse(JSON.stringify(testTx))); testTx.joinMultiSign('7ed1aef02e9259fa81081ac2850a1e3363bbae5b5c3ac84e9ed2548848620e5f'); // Sign the transaction using private key testTx.joinMultiSign('3af2373286901af9aa9a76087800109d0b63fb8e96be447f1fafcf98db21fe84'); // Sign the transaction using private key testTx.joinMultiSign('bb0e2a6e667dd396c77d13398e4886fed7d31c14e48fc471896a7200ba2e6358'); // Sign the transaction using private key console.log(testTx.isCompletedMultiSign()); testTx = testTx.completeMultiSignTx(); const rpcServer = new Quras.rpc.RPCClient(Quras.CONST.QURAS_NETWORK.MAIN); rpcServer.sendRawTransaction(testTx.serialize()) // Send the transaction to RPC Server. .then((data) => { }).catch ((error) => {}); }).catch((error) => {}); }).catch((error) => {});
Claim XQG from multisig address
When your multisig address holds XQC, you can get XQG as rewards as normal quras address;
Quras.api.qurasDB.getClaimInfo(Quras.CONST.QURAS_NETWORK.DEV, 'DWrtupLj3fTsx19Zp5PjVneSrsvKdDdstS') .then((data) => { var testTx = Quras.tx.Transaction.createClaimTxWithQurasDB('DWrtupLj3fTsx19Zp5PjVneSrsvKdDdstS', data['available']); Quras.api.qurasDB.getMyMultiSignMemberPubkeys(Quras.CONST.QURAS_NETWORK.DEV, 'DWrtupLj3fTsx19Zp5PjVneSrsvKdDdstS') .then((data) => { if (data.length < 1) throw new Error("There is no members"); testTx.createMultiSign(data, 'f6647ec531c4938ea477aa5c99f367820fdefdcff6f24c96aa83cfa2ab1b9e97'); // Sign the transaction using private key console.log(testTx.isCompletedMultiSign()); testTx = new Quras.tx.Transaction(JSON.parse(JSON.stringify(testTx))); testTx.joinMultiSign('7ed1aef02e9259fa81081ac2850a1e3363bbae5b5c3ac84e9ed2548848620e5f'); // Sign the transaction using private key console.log(testTx.isCompletedMultiSign()); testTx.joinMultiSign('3af2373286901af9aa9a76087800109d0b63fb8e96be447f1fafcf98db21fe84'); // Sign the transaction using private key console.log(testTx.isCompletedMultiSign()); testTx.joinMultiSign('bb0e2a6e667dd396c77d13398e4886fed7d31c14e48fc471896a7200ba2e6358'); // Sign the transaction using private key console.log(testTx.isCompletedMultiSign()); testTx = testTx.completeMultiSignTx(); const rpcServer = new Quras.rpc.RPCClient(Quras.CONST.QURAS_NETWORK.MAIN); rpcServer.sendRawTransaction(testTx.serialize()) // Send the transaction to RPC Server. .then((data) => {}).catch ((error) => {}); }).catch((error) => {}); }).catch((error) => {});