Скочи на садржај

Први пројекат: Децентрализована апликација за гласање

Пут Солане почињемо децентрализованом апликацијом за гласање, која омогућава корисницима да ставе неку своју идеју, предлог или било шта друго на гласање. Сваки предлог има кратак опис, како би се корисницима образложио предлог о којем гласају. Уз то у позадини се обрађују гласови, за и против и чува податак о томе на блокчејну. Овај механзам гласања, иако је ова апликација поченичка, је применљив различите видове примена уз мање или више измена. Пример примене су апликације за групно финансирање, подршка одлучивању у компанијама, гласање за избор најбољих решења или одговора, избор нове функционалности неке апликације, избор најдуховитијег коментара…Уз кратак опис апликације која се пише, биће речи о основним деловима и макроима који су коришћени у самом програму, али и проблеме на које сам наишао током рада. Проблеми захтевају и неко решење тако да је и то део овог текста и надам се вама занимљиво и корисно 🙂

Зашто одабрати апликацију за гласање као свој први пројекат?

Покретање вашег првог пројекта у области децентрализованих апликација може бити застрашујући задатак, али избор апликације за гласање као почетне тачке у развој Солане нуди бројне предности. Апликације за гласање нису само практичне, већ имају и значајан значај у различитим организационим контекстима и оквирима управљања. Ангажовањем са овом врстом пројекта, програмери могу истражити критичне функционалности које истичу основне принципе децентрализације.

Једна од најважнијих предности апликације за гласање је њена демонстрација транспарентности. И у јавном и у приватном сектору, транспарентни процеси доношења одлука су неопходни за изградњу поверења. Децентрализована природа таквих апликација осигурава да се сви гласови евидентирају у јавној књизи, што чини готово немогућим манипулисање резултатима или измену записа накнадно. Ова карактеристика промовише поверење међу учесницима, постављајући темељ за демократске процесе.

Illustration of how blockchain works
Illustration of how blockchain works

Штавише, апликације за гласање обухватају принцип непроменљивости, који је кључан за блокчејн системе. Када се глас једном да и забележи, не може се променити или избрисати. Ова карактеристика не само да јача интегритет процеса гласања, већ је и у складу са растућом потражњом за системима који дају приоритет безбедности од преваре и корупције. Развојем апликације за гласање можете стећи искуство из прве руке у имплементацији ових битних карактеристика, које су применљиве на разне друге децентрализоване апликације.

Поред тога, рад на пројекту гласања вам омогућава да се удубите у важне техничке аспекте блокчејн технологије, као што су паметни уговори и механизми за аутентификацију корисника. Поред непосредних техничких користи, креирање апликације за гласање такође може пружити непроцењиве увиде у динамику управљања заједницом, омогућавајући вам да разумете како децентрализовани системи могу ефикасно функционисати у реалним сценаријима.

Стога, избор апликације за гласање за ваш почетни Солана пројекат значи да ћете стећи разноврстан скуп вештина које нису само релевантне данас, већ су све важније у обликовању будућих модела управљања.

Структура апликације и основни макрои Сидра

У претходном тексту је било речи о основним командама за креирање новог пројекта, тако да одмах прелазим на структуру саме апликације. Коришћењем create-solana-dapp команде, креира се комплетан костур апликације за бек и фронтенд. Радни оквир који је подразумеван је Сидро (енг. Anchor) и у директоријуму са истим именом је смештена датотека на којој ћемо радити под називом lib.rs. Она представља срж апликације и оно што се извршава у њој, ће бити приказивано на корисничком Веб интерфејсу. Остатак структуре пројекта је детаљно објашњен у документацији за Солану и Сидро и део је кампа за обуку уколико више волите да пратите видео материјал.

Основни макрои Сидра

Радни оквир Сидро користи Раст-ове макрое како би смањио писање шаблонског кода и поједноставио уобичајне безбедносне провере које су неопходне за писање Солана програма. Основни макрои Сидра су:

  1. declare_id: Који дефинише адресу програма на блокчејну; Адреса се аутоматски додељује по креирању апликације.

  2. #[program]: Модул који садржи логику инструкција програма; У суштини све јавне функције које можете користити у програму су смештене овде.

  3. #[derive(Accounts)]: Односи се на типове структура (struct) да би се назначила листа налога потребних инструкцији.

  4. #[account]: Односи се на типове структура за креирање прилагођених типова налога за програм.

Ови макрои су уско повезани, а њихову везу сликовито схватам овако: #[account] макро садржи тип структуре који је неопходан структури у макроу #[derive(Accounts)], док функција у макроу #[program] захтева постојање стуктуре у #[derive(Accounts)] макроу.

Ethereum vs Solana
Ethereum vs Solana

Изазови, решења и добра пракса из прве апликације

На почетку овог текста сам већ навео неке основне функционалности које нудио ова децентрализована апликација. Међутим, иако једноставна, стварала је мале главобоље. Као новајлији на Солани и скромним познавањем Раст-а требало је мало времена за навикавање на синтаксу и окружење. Па да видимо како је то изгледало.

