Sestavte si decentralizovanou hlasovací aplikaci s Choice Coin a Javascript algorand sdk   pomocí NodeJS📨

Choice Coin je standardní aktivum Algorand, které pohání decentralizovaná rozhodnutí, software pro hlasování a správu postavený přímo na blockchainu Algorand. Decentralizovaná rozhodnutí umožňují organizacím přijímat rozhodnutí o správě a řízení otevřeným a decentralizovaným způsobem.

V tomto tutoriálu vytvoříme decentralizovanou hlasovací aplikaci s javascriptem algorand sdk pomocí NodeJs

Požadavky

  • Nástroje NPM a Node nainstalované, stáhněte si ZDE
  • Klíč Purestake API:Viz výukový program
  • Financované účty Testnet:viz výukový program

1. Nastavte složku projektu a nainstalujte algosdk

Vytvořte nový projekt složku, lze to provést v terminálu pomocí:

$ mkdir choice-coin-voting-app

Po vytvoření složky projektu zadejte adresář ve vašem terminálu

$ cd choice-coin-voting-app

Chcete-li nainstalovat závislosti do projektu, musíte spustit instance NPM pomocí:

$ npm init -y

Vytvořte nový soubor, já svůj pojmenuji index.js . To lze také provést v terminálu pomocí:

$ touch index.js

V terminálu nainstalujte npm jak AlgoSDK, tak Prompt-Sync

$ npm install algosdk prompt-sync

AlgoSDK je oficiální JavaScriptová knihovna pro komunikaci se sítí Algorand. Je navržen pro moderní prohlížeče a Node.js.
Modul Prompt-Sync je funkce, která vytváří funkce dotazování, to je totéž jako výzva prohlížeče, ale funguje to s prostředím NodeJs

V index.js importujte oba moduly

const algosdk = require('algosdk'); 
const prompt = require('prompt-sync')(); 

2. Nakonfigurujte rozhraní Purestake API a vytvořte klienta

Zaregistrujte se pro vývojářský účet Purestake a získejte svůj API klíč pro interakci se sítí algorand.

const server = "https://testnet-algorand.api.purestake.io/ps2";
const port = "";
const token = {
  "X-API-Key": "YOUR API KEY", 
};

Vytvořte proměnnou AlgodClient pro zahájení připojení

const algodClient = new algosdk.Algodv2(token, server, port)

3. Obnovte účet a zadejte ID aktiva vybrané mince

  • Vytvořte novou adresu peněženky testnet z myAlgoWallet nebo Algosigner, zkopírujte a uložte 25 mnemotechnické heslo a s nikým nesdílejte .
  • Najděte adresu peněženky pomocí několika testnetových algoritmů ZDE.
  • Přihlaste se k odběru $Choice Coin aktiva s ID 21364625 pomocí myAlgoWallet nebo Algosigner
  • Vyměňte testovací síť Algos za $choice na Tinymanovi.

V index.js


const mnemonic = "The mmemonic 25 characters seperated by a whitespace should be imported here"; 

const recoveredAccount = algosdk.mnemonicToSecretKey(mnemonic); 

const ASSET_ID = 21364625

const voting_address = "" 

V konstantě voting_address zadejte nově vytvořenou peněženku s hlasovací adresou odlišnou od té, která byla obnovena z $choice částku hlasů lze odeslat na adresu, ujistěte se, že je $choice přihlášen k přijímání hlasů stejně jako dříve

4. Výběr možnosti hlasování a odeslání hlasu

Vytvořte hlasovací funkci a odešlete hlasovanou částku z recoveredAccount na voting_address peněženku v závislosti na zvolené možnosti kandidáta.

const chooseVotingOption = async () => {
    const candidateOption = prompt("Press 0 for candidate Zero or Press 1 for candidate One:") 

     const amount = prompt("Please enter Amount to commit to voting:");


    const params =  await algodClient.getTransactionParams().do()
    const encoder = new TextEncoder()

     if (!(candidateOption)) {
         console.log('Please select a valid candidate option');
     } else if (!Number(amount)) {
         console.log("Please Enter A valid Choice token amount to vote")
     }
      else  if (candidateOption == "0") {
            try {
                let txn = algosdk.makeAssetTransferTxnWithSuggestedParams(
                    recoveredAccount.addr,
                    voting_address,
                    undefined,
                    undefined,
                    Number(amount),
                    encoder.encode("Voting with Choice coin"),
                    ASSET_ID,
                    params

                )

        let signedTxn = txn.signTxn(recoveredAccount.sk);
        const response =  await algodClient.sendRawTransaction(signedTxn).do();
            if(response) {
              console.log(`You just voted for candidate Zero,Your voting ID: ${response.txId}`);

                waitForConfirmation(algodClient, response.txId);
            } else {
                console.log('error voting for candidate Zero, try again later')
            }

        }
        catch(error) {
            console.log("error voting for candidate Zero, Try again later");
        }

 } 


     else  if(candidateOption == "1"){
        try {
            let txn = algosdk.makeAssetTransferTxnWithSuggestedParams(
                recoveredAccount.addr,
                voting_address,
                undefined,
                undefined,
                Number(amount),
                encoder.encode("Voting with Choice coin"),
                ASSET_ID,
                params
            )
       let signedTxn = txn.signTxn(recoveredAccount.sk);
       const response =  await algodClient.sendRawTransaction(signedTxn).do();
            if(response) {
               console.log(`You just voted for candidate One,Your voting ID: ${response.txId}`);

                waitForConfirmation(algodClient, response.txId);
            } else {
               console.log('error voting for candidate one, try again later')
            }

        }
        catch(error) {
            console.log("Error voting for candidate One, Try again later");
        }

        }
        }

