Algorand Günlüğüm(10/10)

Enes POLAT
Turk Telekom Bulut Teknolojileri
5 min readOct 4, 2022

10 bölümden oluşan Algorand günlüğüm serisinde JavaScript diliyle Algorand blokzincirinde uygulama geliştirmeye öğrenmeye devam ediyoruz.

Daha önceki birinci bölüm, ikinci bölüm, üçüncü bölüm, dördüncü bölüm, beşinci bölüm, altıncı bölüm, yedinci bölüm, sekizinci bölüm ve dokuzuncu bölümü okumadıysanız linklerden erişebilirsiniz.

Kaynak: https://yoyodex.io/algorand-yukselis-trendini-surdurmek-icin-temel-destegin-uzerinde-kalmali/?amp=1

Merkezi Olmayan Seçim Sistemi Yapma

Bu yazımızda node.js üzerinden Algorand blokzincirinde çalışan merkezi olmayan bir oylama sistemi yapacağız. Dilerseniz hemen başlayalım.

Öncelikli olarak seçim sistemi için yeni bir klasör oluşturalım ve klasör içine geçiş yapalım:

$ mkdir choice-coin-voting-app
cd choice-coin-voting-app

Node projesi hazırlayalım:

$ npm init -y

index.js isminde bir dosya oluşturalım

$ touch index.js

algosdk ve node.js üzerinde kullanıcıdan bilgi almamızı sağlayanprompt-sync i kuralım

npm install algosdk prompt-sync

index.js dosyasında her iki modülü de çağıralım

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

purestake developer hesap bilgimizle algorand blokzincirine tünelleme yapalım:

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

Yukarıdaki bilgiler ışığında blokzincire bağlanalım:

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

Daha önce oluşturduğumuz bir hesap mnemonic bilgileriyle $Choice Coin tokenına opt-in ederek ID 21364625 sürece devam edelim. Bu token için https://testnet.tinyman.org/#/swap?asset_in=0&asset_out=21364625 sayfasına girerek hesabımızın bir kısım Algo meblağını Choice Coine swap edelim. Bu token sayesinde seçim yapacağız. Ayrıca ikinci bir hesabıda seçim işlemi için açalım. Benim açtığım hesap ZBGKZ6PXBLUENEGHKSEDN74D4BUCYQUH3GMOEEXLDSIVRKIHBUMMMECHQM olarak devam ettim. Bu hesaba da Choin Coin için 21364625 ID’si üzerinden opt-in ettim.

const mnemonic = "ostrich age when globe wing scene ranch stick argue vibrant protect perfect pill silent spoon wisdom convince mystery infant middle roof screen stamp abstract entry"; 

const recoveredAccount = algosdk.mnemonicToSecretKey(mnemonic);

const ASSET_ID = 21364625

const voting_address = "ZBGKZ6PXBLUENEGHKSEDN74D4BUCYQUH3GMOEEXLDSIVRKIHBUMMMECHQM"

Şimdi bir oylama fonksiyonu oluşturalım ve oylanan kişiye bağlı gönderilecek balance tutarını voting_adresine gönderen bir işlevsellik katalım.

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");
}

}
}

Algorand blokzincirinden oylamanın doğrulamasını bekleyen fonksiyonu yazalım:

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();
}
};

Oylamadan sonra havuzdaki balance değerini okuyan fonksiyonu yazalım

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}`);
}
})

};

Tüm index.js kodunu aşağıda paylaşıyorum

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

// open a Purestake 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",
};
const algodClient = new algosdk.Algodv2(token, server, port);

// 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

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

// Input 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();
const encoder = new TextEncoder();

// 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")
}
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");
}

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


// check account balance
const checkBalance = async () => {
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();

node index.js ile scripti çalıştırın ve her kullandığınız oya göre sonucu görün

Sonuç

Algorand blokzincirinde oylama sistemi yaptık.

Orjinal İngilizce buradan erişebilirsiniz.

--

--