Neste tutorial, abordaremos o processo de criação de uma multisig - uma conta que compartilha autorização para transações em vários endereços.
Introdução
Neste tutorial, abordaremos o processo de criação de uma multisig - uma conta que compartilha autorização para transações em vários endereços. A palavra "multisig" significa "assinatura múltipla". Para os fins deste tutorial, geraremos duas contas adicionais e garantiremos que ambas sejam financiadas com WND suficiente para cobrir o depósito existencial e enviar algumas transações. Estes serão usados para simular as outras partes assinantes da carteira multisig.
Criaremos um novo aplicativo de linha de comando em JavaScript para lidar com as operações de criação e uso dessa conta multisig no Westend, embora os mesmos conceitos e a maior parte do código ainda se apliquem à Polkadot ou a outras blockchains baseadas no Substrate.
Existem muitas aplicações em potencial desse conceito; no entanto, para este tutorial, estamos preocupados principalmente com a camada adicional de segurança da conta. Essa funcionalidade está no centro de muitas DAOs e estruturas de governança semelhantes. Uma conta multisig é em si uma forma de governança on-chain e uma multisig geralmente requer participação ativa.
Confira o Documentação da API da Polkadot para um resumo de todos os metadados relevantes da API.
Na documentação da API Polkadot JS:
É possível criar uma conta com várias assinaturas em cadeias baseadas no Substrate. Uma conta com várias assinaturas é composta por um ou mais endereços e um limite. O limite define quantos signatários ( endereços participantes ) precisam concordar com o envio de um extrínseco para que a chamada seja bem-sucedida. Por exemplo, Alice, Bob e Charlie montaram uma multi-sig com um limite de 2. Isso significa que Alice e Bob podem executar qualquer chamada, mesmo que Charlie discorde. Da mesma forma, Charlie e Bob podem executar qualquer ligação sem Alice. Um limite é tipicamente um número menor que o número total de membros, mas também pode ser igual a ele, o que significa que todos precisam estar de acordo.
também:
Contas com várias assinaturas não podem ser modificadas após serem criadas. Alterar o conjunto de membros ou alterar o limite não é possível e, em vez disso, requer a dissolução da atual multi-sig e a criação de uma outra. Como tal, os endereços de conta multi-sig são determinísticos, ou seja, você sempre pode calcular o endereço de uma multi-sig apenas conhecendo os membros e o limite, sem que a conta ainda exista. Isso significa que é possível enviar tokens para um endereço que ainda não existe e se as entidades designadas como destinatários se reunirem em uma nova multi-sig sob um limite correspondente, eles terão acesso imediato a esses tokens.
também:
Embora Westend pretenda replicar a rede principal da Polkadot o mais próximo possível, existem algumas diferenças notáveis:
Depósito existencial é igual a 0,01 WND ( Westies; Moeda nativa de Westend ) em vez de 1 DOT.
O depósito de transação com várias assinaturas é igual a ~ 1 WND em vez de ~ 20.2 DOT.
Configuração
Não é um requisito, no entanto, concluir o Polkadot Pathway e o tutorial de recuperação social formam uma forte base de entendimento que aprimorará este tutorial.
A maneira mais simples de satisfazer esses requisitos e manter a flexibilidade como usuário do Windows 10 é instalar WSL2 e VSCode - a janela do terminal dentro do VSCode pode utilizar qualquer shell, da bash ao PowerShell. Os usuários de Linux e macOS não precisam do WSL2 e podem usar qualquer aplicativo de terminal e editor de texto de sua escolha.
Node.js instalado, de preferência com uma ferramenta para gerenciamento de versão - nvm ou fnm são escolhas populares
Um gerenciador de pacotes como npm ou yarn - a instalação variará de acordo com o sistema operacional
Este tutorial possui as duas dependências a seguir que devem ser instaladas através do gerenciador de pacotes :
Inicialize o diretório do projeto
mkdir polkadot_ms
cd polkadot_ms
npm init -y
npm install --save dotenv @polkadot/api
Quando copiamos e colamos todos os quatro comandos em um terminal, os três primeiros serão executados em sequência porque possuem um caractere de código de fim de linha (enter). mkdir polkadot_ms
criará um novo subdiretório chamado polkadot_ms
, então o comando cd altera o diretório de trabalho. npm init -y
vai emitir o conteúdo do padrão package.json
para o terminal. Neste ponto, a parte npm install
estará na linha de comando, no entanto ainda devemos pressionar Enter para iniciar o processo de instalação.
Quando o processo de instalação estiver concluído, crie um arquivo .env
no diretório do projeto. Por conveniência, copie e cole o modelo abaixo. Leia mais sobre dotenv
em nosso guia de referência rápida. Lembre-se também de substituir API_KEY
por uma chave API válida do DataHub do Painel de serviços Polkadot.
Cole o seguinte no seu arquivo.env
:
MULTISIG_ADDRESS=
ALICE_ADDRESS=
ALICE_MNEMONIC=
BOB_ADDRESS=
BOB_MNEMONIC=
CHARLIE_ADDRESS=
CHARLIE_MNEMONIC=
Crie 3 contas
Crie um arquivo chamado create_account.js
e cole o seguinte código :
// create_account.js
const { ApiPromise, Keyring } = require('@polkadot/api');
const { HttpProvider } = require('@polkadot/rpc-provider');
const { mnemonicGenerate } = require('@polkadot/util-crypto');
require("dotenv").config();
const main = async () => {
const httpProvider = new HttpProvider(process.env.DATAHUB_URL);
const api = await ApiPromise.create({ provider: httpProvider });
const keyring = new Keyring({type: 'sr25519'});
const mnemonic = mnemonicGenerate();
const newAccount = await keyring.addFromUri(mnemonic);
console.log(`address: ${newAccount.address}`);
console.log(`mnemonic: ${mnemonic}`);
};
main().catch((err) => {console.error(err)}).finally(() => process.exit());
Em uma janela do terminal, execute node create_account.js
3 (três) vezes para gerar os dados que necessitamos. Copie / cole os mnemônicos e endereços para cada nova conta no modelo .env
.
Alice
: A conta que usaremos na carteira multisig.Bob & Charlie
: Essas contas representam outros participantes do multisig.
Financie a conta Alice visitando https://faucet.figment.io e digitando o endereço que geramos para Alice. Isso fornecerá tokens WND suficientes para essa conta para concluirmos o tutorial com muitos itens restantes para teste. Como precisaremos pagar as taxas pelas transações durante o tutorial, também será necessário transferir alguns tokens para as outras contas.
Existem três tipos de ações a serem tomadas com uma conta multi-sig. Executar uma chamada, aprovar uma chamada ou cancelar uma chamada.
Crie uma conta Multisig
Crie um arquivo chamado create_multisig.js
e cole o seguinte código :
const { ApiPromise, Keyring } = require('@polkadot/api');
const { sortAddresses, encodeMultiAddress } = require('@polkadot/util-crypto');
const { HttpProvider } = require('@polkadot/rpc-provider');
require("dotenv").config();
const main = async () => {
const httpProvider = new HttpProvider(process.env.DATAHUB_URL);
const api = await ApiPromise.create({ provider: httpProvider });
const keyring = new Keyring({type: 'sr25519'});
// 1. Define as constantes relevantes
const INDEX = 0;
const THRESHOLD = 2;
const SS58PREFIX = 0;
const AMOUNT_TO_SEND = 1000000000000;
// 2. Inicializa as contas
const Alice = keyring.addFromUri(process.env.ALICE_MNEMONIC);
const Bob = keyring.addFromUri(process.env.BOB_MNEMONIC);
const Charlie = keyring.addFromUri(process.env.CHARLIE_MNEMONIC);
const addresses = [
Alice.address, // addresses[0]
Bob.address, // addresses[1]
Charlie.address, // addresses[2]
];
// 3.Cria Multisig (com operacional SS58PREFIX)
const multisig = encodeMultiAddress(addresses, THRESHOLD);
console.log(`Multisig Address: ${multisig}\n`);
// 4. Filtra o remetente
const otherSignatories = addresses.filter((who) => who !== addresses[INDEX]);
const otherSignatoriesSorted = sortAddresses(otherSignatories);
console.log(`Other Signatories: ${JSON.stringify(otherSignatoriesSorted, null, 2)}\n`);
// 4. Define um array de transações
const transactions = [
api.tx.balances.transfer(Bob.address, AMOUNT_TO_SEND),
api.tx.balances.transfer(Charlie.address, AMOUNT_TO_SEND),
];
// 5. Envia oLote 1 WND para outros endereços
// Isso é necessário para poder assinar e enviar transações com estas contas
const txHash = await api.tx.utility
.batch(transactions)
.signAndSend(Alice);
console.log(`Sending 1 WND from ${Alice.address} to ${otherSignatories}`);
console.log(`transfer tx: https://westend.subscan.io/extrinsic/${txHash}`);
};
main().catch((err) => { console.error(err) }).finally(() => process.exit());
SS58PREFIX
é usado para codificar nosso endereço para uso em diferentes cadeias. O valor0
codificará nosso endereço multisig para a cadeia de relés Polkadot; portanto, o endereço codificado começará com o número1
. A equipe Parity mantém um registro dos tipos SS58, o que pode ser útil ao trabalhar com várias parachains.INDEX
será usado para se referir ao índice de nosso endereço em uma matriz de endereços. Mais informações sobre matrizes indexadas a zero, para os curiosos.THRESHOLD
especifica o número de contas necessárias para aprovar uma transação da Multisig. É possível definir o limite para o mesmo número de endereços totais, o que significaria que nenhuma transação poderia ser enviada dessa multisig sem a aprovação total, no entanto, neste exemplo, definiremos como necessárias 2 de 3 assinaturas.otherSignatories
ilustra o uso defilter()
para remover o endereço no índice especificado. Antes de exibirmos a lista filtrada de endereços, a funçãosortAddresses()
irá classificá-lo por chave pública. Registrando isso viaJSON.stringify()
será exibidoem um formato mais legível no terminal.encodeMultiAddress()
faz parte da matriz de endereços,THRESHOLD
& e opcionalmenteoSS58PREFIX
e retorna o endereço determinístico da multisig. Se o prefixo SS58 estiver incluído, o endereço será codificado para a cadeia especificada.
Execute o código com node create_multisig.js
:
Multisig Address: 5CPnQhU8TCvtbaJQEYEPuYhgbwpeGqhx6uErZJ7QDcaD7aX9
Other Signatories: [
"5GL63QD2HhXvBMcP9skdjq8H5Znhe7Fke83aWENHPGRMvJSA",
"5GpDZiUMpdX2GcGJzAZVX36kSGoScraCLEjTTgvhufEokRCX"
]
Sending 1 WND from 5Ekc5BsbkAgSbSYwi4W1CnpYLFzwUDJ4WGvohSzNcau2ZDLp
to 5GL63QD2HhXvBMcP9skdjq8H5Znhe7Fke83aWENHPGRMvJSA, 5GpDZiUMpdX2GcGJzAZVX36kSGoScraCLEjTTgvhufEokRCX
transfer tx: [https://westend.subscan.io/extrinsic/…](https://westend.subscan.io/extrinsic/%E2%80%A6)
Lembre-se de copiar e colar o valor resultante para o endereço Multisig em
.env
comoMULTISIG_ADDRESS
em preparação para o próximo passo!
Financiar uma conta Multisig
O financiamento da carteira multisig é uma etapa importante nesse processo do tutorial, para que ela tenha saldo disponível suficiente para cobrir o depósito existencial e um saldo disponível para o envio de transações adicionais.
Crie um arquivo chamado fund_multisig.js
e cole o seguinte código :
const { ApiPromise, Keyring } = require('@polkadot/api');
const { HttpProvider } = require('@polkadot/rpc-provider');
const { formatBalance } = require('@polkadot/util/format');
require("dotenv").config();
const main = async () => {
const httpProvider = new HttpProvider(process.env.DATAHUB_URL);
const api = await ApiPromise.create({ provider: httpProvider });
const keyring = new Keyring({type: 'sr25519'});
// 1. Define as constantes relevantes
formatBalance.setDefaults({
unit: 'WND',
decimals: 12,
});
// 2. Define as constantes relevantes
const MULTISIG = process.env.MULTISIG_ADDRESS;
const AMOUNT_TO_SEND = 2000000000000;
const displayAmount = formatBalance(AMOUNT_TO_SEND); // 2.0000 WND
// 3. Inicializa a conta
const Alice = keyring.addFromUri(process.env.ALICE_MNEMONIC)
// 4.Envia 2 WND para conta multisig
const txHash = await api.tx.balances
.transfer(MULTISIG, AMOUNT_TO_SEND)
.signAndSend(Alice);
console.log(`Sending ${displayAmount} from ${Alice.address} to ${MULTISIG}`);
console.log(`transfer tx: https://westend.subscan.io/extrinsic/${txHash}`);
};
main().catch((err) => { console.error(err) }).finally(() => process.exit());
A função formatBalance.setDefaults()
nos permite especificar um nome de unidade e casas decimais. Como estamos operando na rede de testes Westend, o WND é apropriado. Como podemos ver, AMOUNT_TO_SEND
será especificado como um grande número - 2 trilhões de pWND **** (p para pico, denotando um fator de, neste caso ) - embora possamos exibi-lo de maneira legível e pré-formatada usando formatBalance()
. Pode ser útil visualizar amountToSend
em doze casas decimais como esta :
// 2,000,000,000,000 = 2.0 WND
Para concluir a ação de financiar a conta multisig especificada, pagando com o saldo disponível de Alice
, nós usamos api.tx.balances
para acessar o método transfer()
e depois signAndSend()
. Isso realizará a criação da conta multisig ( fornecendo o depósito existencial ) enquanto transfere 2 WND para ela.
Execute o código com node fund_multisig.js
:
Sending 2.0000 WND
from 5Ekc5BsbkAgSbSYwi4W1CnpYLFzwUDJ4WGvohSzNcau2ZDLp
to 5CPnQhU8TCvtbaJQEYEPuYhgbwpeGqhx6uErZJ7QDcaD7aX9
transfer tx: [https://westend.subscan.io/extrinsic/…](https://westend.subscan.io/extrinsic/%E2%80%A6)
A páginaSubScan incluirá esses 4 eventos. Consulte os seguintes exemplos de eventos bem-sucedidos.
Executar uma transferência Multisig
Crie um arquivo chamado transfer_multisig.js
e cole o seguinte código :
const { ApiPromise, Keyring } = require('@polkadot/api');
const { HttpProvider } = require('@polkadot/rpc-provider');
const { formatBalance } = require('@polkadot/util/format')
require("dotenv").config();
const main = async () => {
const httpProvider = new HttpProvider(process.env.DATAHUB_URL);
const api = await ApiPromise.create({ provider: httpProvider });
const keyring = new Keyring({type: 'sr25519'});
// 1. Use formatBalance para exibir os valores
formatBalance.setDefaults({
unit: 'WND',
decimals: 12,
});
// 2. Define constantes relevantes
const THRESHOLD = 2;
const MAX_WEIGHT = 640000000;
const AMOUNT_TO_SEND = 1000000000000;
const MULTISIG = process.env.MULTISIG_ADDRESS;
const displayAmount = formatBalance(AMOUNT_TO_SEND);
const depositBase = api.consts.multisig.depositBase;
const depositFactor = api.consts.multisig.depositFactor;
// 3. Inicializa as contas
const Alice = keyring.addFromUri(process.env.ALICE_MNEMONIC);
const Bob = keyring.addFromUri(process.env.BOB_MNEMONIC);
const Charlie = keyring.addFromUri(process.env.CHARLIE_MNEMONIC);
const otherSignatories = [
Bob.address,
Charlie.address,
].sort();
// 4. Chamadas API - dados são necessários para o timepoint
const call = api.tx.balances.transfer(Charlie.address, AMOUNT_TO_SEND);
const info = await api.query.multisig.multisigs(MULTISIG, call.method.hash);
// 5. Define o timepoint
// se esta É a primeira aprovação estão deve retornar None (null)
const TIME_POINT = null;
// Se esta NÃO é a primeira aprovação então deve retornar Some
// Com o timepoint (número do bloco e índice da transação), da primeira transação de aprovação
// const TIME_POINT = info.unwrap().when;
// 6. approveAsMulti
const txHash = await api.tx.multisig
.approveAsMulti(THRESHOLD, otherSignatories, TIME_POINT, call.method.hash, MAX_WEIGHT)
.signAndSend(Alice);
console.log(`depositBase : ${depositBase}`);
console.log(`depositFactor : ${depositFactor}`);
console.log(`Sending ${displayAmount} from ${Alice.address} to ${MULTISIG}`);
console.log(`Required values : approveAsMulti(THRESHOLD, otherSignatories, TIME_POINT, call.method.hash, MAX_WEIGHT)`);
console.log(`Submitted values : approveAsMulti(${THRESHOLD}, otherSignatories: ${JSON.stringify(otherSignatories, null, 2)}, ${TIME_POINT}, ${call.method.hash}, ${MAX_WEIGHT})\n`);
console.log(`approveAsMulti tx: https://westend.subscan.io/extrinsic/${txHash}`);
};
main().catch((err) => { console.error(err) }).finally(() => process.exit());
THRESHOLD
eotherSignatories
deve ser conhecido,TIME_POINT
deve sernull
se esta é a primeira aprovação para o multisig.call.method.hash
faz o que diz, retornando uma representação de hash dos dados do método da transferência.MAX_WEIGHT
refere-se ao peso máximo da chamada, embora isso não esteja claramente indicado na documentação da API, ele tem a ver com o cálculo da taxa. O peso é um número fixo projetado para gerenciar os tempos de validação de blocos. Pode ser complementado com uma dica opcional. Leia mais sobre as taxas de transação Polkadot aqui.
Execute o código com node transfer_multisig.js
:
depositBase : 1.0044 WND
depositFactor : 1.6000 mWND
Sending 1.0000 WND
from 5Ekc5BsbkAgSbSYwi4W1CnpYLFzwUDJ4WGvohSzNcau2ZDLp
to 5CPnQhU8TCvtbaJQEYEPuYhgbwpeGqhx6uErZJ7QDcaD7aX9
Required values : approveAsMulti(THRESHOLD, otherSignatories, TIME_POINT, call.method.hash, MAX_WEIGHT)
Submitted values : approveAsMulti(2, otherSignatories: [
"5GL63QD2HhXvBMcP9skdjq8H5Znhe7Fke83aWENHPGRMvJSA",
"5GpDZiUMpdX2GcGJzAZVX36kSGoScraCLEjTTgvhufEokRCX"
], null, 0xb9533f7199a78343facd0fa13e15a08b3620c75dfe49c37660e832a0cb1ff146, 640000000)
approveAsMulti tx: [https://westend.subscan.io/extrinsic/…](https://westend.subscan.io/extrinsic/%E2%80%A6)
Aprovar uma transferência Multisig
Crie um novo arquivo chamado approve_multisig.js
e cole o seguinte código :
const { ApiPromise, Keyring } = require('@polkadot/api');
const { HttpProvider } = require('@polkadot/rpc-provider');
const { formatBalance } = require('@polkadot/util/format')
require("dotenv").config();
const main = async () => {
const httpProvider = new HttpProvider(process.env.DATAHUB_URL);
const api = await ApiPromise.create({ provider: httpProvider });
const keyring = new Keyring({type: 'sr25519'});
// 1. Usa o formatBalance para exibir os valores
formatBalance.setDefaults({
unit: 'WND',
decimals: 12,
});
// 2. Define as constantes relevantes
const THRESHOLD = 2;
const STORE_CALL = false;
const MAX_WEIGHT = 640000000;
const AMOUNT_TO_SEND = 1000000000000;
const MULTISIG = process.env.MULTISIG_ADDRESS;
const displayAmount = formatBalance(AMOUNT_TO_SEND);
// 3. Inicializa as contas
const Alice = keyring.addFromUri(process.env.ALICE_MNEMONIC);
const Bob = keyring.addFromUri(process.env.BOB_MNEMONIC);
const Charlie = keyring.addFromUri(process.env.CHARLIE_MNEMONIC);
const otherSignatories = [
Alice.address,
Charlie.address,
].sort();
// 4. Envia 1 WND para a conta Charlie
const call = api.tx.balances.transfer(Charlie.address, AMOUNT_TO_SEND);
// 5. Recupera e desempacota o ponto de parada
const info = await api.query.multisig.multisigs(MULTISIG, call.method.hash);
const TIME_POINT= info.unwrap().when;
console.log(`Time point is: ${TIME_POINT}`);
// 6. Envia a transação asMulti
//Agora a chamada multisig que foi iniciada pela conta da Alice envia 1 WND para Charlie que é aprovado pelo Bob.
// Como o limite é definido como 2 , essa aprovação deve enviar a chamada
// (Recebimento de 2 chamadas)
const txHash = await api.tx.multisig
.asMulti(THRESHOLD, otherSignatories, TIME_POINT, call.method.toHex(), STORE_CALL, MAX_WEIGHT)
.signAndSend(Bob);
console.log(`Sending ${displayAmount} from ${MULTISIG} to ${Charlie.address}`);
console.log(`Required values : asMulti(THRESHOLD, otherSignatories, TIME_POINT, call.method.hash, MAX_WEIGHT)`);
console.log(`Submitted values : asMulti(${THRESHOLD}, otherSignatories: ${JSON.stringify(otherSignatories, null, 2)}, ${TIME_POINT}, ${call.method.hash}, ${MAX_WEIGHT})\n`);
console.log(`asMulti tx: https://westend.subscan.io/extrinsic/${txHash}`);
}main().catch((err) => { console.error(err) }).finally(() => process.exit());
call.method.toHex()
difere de call.method.hash
em que toHex()
só vai passar uma representação hexadecimal do método, mas não o método completo.
Se encontrarmos Error: Option: unwrapping
a None value
significa que a chamada unwrap()
n consulta da API encontrou um valor Nenhum quando esperava Algum valor ( um ponto de tempo válido ). Provavelmente isso seria devido ao api.query.multisig.multisigs()
não tendo um ponto de tempo associado - indicando a ausência de approveAsMulti()
. Em essência, não há dados sobre os quais agir neste caso - possivelmente por tentar executar approve_multisig.js
antes de transfer_multisig.js
.
Execute o código com node approve_multisig.js
:
The timepoint is: {"height":5556711,"index":2}
Sending 1.0000 WND
from 5CPnQhU8TCvtbaJQEYEPuYhgbwpeGqhx6uErZJ7QDcaD7aX9
to 5GpDZiUMpdX2GcGJzAZVX36kSGoScraCLEjTTgvhufEokRCX
asMulti tx: [https://westend.subscan.io/extrinsic/…](https://westend.subscan.io/extrinsic/%E2%80%A6)
Cancelar uma transferência multisig
Crie um novo arquivo chamado cancel_multisig.js
e cole o seguinte código :
const { ApiPromise, Keyring } = require('@polkadot/api');
const { HttpProvider } = require('@polkadot/rpc-provider');
const { formatBalance } = require('@polkadot/util/format')
require("dotenv").config();
const main = async () => {
const httpProvider = new HttpProvider(process.env.DATAHUB_URL);
const api = await ApiPromise.create({ provider: httpProvider });
const keyring = new Keyring({type: 'sr25519'});
// 1. Usa formatBalance para exibir os valores
formatBalance.setDefaults({
unit: 'WND',
decimals: 12,
});
// 2. Define as constantes relevantes
const THRESHOLD = 2;
const STORE_CALL = false;
const MAX_WEIGHT = 640000000;
const AMOUNT_TO_SEND = 1000000000000;
const MULTISIG = process.env.MULTISIG_ADDRESS;
const displayAmount = formatBalance(AMOUNT_TO_SEND);
// 3. Inicializa as contas
const Alice = keyring.addFromUri(process.env.ALICE_MNEMONIC);
const Bob = keyring.addFromUri(process.env.BOB_MNEMONIC);
const Charlie = keyring.addFromUri(process.env.CHARLIE_MNEMONIC);
const otherSignatories = [
Alice.address,
Charlie.address,
].sort();
// 4. Envia 1 WND para conta Charlie
// Essa é a transação multisig que nós queremos cancelar
const call = api.tx.balances.transfer(Charlie.address, AMOUNT_TO_SEND);
// 5. Recupera e desempacota timepoint
const info = await api.query.multisig.multisigs(MULTISIG, call.method.hash);
const TIME_POINT= info.unwrap().when;
console.log(`Time point is: ${TIME_POINT}`);
// 6. Cancela a transação asMulti
const txHash = await api.tx.multisig
.cancelAsMulti(THRESHOLD, otherSignatories, TIME_POINT, call.method.hash)
.signAndSend(Bob);
console.log(`Sending ${displayAmount} from ${MULTISIG} to ${Charlie.address}`);
console.log(`Required values : cancelAsMulti(THRESHOLD, otherSignatories, TIME_POINT, call.method.hash)`);
console.log(`Submitted values : cancelAsMulti(${THRESHOLD}, otherSignatories: ${JSON.stringify(otherSignatories, null, 2)}, ${TIME_POINT}, ${call.method.hash})\n`);
console.log(`cancelAsMulti tx: https://westend.subscan.io/extrinsic/${txHash}`);
}
main().catch((err) => { console.error(err) }).finally(() => process.exit());
Não é necessário executar este código no curso normal do tutorial, ele é em grande parte incluído aqui por uma questão de integridade. Isso seria útil caso uma transação de aprovação multisig fique paralisada ou precise ser cancelada por qualquer motivo. Caso seja necessário ou para fins de teste, execute o código com node cancel_multisig.js
:
Time point is: {"height":5557129,"index":2}
Sending 1.0000 WND
from 5CPnQhU8TCvtbaJQEYEPuYhgbwpeGqhx6uErZJ7QDcaD7aX9
to 5GpDZiUMpdX2GcGJzAZVX36kSGoScraCLEjTTgvhufEokRCX
Required values : cancelAsMulti(THRESHOLD, otherSignatories, TIME_POINT, call.method.hash)
Submitted values : cancelAsMulti(2, otherSignatories: [
"5GL63QD2HhXvBMcP9skdjq8H5Znhe7Fke83aWENHPGRMvJSA",
"5GpDZiUMpdX2GcGJzAZVX36kSGoScraCLEjTTgvhufEokRCX"
], {"height":5557129,"index":2}, 0xb9533f7199a78343facd0fa13e15a08b3620c75dfe49c37660e832a0cb1ff146)
cancelAsMulti tx: [https://westend.subscan.io/extrinsic/0x774822d10f1159f12491bf9351a7b043100ccac88f5ed2c34ab1eac07fe190fe](https://westend.subscan.io/extrinsic/0x774822d10f1159f12491bf9351a7b043100ccac88f5ed2c34ab1eac07fe190fe)
Conclusão
Parabéns! Este tutorial abordou a criação e o uso de uma conta multisig usando a API Polkadot JS. Agora podemos iniciar, aprovar e cancelar transações usando uma conta que requer várias autorizações. Essa funcionalidade permite que muitas outras coisas incríveis sejam construídas no Polkadot, e todos esperamos ver o que você constrói usando contas multisig.
Este artigo foi escrito por Rogan X e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.
Top comments (0)