Neste tutorial, você aprenderá como construir um aplicativo de votação com Choice Coin e JavaScript Algorand SDK usando NodeJs.
Requisitos
NPM e Node instalados, baixe AQUI
Uma chave de API Purestake: veja o tutorial
Contas de rede de teste financiadas: veja o tutorial
Um ambiente de desenvolvimento integrado (IDE), por exemplo, VSCode
Contexto
Este tutorial foi criado por Samuel Aspirin e Adetona Fashola.
Choice Coin é um Ativo Padrão da Algorand que potencializa o Decentralized Decisions; um software de votação e governança construído diretamente na blockchain Algorand. O software Decentralized Decisions permite que as organizações tomem decisões de governança de maneira aberta e descentralizada.
O objetivo da Choice Coin é permitir que organizações descentralizadas se governem e controlem ativos digitais de maneira equitativa. Mais organizações que desenvolvem projetos em Finanças Descentralizadas (DeFi), Tokens Não Fungíveis (NFTs) e redes blockchain precisam de uma maneira de governar. Ao contrário dos sistemas centralizados, que são inerentemente hierárquicos e piramidais por natureza, os sistemas descentralizados distribuem o poder e a tomada de decisões pelas redes globais de maneira justa. Assim, há necessidade de uma maneira de organizações descentralizadas poderem tomar decisões em livros-razão distribuídos.
Decentralized Decisions é um software projetado para atender a essa necessidade e fornecer um aplicativo de votação descentralizado pronto para uso usando Choice Coin na Rede Algorand.
O software Decentralized Decisions é de código aberto e está disponível no GitHub.
A principal linguagem de programação utilizada para o desenvolvimento do Decentralized Decisions é o Python, porém o software também pode ser escrito em outras linguagens, como o JavaScript.
Etapas:
- Configure a pasta do projeto e instale o algosdk
- Configure a API Purestake e crie um cliente
- Recupere a conta e insira o ID do ativo Choice Coin
- Escolhendo a Opção de Voto e Enviando o Voto
- Aguarde a confirmação para sincronizar o voto da Blockchain Algorand
- Verifique o saldo de $ Choice após a votação
- Execute o código completo
1. Configure a pasta do projeto e instale o algosdk
Crie uma nova pasta de projeto, isso pode ser feito no terminal com:
$ mkdir choice-coin-voting-app
Depois de criar a pasta do projeto, digite o diretório no seu terminal
$ cd choice-coin-voting-app
Para instalar dependências no projeto, você precisa iniciar uma instância NPM usando:
$ npm init -y
Crie um novo arquivo, vou nomear o meu index.js
. Isso também pode ser feito no terminal com:
$ touch index.js
No terminal, com o npm, instale o AlgoSDK e o Prompt-Sync
$ npm install algosdk prompt-sync
AlgoSDK é a biblioteca JavaScript oficial para comunicação com a rede Algorand. Ela é projetada para navegadores modernos e Node.js.
O módulo Prompt-Sync é uma função que cria funções de prompt, é a mesma coisa com o prompt dos navegadores, mas funciona com o ambiente NodeJS.
No arquivo index.js
, importe os dois módulos.
const algosdk = require('algosdk');
const prompt = require('prompt-sync')();
2. Configure a API Purestake e crie um cliente
Registre-se para uma conta de desenvolvedor Purestake e obtenha sua chave de API para interagir com a rede Algorand.
const server = "https://testnet-algorand.api.purestake.io/ps2";
const port = "";
const token = {
"X-API-Key": "SUA CHAVE DE API",
};
Crie a constante AlgodClient para iniciar a conexão.
const algodClient = new algosdk.Algodv2(token, server, port)
3. Recupere a conta e insira o ID do ativo Choice Coin
Crie um novo endereço de carteira testnet de myAlgoWallet ou Algosigner, copie e salve sua senha mnemônica de 25 e não compartilhe com ninguém.
Adicione fundos ao endereço da carteira com alguns ALGOs da testnet através da torneira.
Ative o ativo $Choice Coin com o ID 21364625 usando myAlgoWallet ou Algosigner
Troque os Algos da testnet por $choice no Tinyman.
Em index.js
const mnemonic = "Os 25 caracteres mnemônicos separados por um espaço em branco devem ser importados aqui";
const recoveredAccount = algosdk.mnemonicToSecretKey(mnemonic);
const ASSET_ID = 21364625
const voting_address = ""
Na constante voting_address
, insira uma carteira de endereço de votação recém-criada diferente daquela recuperada para a qual o valor de votação $choice pode ser enviado, certifique-se de que $choice está optando por receber votos como antes.
4. Escolhendo a Opção de Voto e Enviando o Voto
Crie uma função de votação e envie o valor votado de recoveredAccount
para a carteira de voting_address
dependendo da opção do candidato que está sendo votada.
const chooseVotingOption = async () => {
const candidateOption = prompt("Pressione 0 para o candidato Zero ou Pressione 1 para o candidato Um:")
const amount = prompt("Insira o valor para se comprometer com a votação:");
const params = await algodClient.getTransactionParams().do()
const encoder = new TextEncoder()
if (!(candidateOption)) {
console.log('Selecione uma opção de candidato válida');
} else if (!Number(amount)) {
console.log("Insira um valor de token de escolha válido para votar")
}
else if (candidateOption == "0") {
try {
let txn = algosdk.makeAssetTransferTxnWithSuggestedParams(
recoveredAccount.addr,
voting_address,
undefined,
undefined,
Number(amount),
encoder.encode("Votação com Choice coin"),
ASSET_ID,
params
)
let signedTxn = txn.signTxn(recoveredAccount.sk);
const response = await algodClient.sendRawTransaction(signedTxn).do();
if(response) {
console.log(`Você acabou de votar no candidato Zero, seu ID de voto: ${response.txId}`);
waitForConfirmation(algodClient, response.txId);
} else {
console.log('erro ao votar no candidato Zero, tente novamente mais tarde')
}
}
catch(error) {
console.log("erro ao votar no candidato Zero, tente novamente mais tarde");
}
}
else if(candidateOption == "1"){
try {
let txn = algosdk.makeAssetTransferTxnWithSuggestedParams(
recoveredAccount.addr,
voting_address,
undefined,
undefined,
Number(amount),
encoder.encode("Votação com Choice coin"),
ASSET_ID,
params
)
let signedTxn = txn.signTxn(recoveredAccount.sk);
const response = await algodClient.sendRawTransaction(signedTxn).do();
if(response) {
console.log(`Você acabou de votar no candidato Um, seu ID de votação: ${response.txId}`);
waitForConfirmation(algodClient, response.txId);
} else {
console.log('erro ao votar no candidato um, tente novamente mais tarde')
}
}
catch(error) {
console.log("Erro ao votar no candidato um, tente novamente mais tarde");
}
}
}
5. Aguarde a confirmação para sincronizar o voto da Blockchain Algorand
const waitForConfirmation = async function (algodClient, txId) {
let lastround = (await algodClient.status().do())['last-round'];
while (true) {
const pendingInfo = await algodClient.pendingTransactionInformation(txId).do();
if (pendingInfo['confirmed-round'] !== null && pendingInfo['confirmed-round'] > 0) {
//Obteve a transação concluída
console.log('Votação confirmada na rodada ' + pendingInfo['confirmed-round']);
break;
}
lastround++;
await algodClient.statusAfterBlock(lastround).do();
}
};
Esta função verifica quando o voto está sendo confirmado a partir da rede Algorand.
6. Verifique o saldo de $ Choice após a votação
const checkBalance = async () => {
// obter as informações da conta
const accountInfo = await algodClient.accountInformation(recoveredAccount.addr).do();
const assets = accountInfo["assets"];
// obter a quantidade de choice dos ativos
assets.map(asset => {
if (asset['asset-id'] === ASSET_ID) {
const amount = asset["amount"];
const choiceAmount = amount / 100;
console.log(
`Conta ${recoveredAccount.addr} tem ${choiceAmount} $choice`
);
return;
} else {
console.log(`Conta ${recoveredAccount.addr} deve optar pelo ID do ativo Choice Coin ${ASSET_ID}`);
}
})
};
Verifique o saldo de $Choice após o término da votação. Se não houver um ID do ativo Choice nas informações da conta, a função é interrompida usando return
e uma mensagem do console
é mostrada para adicionar o ID do ativo Choice ao endereço da carteira.
7. Execute o código completo
O index.js
ficaria assim.
const algosdk = require('algosdk');
const prompt = require('prompt-sync')();
// abra uma API Purestake e obtenha uma API KEY exclusiva
const server = "https://testnet-algorand.api.purestake.io/ps2";
const port = "";
const token = {
"X-API-Key": "your API key",
};
const algodClient = new algosdk.Algodv2(token, server, port);
// crie uma conta na testnet com myalgowallet, guarde a chave mnemônica
const mnemonic = "Os 25 caracteres mnemônicos separados por um espaço em branco devem ser importados aqui";
// obter conta da chave mnemônica
const recoveredAccount = algosdk.mnemonicToSecretKey(mnemonic);
// ID do ativo choice coin
const ASSET_ID = 21364625
const voting_address = "insira um endereço de carteira de votação para a qual você possa enviar Choice, certifique-se de que Choice esteja optando por receber votos"
// Digite 1 para votar no candidato um e 0 para votar no candidato Zero
const chooseVotingOption = async () => {
const candidateOption = prompt("Pressione 0 para o candidato Zero ou Pressione 1 para o candidato Um:")
const amount = prompt("Insira o valor para se comprometer com a votação:");
const params = await algodClient.getTransactionParams().do();
const encoder = new TextEncoder();
// se não houver opção válida
if (!(candidateOption)) {
console.log('Selecione uma opção de candidato válida');
} else if (!Number(amount)) {
console.log("Insira um valor de token Choice válido para votar")
}
else if (candidateOption == "0") {
try {
let txn = algosdk.makeAssetTransferTxnWithSuggestedParams(
recoveredAccount.addr,
voting_address,
undefined,
undefined,
Number(amount),
encoder.encode("Votação com Choice coin"),
ASSET_ID,
params
)
let signedTxn = txn.signTxn(recoveredAccount.sk);
const response = await algodClient.sendRawTransaction(signedTxn).do();
if(response) {
console.log(`Você acabou de votar no candidato Zero, seu ID de voto: ${response.txId}`);
<!-- wait for confirmation-->
waitForConfirmation(algodClient, response.txId);
} else {
console.log('erro ao votar no candidato Zero, tente novamente mais tarde')
}
} catch(error) {
console.log("erro ao votar no candidato Zero, tente novamente mais tarde");
}
} else if(candidateOption == "1"){
try {
let txn = algosdk.makeAssetTransferTxnWithSuggestedParams(
recoveredAccount.addr,
voting_address,
undefined,
undefined,
Number(amount),
encoder.encode("Votação com Choice coin"),
ASSET_ID,
params
)
let signedTxn = txn.signTxn(recoveredAccount.sk);
const response = await algodClient.sendRawTransaction(signedTxn).do();
if(response) {
console.log(`Você acabou de votar no candidato Um, seu ID de votação: ${response.txId}`);
<!-- wait for confirmation-->
waitForConfirmation(algodClient, response.txId);
} else {
console.log('erro ao votar no candidato um, tente novamente mais tarde')
}
} catch(error) {
console.log("Erro ao votar no candidato um, tente novamente mais tarde");
}
}
}
chooseVotingOption();
// função de verificação
const waitForConfirmation = async function (algodClient, txId) {
let lastround = (await algodClient.status().do())['last-round'];
while (true) {
const pendingInfo = await algodClient.pendingTransactionInformation(txId).do();
if (pendingInfo['confirmed-round'] !== null && pendingInfo['confirmed-round'] > 0) {
console.log('Votação confirmada na rodada ' + pendingInfo['confirmed-round']);
break;
}
lastround++;
await algodClient.statusAfterBlock(lastround).do();
}
};
// verificar saldo da conta
const checkBalance = async () => {
const accountInfo = await algodClient.accountInformation(recoveredAccount.addr).do();
const assets = accountInfo["assets"];
// obter a quantidade de Choice dos ativos
assets.map(asset => {
if (asset['asset-id'] === ASSET_ID) {
const amount = asset["amount"];
const choiceAmount = amount / 100;
console.log(
`Conta ${recoveredAccount.addr} tem ${choiceAmount} $choice`
);
return;
} else {
console.log(`Conta ${recoveredAccount.addr} deve optar pelo ID do ativo Choice Coin ${ASSET_ID}`);
}
})
};
checkBalance();
Para determinar o vencedor, você pode verificar a saída da função checkBalance
que mostra o número de $choice que cada conta possui. Este número representa o número total de votos para cada opção. Se quiser, você pode escrever uma função rápida para determinar quem recebeu mais votos.
Em conclusão, fizemos uma aplicação de votação com Choice Coin e Javascript com o Algorand SDK usando NodeJS. Você pode conferir o código completo no GitHub
(Fonte da imagem: Unsplash @Arnaud Jaegers)
Tutorial original escrito por Samuel Aspirin, traduzido por Paulinho Giovannini.
Latest comments (0)