5. Počkejte na potvrzení pro synchronizaci hlasování z Algorand Blockchain

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) {
          //Got the completed Transaction
          console.log('Voting confirmed in round ' + pendingInfo['confirmed-round']);
          break;
        }
        lastround++;
        await algodClient.statusAfterBlock(lastround).do();
     }
 };

Tato funkce ověřuje, kdy je hlasování potvrzeno ze sítě algorand.

6. Po hlasování zkontrolujte zůstatek $Choice

const checkBalance = async () => {

  //get the account information
    const accountInfo =  await algodClient.accountInformation(recoveredAccount.addr).do();
    const assets =  accountInfo["assets"];

    //get choice amount from assets
     assets.map(asset => {
        if (asset['asset-id'] === ASSET_ID) {
            const amount = asset["amount"];
            const choiceAmount = amount / 100;
            console.log(
                `Account ${recoveredAccount.addr} has ${choiceAmount} $choice`
              );
              return;
        }  else {
            console.log(`Account ${recoveredAccount.addr} must opt in to Choice Coin Asset ID ${ASSET_ID}`);
          }
     })

  };

Zkontrolujte zůstatek $Choice po skončení hlasování, pokud v informacích o účtu není uvedeno žádné ID aktiva výběru. funkce se zastaví pomocí return a console zobrazí se zpráva pro přidání vybraného ID aktiva do účtu

7. Spusťte celý kód

index.js by vypadalo.

const algosdk = require('algosdk'); //importing algosdk
const prompt = require('prompt-sync')(); //importing nodeJs  prompt to enable prompt in a nodeJs environment

// open a purestaker api and get a unique API KEY
const server = "https://testnet-algorand.api.purestake.io/ps2";
const port = "";
const token = {
  "X-API-Key": "" //your API key gotten from purestake API, 
};
const algodClient = new algosdk.Algodv2(token, server, port); //connecting to algodclient

// create a testnet account with myalgowallet, keep the mmemonic key;
const mnemonic = "The mmemonic 25 characters seperated by a whitespace should be imported here";

// get account from mmemonic key;
const recoveredAccount = algosdk.mnemonicToSecretKey(mnemonic); 

//choice coin asset ID 
const ASSET_ID = 21364625

// voting address
const voting_address = "" //input a voting address wallet you can send choice to, make sure choice is opt-in to receive votes

//Press 1 to vote for candidate one and 0 to vote for candidate Zero

const chooseVotingOption = async () => {
    const candidateOption = prompt("Press 0 for candidate Zero or Press 1 for candidate One:") 
     const amount = prompt("Please enter Amount to commit to voting:");


    const params =  await algodClient.getTransactionParams().do(); //get params
    const encoder = new TextEncoder();  //message encoder

    // if there is no valid option 
     if (!(candidateOption)) {
         console.log('Please select a valid candidate option');
     } else if (!Number(amount)) {
         console.log("Please Enter A valid Choice token amount to vote")
     }
     // if your option is candidate zero
      else  if (candidateOption == "0") {
            try {
                let txn = algosdk.makeAssetTransferTxnWithSuggestedParams(
                    recoveredAccount.addr,
                    voting_address,
                    undefined,
                    undefined,
                    Number(amount),
                    encoder.encode("Voting with Choice coin"),
                    ASSET_ID,
                    params

                )

            let signedTxn = txn.signTxn(recoveredAccount.sk);
            const response =  await algodClient.sendRawTransaction(signedTxn).do();
            if(response) {
                console.log(`You just voted for candidate Zero,Your voting ID: ${response.txId}`);
                // wait for confirmation
                waitForConfirmation(algodClient, response.txId);
            } else {
                console.log('error voting for candidate Zero, try again later')
            }

        }
        catch(error) {
            console.log("error voting for candidate Zero, Try again later");
        }

 } 
 // if your option is candidate one

 else  if(candidateOption == "1"){
    try {
        let txn = algosdk.makeAssetTransferTxnWithSuggestedParams(
            recoveredAccount.addr,
            voting_address,
            undefined,
            undefined,
            Number(amount),
            encoder.encode("Voting with Choice coin"),
            ASSET_ID,
            params
        )
        let signedTxn = txn.signTxn(recoveredAccount.sk);
        const response =  await algodClient.sendRawTransaction(signedTxn).do();
        if(response) {
            console.log(`You just voted for candidate One,Your voting ID: ${response.txId}`);
            // wait for confirmation
            waitForConfirmation(algodClient, response.txId);
        } else {
            console.log('error voting for candidate one, try again later')
        }

    }
    catch(error) {
        console.log("Error voting for candidate One, Try again later");
    }

    }
    }

chooseVotingOption();

//verification function
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) {
          //Got the completed Transaction
          console.log('Voting confirmed in round ' + pendingInfo['confirmed-round']);
          break;
        }
        lastround++;
        await algodClient.statusAfterBlock(lastround).do();
     }
 };


// check account balance
const checkBalance = async () => {


  //get the account information
    const accountInfo =  await algodClient.accountInformation(recoveredAccount.addr).do();
    const assets =  accountInfo["assets"];

    //get choice amount from assets
     assets.map(asset => {
        if (asset['asset-id'] === ASSET_ID) {
            const amount = asset["amount"];
            const choiceAmount = amount / 100;
            console.log(
                `Account ${recoveredAccount.addr} has ${choiceAmount} $choice`
              );
              return;
        }  else {
            console.log(`Account ${recoveredAccount.addr} must opt in to Choice Coin Asset ID ${ASSET_ID}`);
          }
     })

  };

checkBalance();

Na závěr jsme vytvořili hlasovací aplikaci s volbou coin a JavaScript algorand SDK pomocí NodeJS. Celý kód můžete zkontrolovat na Github