Грешка #1: Exceeded timeout of 5000 ms for a test

Иако на последњој верзији Солане, Сидра и пратећих зависности, при покретању теста долазило је појаве до грешке „Exceeded timeout of 5000 ms for a test“. Тест је пуцао након истека тог временског интервала од 5 секунди. На Солана Стак Ексчејнџу можете наћи објаву.

Оно што су ми други одговорили а што се генерално сматра добром праксом је да сав код који се користи у више тестова треба сместити у beforeAll функцију. Извршиће се само једанпут и скратити време извршавања, код изгледа прегледније.

Ову грешку нисам успео да решим, па сам пројекат почео из почетка 🙂

Мој код:

import { BankrunProvider, startAnchor } from "anchor-bankrun";
import * as anchor from '@coral-xyz/anchor'
import { BN, Program } from '@coral-xyz/anchor'
import { Keypair, PublicKey } from '@solana/web3.js'
import { Votingdapp2 } from '../target/types/votingdapp2'

const IDL = require('../target/idl/votingdapp2.json');

const votingAddress = new PublicKey("coUnmi3oBUtwtd9fjeAvSsJssXh5A5xyPbhpewyzRVF");

describe('Voting', () => {

it('Initialize Poll', async () => {
//const signer = Keypair.generate();

const context = await startAnchor("", [{ name: "voting", programId: votingAddress }], []);

const provider = new BankrunProvider(context);

const votingProgram = new Program<Votingdapp2>(
IDL,
provider,
);

await votingProgram.methods.initializePoll(
new anchor.BN(1),
"What is your favourite type of peanut butter",
new anchor.BN(0),
new anchor.BN(1821246480),
).rpc();

const [pollAddress] = PublicKey.findProgramAddressSync([new anchor.BN(1).toArrayLike(Buffer, 'le', 8)], votingAddress);

const poll = await votingProgram.account.poll.fetch(pollAddress);
console.log(poll);

})

});

Код након примењених препорука:

import { BankrunProvider, startAnchor } from "anchor-bankrun";
import * as anchor from '@coral-xyz/anchor'
import { Program } from '@coral-xyz/anchor'
import { Keypair, PublicKey } from '@solana/web3.js'
import { Voting } from '../target/types/voting'

const IDL = require('../target/idl/voting.json');

const votingAddress = new PublicKey("FqzkXZdwYjurnUKetJCAvaUw5WAqbwzU6gZEwydeEfqS");

describe('Voting', () => {
// Configure the client to use the local cluster.
let context;
let provider;
let votingProgram: Program;

beforeAll(async () => {
context = await startAnchor("", [{name: "voting", programId: votingAddress}], []);
provider = new BankrunProvider(context);

votingProgram = new Program<Voting>(
IDL,
provider,
);

})

it('Initialize Poll', async () => {

await votingProgram.methods.initializePoll(

new anchor.BN(1),

"What is your favorite type of peanut butter?",

new anchor.BN(0),

new anchor.BN(1847955695),

).rpc();

const [pollAddress] = PublicKey.findProgramAddressSync(

[new anchor.BN(1).toArrayLike(Buffer, 'le', 8)],

votingAddress,

)

const poll = await votingProgram.account.poll.fetch(pollAddress);

console.log(poll);

})

})

Грешка 2: Argument of type ‘BankrunProvider’ is not assignable to parameter of type ‘Provider’

Ова грешка јавила се у самом фајлу паметног уговора, више о њој можете видети на објави на Солана Стак Ексчејнџу. Као неко привремено решење користио сам потискивање грешака додавањем //@ts-ignore директиву испред реда где је грешка настала. Коначно решење за ову и претходну грешку видећемо у наставку.

Грешка 3: File not found: No such file or directory (os error 2)

Око ове грешке сам провео највише времена покушавајући да је решим, јер нисам желео да одустанем! 🙂 Више о њој. Убедљиво највише ме је збуњивала јер нисам знао где тачно у самом пројекту да тражим шта сам омашио. Датотека паметног уговора је изгледала исто као и код предавача на курсу, тест такође.

Решење за ове грешке и проблеме

Због некомпатибилности web3.js библиотеке са Сидром због конфигурације коју сам одабрао током креирања пројекта долазило је до појаве све три горе наведене грешке. Једноставно се решило све само од себе када сам при креирању пројекта одабрао web3js-next-tailwind-counter што представља старији начин креирања пројеката управо због компатибилности Сидра и web3.js библиотеке. Друга ствар коју нисам урадио је npm install за довлачење потребних зависности. Мислио сам да се то аутоматски одвија приликом креирања пројекта, међутим знајте да није 😉 Последња ствар која је правила проблем и доводила до ове треће грешке је што назив Counter треба да се замени са Votе свуда у конфигурационим датотекама пројекта. Промекло ми је да то урадим у једној датотеци и ето проблема. Ето мало да се похвалим, пожалим и надам се помогнем неком да не разбија главу овим почетничким грешкама 🙂 Сад идемо даље!

Оставите одговор

Ваша адреса е-поште неће бити објављена. Неопходна поља су означена *

eight − two =