Nhảy tới nội dung

Multisig Account Key

AccountKeyWeightedMultiSig is an account key type containing a threshold and WeightedPublicKeys which contains a list consisting of a public key and its weight.

In order for a transaction to be valid for an account associated with AccountKeyWeightedMultiSig, the following conditions should be satisfied: _ The weighted sum of the signed public keys should be larger than the threshold. _ The invalid signature should not be included in the transaction. * The number of signed public keys should be less than the number of weightedPublicKeys.

Import the ethers and @kaiachain/ethers-ext packages to add kaia features on ethers.js

Define sender address, sender private key and new muti-sig private keys to be changed

Set up the provider with the specified kaia Baobab testnet URL. A provider in ethers is a read-only abstraction to access the blockchain data.

Also, you can change the provider URL from baobab to allthatnode

Create three sender's wallets with the private keys and provider

Compute the public keys from the new private keys

Declare a transaction which has the keys field with the computed public keys and theirs weight, specify the type as WeightedMultiSig

Sign the transaction with the first wallet

Sign the transaction with the second wallet

Sign the transaction with the third wallet and send it to kaia network

The wait function returns the tx receipt if it is completed in the blockchain.

AccountUpdateWithMultiSigExample.js

const { ethers } = require("ethers");
const { Wallet, TxType, AccountKeyType } = require("@kaiachain/ethers-ext");
// Using same senderNewPriv keys to execute this example repeatedly.
// But you might want to register the different private keys.
const senderAddr = "0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e";
const senderNewPriv1 = "0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a";
const senderNewPriv2 = "0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8";
const senderNewPriv3 = "0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac";
const provider = new ethers.providers.JsonRpcProvider("https://public-en-kairos.node.kaia.io");
const wallet1 = new Wallet(senderAddr, senderNewPriv1, provider);
const wallet2 = new Wallet(senderAddr, senderNewPriv2, provider);
const wallet3 = new Wallet(senderAddr, senderNewPriv3, provider);
async function main() {
const pub1 = ethers.utils.computePublicKey(senderNewPriv1, true);
const pub2 = ethers.utils.computePublicKey(senderNewPriv2, true);
const pub3 = ethers.utils.computePublicKey(senderNewPriv3, true);
console.log({ pub1, pub2, pub3 });
const tx = {
type: TxType.AccountUpdate,
from: senderAddr,
gasLimit: 1000000,
key: {
type: AccountKeyType.WeightedMultiSig,
threshold: 2,
keys: [
[1, pub1],
[1, pub2],
[1, pub3],
]
}
};
// The example senderAddr actually requires only 2 signature (threshold = 2),
// but we use 3 signatures to show different ways to sign a transaction.
// sign 1: First signer sign from the tx object
const populatedTx = await wallet1.populateTransaction(tx);
const rawTx1 = await wallet1.signTransaction(populatedTx);
console.log("rawTx1", rawTx1);
// sign 2: Middle signer sign from the rawTx
const rawTx2 = await wallet2.signTransaction(rawTx1);
console.log("rawTx2", rawTx2);
// sign 3: Last signer sign and send from the rawTx
const sentTx3 = await wallet3.sendTransaction(rawTx2);
console.log("sentTx3", sentTx3.hash);
const receipt = await sentTx3.wait();
console.log("receipt", receipt);
}
main().catch(console.error);

output

❯ js AccountUpdateWithMultiSigExample.js
{
pub1: '0x021473839f05083617d532325ce8aa40edffb2bc79f1ce17c77cc41f92f027dd82',
pub2: '0x03dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd',
pub3: '0x03f26489914098c5da51f0f646e3000da4d6197217df082b4f7ce1530f0a0cbf2a'
}
rawTx1 0x20f8dd74850ba43b7400830f42409482c6a8d94993d49cfd0c1d30f0f8caa65782cc7eb87204f86f02f86ce301a1021473839f05083617d532325ce8aa40edffb2bc79f1ce17c77cc41f92f027dd82e301a103dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cde301a103f26489914098c5da51f0f646e3000da4d6197217df082b4f7ce1530f0a0cbf2af847f8458207f6a055fef1ed11853c582a281365fb4f381d2b895758a0436002b6fac3b292594e32a01681d4879eac18d27d20b2dd377cbba4ce723be992ec0fd5e6686645c75c1a3c
rawTx2 0x20f9012474850ba43b7400830f42409482c6a8d94993d49cfd0c1d30f0f8caa65782cc7eb87204f86f02f86ce301a1021473839f05083617d532325ce8aa40edffb2bc79f1ce17c77cc41f92f027dd82e301a103dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cde301a103f26489914098c5da51f0f646e3000da4d6197217df082b4f7ce1530f0a0cbf2af88ef8458207f6a055fef1ed11853c582a281365fb4f381d2b895758a0436002b6fac3b292594e32a01681d4879eac18d27d20b2dd377cbba4ce723be992ec0fd5e6686645c75c1a3cf8458207f6a0b445954342f2a9d2b0973f8b36de46e633968c946a9dbbaa3add4f09c91bc0f7a00a72b483157a961d10ed57b6089ee8399018fe5a0f91881375f1b4a0b4fdcf54
sentTx3 0x722b434220cd61c80cf827672bc79006183629399a4f1ad0c98552a47cbb7e07
receipt {
to: '0x82C6a8D94993d49cfd0c1D30F0F8Caa65782cc7E',
from: '0x82C6a8D94993d49cfd0c1D30F0F8Caa65782cc7E',
contractAddress: null,
transactionIndex: 1,
gasUsed: BigNumber { _hex: '0x01b198', _isBigNumber: true },
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
blockHash: '0x7e43df2efc735e7c47c163c6ac5ad50c10de542f48cfc5088dfec251b66298c2',
transactionHash: '0x722b434220cd61c80cf827672bc79006183629399a4f1ad0c98552a47cbb7e07',
logs: [],
blockNumber: 152203392,
confirmations: 2,
cumulativeGasUsed: BigNumber { _hex: '0x03ed06', _isBigNumber: true },
effectiveGasPrice: BigNumber { _hex: '0x05d21dba00', _isBigNumber: true },
status: 1,
type: 0,
byzantium: true
}