多くの場合、スマート コントラクトの書き方を学び始めると、最初に耳にするのは Solidity と Ethereum です。私も最初に耳にしたのはこれです。ほとんどのチュートリアルではこれらに焦点を当てていますが、それには十分な理由があります。Solidity により、ブロックチェーン上で動作するプログラムの作成が可能になり、Ethereum は多くの人が始める場所になりました。
しかし、Solidity は唯一のスマート コントラクト言語ではありません。また、分散型アプリケーションをサポートするブロックチェーンは Ethereum だけではありません。
また、 The Open Networkの略称であるTONもあります。これは Telegram によって作成されましたが、現在はパブリックのコミュニティ主導のチェーンになっています。高速で軽量で、Ethereum で慣れ親しんでいるものとは少し異なる方法で処理します。これには、スマート コントラクトの記述方法も含まれます。TON のドキュメントを調べ始めたとき、スマート コントラクトを記述するための 4 つの異なる言語、 Tact、Tolk、FunC、および Fiftに出会いました。ここでは 4 つすべてについて詳しく説明しません。
このガイドでは、Tact 言語に焦点を当て、ユーザーが投票し、チェーン上で結果を確認できる基本的な投票契約を Tact 言語を使用して構築する方法を説明します。
TON エコシステムは実際には複数の言語をサポートしており、それぞれが異なるユースケース、抽象化レベル、開発者エクスペリエンスを提供します。以下に、それぞれの概要を示します。
Tact は、TON ブロックチェーン上で契約を構築および展開するためのより迅速なパスを提供します。
コードを書き始める前に、Tact スマート コントラクトの構造を理解することが重要です。一般的な Tact コントラクトには、いくつかのコア コンポーネントが含まれています。
contract
ブロック – ここでコントラクトの名前を定義し、状態変数を宣言します。
init
ブロック – コントラクトの状態変数を初期化し、コントラクトの開始条件を設定します。このブロックは、デプロイメント時に 1 回実行されます。
receive
ブロック – イベント リスナーのようなものです。受信メッセージを処理し、コントラクトがそれにどのように反応するかを定義します。
ゲッター関数 ( 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()
ブロックは、コントラクトがデプロイされたときに 1 回だけ実行され、状態変数を初期化するために使用されます。
それでは、独自のコードをマッピングしてみましょう。
まず、投票用のメッセージ構造を定義します。
// 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 はこの構造を使用して、受信した投票を処理し、どの候補者がポイントを獲得するかを決定します。
次に、契約を設定し、各候補者の投票を追跡するための 2 つの状態変数を追加します。
... contract VotingContract with Deployable { // State variables to track votes votesAlice: Int as uint32; votesBob: Int as uint32;
契約内で、2 つの変数を定義しました。
votesAlice
: Alice が受け取った投票数を格納します。votesBob
: Bob が受け取った投票数を格納します。
ここで、 init
ブロック内でこれらの投票数をゼロに初期化し、契約が最初にデプロイされたときの開始状態を設定します。
init() { self.votesAlice = 0; self.votesBob = 0; }
init
ブロックは、コントラクトがデプロイされたときに 1 回だけ実行され、両方の投票カウントをゼロに設定します。
ここでロジックが登場します。投票が送信されると、コントラクトで誰に対する投票かを確認し、正しい投票数を増やすようにします。
// Handle vote messages receive(msg: Vote) { if (msg.candidate == 1) { self.votesAlice += 1; } else if (msg.candidate == 2) { self.votesBob += 1; } }
したがって、投票が受け取られると、次のようになります。
msg.candidate
が1の場合、 votesAlice
に+1を追加します。msg.candidate
が2の場合、 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; } }
これら 2 つのゲッター関数を使用すると、契約内容を変更せずに各候補者が獲得した投票数を確認できます。これは読み取り専用の操作です。
以下は完全な投票契約コードです。
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; } }
デプロイしたら、下にスクロールすると 2 つのセクションが表示されます。
getVotesForAlice
、 getVotesForBob
Vote
投票するには:投票セクションで、 candidate
入力フィールドに1
入力し、 [送信] をクリックします。これで Alice に投票できました。これを繰り返してさらに投票することができます。
投票数を確認するには: getVotesForAlice
の下のCallをクリックし、ログパネルで投票数を確認します。
candidate
フィールドに2
送信し、 getVotesForBob
チェックします。 私のテスト実行では、Alice に9 回、Bob に6 回投票しましたが、ゲッター関数はまさにそれを示しました。
🙌 最後まで読んでくださった方、おめでとうございます!
シンプルな投票コントラクトが Tact でどのように機能するかを確認したので、TON でのスマート コントラクト開発への第一歩を踏み出しました。このコントラクトは基本的なものですが、その構造と概念はより複雑なロジックにも適用されます。
実験を続けたい場合は、この契約を拡張するか、 https://tact-by-example.org/allから他の事前構築済みテンプレートを調べてみてください。TON Web IDE を使用すると、さまざまなユースケースを簡単に試すことができ、構築と学習を迅速化するためのテンプレートも付属しています。
さあ、微調整し、テストし、より良いものを作りましょう。