Повечето пъти, когато хората започват да се учат как да пишат интелигентни договори, първото нещо, за което чуват, е Solidity и Ethereum. Това беше и първото нещо, за което чух. Това е, върху което се фокусират повечето уроци и има основателна причина. Solidity направи възможно писането на програми, които живеят на блокчейн, и Ethereum стана мястото, където много хора започнаха.
Но Solidity не е единственият език за интелигентни договори. И Ethereum не е единственият блокчейн, който поддържа децентрализирани приложения.
Има и TON , съкращение от The Open Network . Създадена е от Telegram, но сега е публична верига, управлявана от общността. Той е бърз, лек и се справя с нещата малко по-различно от това, с което може да сте свикнали в Ethereum. Това включва как се пишат интелигентните договори. Когато започнах да проучвам документацията на TON, попаднах на четири различни езика за писане на интелигентни договори: Tact, Tolk, FunC и Fift . Тук няма да навлизам дълбоко в четирите.
Това ръководство се фокусира върху езика Tact и ще видим как да го използваме, за да създадем основен договор за гласуване, който позволява на потребителите да гласуват и да проверяват резултатите във веригата.
Екосистемата TON всъщност поддържа множество езици, всеки от които обслужва различни случаи на употреба, нива на абстракция и опит на разработчиците. Ето кратък преглед на всеки от тях:
Tact осигурява по-бърз път за изграждане и внедряване на договори в блокчейна TON.
Преди да започнем да пишем код, е важно да разберем как са структурирани интелигентните договори на Tact. Типичният договор на Tact включва няколко основни компонента:
блок contract
– Това е мястото, където дефинирате името на вашия договор и декларирате всички променливи на състоянието.
init
block – Той инициализира променливите на състоянието на вашия договор и задава началните условия на договора. Този блок се изпълнява веднъж по време на внедряването.
receive
блокове – Те са като слушатели на събития. Те обработват входящите съобщения и определят как вашият договор реагира на тях.
Getter функции ( get fun
) – Това са незадължителни функции само за четене, които позволяват на потребители или други договори да правят заявки за състоянието на договора, без да го променят.
Tact използва комуникация, базирана на съобщения, така работят всички взаимодействия на TON. Всеки договор получава съобщение и го обработва в собствен блок receive
. Тази базирана на съобщения структура помага да организирате договорната си логика по модулен, поддържаем начин.
Нека сега приложим това в реален пример, като изградим прост договор за гласуване.
В този раздел ще разгледаме как да внедрим основна система за гласуване с помощта на Tact. Този договор за гласуване ще позволи на потребителите да гласуват за предварително определени кандидати и ще проследява общия брой гласове, които всеки кандидат получава.
Ние ще правим всичко в TON Web IDE, което е инструмент в браузъра, където можете да пишете, създавате и тествате своите договори, без да инсталирате нищо локално.
VotingContract
.
След като създадете вашия проект, отворете файла main.tact
. Ще видите шаблонна настройка:
// Import the Deployable trait so the contract can be deployed easily import "@stdlib/deploy"; contract BlankContract with Deployable { init() { } }
import "@stdlib/deploy";
се изисква, за да работи внедряването и не трябва да се премахва от кода.BlankContract
е името на контейнера.init()
се изпълнява само веднъж, когато договорът е разгърнат и се използва за инициализиране на променливи на състоянието.
Сега нека начертаем нашия собствен код.
Първо ще дефинираме структурата на съобщението за гласуване:
// Import the Deployable trait so the contract can be deployed easily import "@stdlib/deploy"; // Define a message structure for voting message Vote { candidate: Int as uint32; // 1 = Alice, 2 = Bob }
Това е съобщението за гласуване. Когато някой иска да гласува, той ще изпрати съобщение до договора, което включва номер:
Tact използва тази структура, за да обработи входящия вот и да реши кой кандидат получава точката.
След това ще настроим нашия договор и ще добавим две променливи на състоянието, за да следим гласовете на всеки кандидат:
... contract VotingContract with Deployable { // State variables to track votes votesAlice: Int as uint32; votesBob: Int as uint32;
В договора дефинирахме две променливи:
votesAlice
: съхранява броя на гласовете, които Алис получава.votesBob
: съхранява броя на гласовете, които Боб получава.
Сега ще инициализираме тези преброявания на гласове до нула в блока init
, за да зададем началното състояние на договора, когато бъде разгърнат за първи път.
init() { self.votesAlice = 0; self.votesBob = 0; }
Блокът init
се изпълнява само веднъж , точно когато договорът е разгърнат, и задава двата броя гласове на нула.
Сега идва логиката. Когато се изпрати глас, искаме договорът да провери за кого е гласът и да увеличи правилния брой гласове.
// Handle vote messages receive(msg: Vote) { if (msg.candidate == 1) { self.votesAlice += 1; } else if (msg.candidate == 2) { self.votesBob += 1; } }
Така че, когато се получи глас:
msg.candidate
е 1, добавяме +1 към votesAlice
msg.candidate
е 2, добавяме +1 към votesBob
И накрая, ще създадем функции за получаване, за да позволим на всеки да направи заявка за броя на гласовете за всеки кандидат, без да променя състоянието на договора.
// Getter for Alice's votes get fun getVotesForAlice(): Int { return self.votesAlice; } // Getter for Bob's votes get fun getVotesForBob(): Int { return self.votesBob; } }
Тези две функции за получаване ни позволяват да проверим броя на гласовете, които всеки кандидат е получил, без да променяме нищо в договора. Това е операция само за четене.
По-долу е пълният код на договора за гласуване:
import "@stdlib/deploy"; // Define a message structure for voting message Vote { candidate: Int as uint32; // 1 = Alice, 2 = Bob } contract VotingContract with Deployable { // State variables to track votes votesAlice: Int as uint32; votesBob: Int as uint32; init() { self.votesAlice = 0; self.votesBob = 0; } // Handle vote messages receive(msg: Vote) { if (msg.candidate == 1) { self.votesAlice += 1; } else if (msg.candidate == 2) { self.votesBob += 1; } } // Getter for Alice's votes get fun getVotesForAlice(): Int { return self.votesAlice; } // Getter for Bob's votes get fun getVotesForBob(): Int { return self.votesBob; } }
След като бъде внедрен, превъртете надолу и ще видите два раздела:
getVotesForAlice
, getVotesForBob
Vote
За да гласувате: В секцията Гласуване въведете 1
в полето за въвеждане candidate
и щракнете върху Изпрати. Вие току-що гласувахте за Алис! Можете да повторите това, за да дадете повече гласове.
За да проверите броя на гласовете : Щракнете върху Обаждане под getVotesForAlice
и проверете панела с регистрационни файлове , за да видите броя на гласовете
2
в полето candidate
, след което маркирайте getVotesForBob
В моето тестово изпълнение гласувах за Алис 9 пъти и Боб 6 пъти и функциите за получаване показаха точно това.
🙌 Поздравления, ако сте прочели докрай!
Сега, след като видяхте как работи прост договор за гласуване в Tact, вие направихте първата си стъпка в разработването на интелигентни договори на TON. Този договор може да е основен, но структурата и концепциите се отнасят и за по-сложна логика.
Ако искате да продължите да експериментирате, опитайте да удължите този договор или проучете други предварително изградени шаблони от https://tact-by-example.org/all . TON Web IDE също улеснява изпробването на различни случаи на употреба и идва с шаблони, за да ви помогне да изграждате и учите по-бързо.
Така че давайте, настройвайте, тествайте, изградете нещо по-добро.