メインコンテンツへスキップ
Change page

スマートコントラクトの解剖学

スマートコントラクトは、イーサリアム上のアドレスで実行されるプログラムです。 それらはトランザクションの受信時に実行できるデータと関数で構成されています。 ここでは、スマートコントラクトの構成要素の概要を説明します。

前提条件

まず「スマートコントラクト」についてお読みください。 このドキュメントは、JavaScriptやPythonなどのプログラミング言語に精通していることを前提としています。

データ

すべてのコントラクトデータは、storageまたはmemoryのいずれかの場所に割り当てる必要があります。 スマートコントラクトのストレージの変更にはコストがかかりますので、データをどこに格納するかを考える必要があります。

EVMストレージ

永続データはストレージと呼ばれ、状態変数で表されます。 これらの値は、ブロックチェーンに永続的に保存されます。 コントラクトがコンパイル時に必要なブロックチェーンのストレージ容量を追跡できるように、型を宣言する必要があります。

// Solidityの例
contract SimpleStorage {
    uint storedData; // 状態変数
    // ...
}
# Vyperの例
storedData: int128

オブジェクト指向言語でのプログラミングの経験がある場合は、ほとんどの型になじみがあるでしょう。 しかし、イーサリアムの開発が初めての場合、addressは目新しいかもしれません。

address型は、20バイトまたは160ビットに相当するイーサリアムアドレスを保持できます。 先頭が0xの16進数を返します。

その他の型には次のものがあります。

  • ブール値
  • 整数
  • 固定小数点数
  • 固定サイズのバイト配列
  • 動的サイズのバイト配列
  • 有理数リテラルと整数リテラル
  • 文字列リテラル
  • 16進数リテラル
  • 列挙型

詳細については、以下のドキュメントをご覧ください。

メモリ

コントラクト関数の実行期間にのみ保存される値は、メモリ変数と呼ばれます。 これらはブロックチェーンに永続的に保存されることはないため、低コストで使用できます

EVMがどのようにデータを格納するか(ストレージ、メモリ、スタック)についての詳細は、Solidityドキュメント (opens in a new tab)を参照してください。

環境変数

コントラクトで定義した変数に加え、特別なグローバル変数がいくつかあります。 これらは主にブロックチェーンや現在のトランザクションに関する情報を提供するために使用されます。

例:

プロパティ状態変数説明
block.timestampuint256現在のブロックエポックタイムスタンプ
msg.senderaddressメッセージの送信者(現在の呼び出し)

関数

簡単に言うと、関数は受信トランザクションに応じて情報を取得したり、情報を設定したりすることができます。

関数呼び出しには、以下の2種類があります。

  • internal – これらはEVMコールを作成しません
    • Internal関数と状態変数は、内部(つまり、現在のコントラクトまたはそこから派生したコントラクト内)からのみアクセスできます。
  • external – これらはEVMコールを作成します
    • external関数はコントラクトインターフェイスの一部であり、他のコントラクトから呼び出したり、トランザクションを介して呼び出したりすることができます。 external関数fは内部では呼び出せません(つまり、f()は機能しませんが、this.f()は機能します)。

publicまたはprivateにすることもできます

  • public関数は、コントラクト内から内部的に呼び出すことも、メッセージを介して外部から呼び出すこともできます。
  • private関数は、それらが定義されたコントラクトからのみ参照でき、派生コントラクトからは参照できません。

関数と状態変数はどちらもpublicまたはprivateにすることができます。

コントラクトの状態変数を更新するための関数は次のとおりです。

// Solidityの例
function update_name(string value) public {
    dapp_name = value;
}
  • string型のvalueが、関数update_nameに渡されます。
  • publicと宣言されており、誰でもアクセスできます。
  • viewが宣言されていないため、コントラクトの状態を変更できます。

View関数

これらの関数によって、コントラクトのデータの状態を変更しないことを指定します。 一般的な例としては、「getter」関数があります。例えば、これを使用してユーザーの残高を受け取ることができます。

// Solidityの例
function balanceOf(address _owner) public view returns (uint256 _balance) {
    return ownerPizzaCount[_owner];
}
dappName: public(string)

@view
@public
def readName() -> string:
  return dappName

状態の変更と見なされるものは、以下のとおりです。

  1. 状態変数への書き込み。
  2. イベントの発行 (opens in a new tab)
  3. 他のコントラクトの作成 (opens in a new tab)
  4. selfdestructの使用。
  5. 呼び出しによるイーサ(ETH)の送信。
  6. viewまたはpureが指定されていない関数の呼び出し。
  7. 低レベル呼び出しの使用。
  8. 特定のオペコードを含むインラインアセンブリの使用。

コンストラクタ関数

constructor関数は、コントラクトが最初にデプロイされたときに1回だけ実行されます。 多くのクラスベースのプログラミング言語のconstructorと同様に、これらの関数はしばしば、指定された値に状態変数を初期化します。

# Vyperの例

@external
def __init__(_beneficiary: address, _bidding_time: uint256):
    self.beneficiary = _beneficiary
    self.auctionStart = block.timestamp
    self.auctionEnd = self.auctionStart + _bidding_time

組み込み関数

コントラクトで定義した変数と関数に加え、特別な組み込み関数がいくつかあります。 最もわかりやすい例は、以下のとおりです。

  • address.send() – Solidity
  • send(address) – Vyper

これらの関数により、コントラクトは他のアカウントにETHを送信することができます。

関数の記述

関数には以下のものが必要です。

  • パラメータ変数と型(パラメータを受け取る場合)
  • internal/externalの宣言
  • pure/view/payableの宣言
  • 戻り値の型(値を返す場合)

完全なコントラクトはこのようになります。 ここで、constructor関数は、dapp_name変数の初期値を提供します。

イベントとログ

イベントは、スマートコントラクトがフロントエンドや他のサブスクライブしているアプリケーションと通信することを可能にします。 トランザクションが検証されてブロックに追加されると、スマートコントラクトはイベントを発行し、情報をログに記録できます。これをフロントエンドが処理して活用します。

注釈付きの例

Solidityで書かれた例を以下に示します。 コードを試したい場合は、Remix (opens in a new tab)で操作できます。

Hello world

トークン

ユニークなデジタル資産

参考リンク

スマートコントラクトの全体的な概要については、SolidityとVyperのドキュメントをご確認ください。

ページの最終更新: 2026年4月15日

この記事は役に立ちましたか?