SolidityとEthereum
Solidityは、Ethereum Virtual Machine(EVM)上で動くスマートコントラクトを書くための、静的型付きの高水準言語です。コントラクトはコードと状態データの組み合わせで、ブロックチェーン上のアドレスに配置されます。
- 読み取り:
viewなどで状態を読む。通常はトランザクションを作らず、ガスを消費しない。 - 書き込み:状態を変更する。署名付きトランザクションとガスが必要。
- デプロイ:コントラクトを新しいアドレスへ作成する特別なトランザクション。
コントラクトは公開され、デプロイ後の処理は原則として取り消せません。学習中はRemix VMを使い、秘密鍵や本物のEtherを入力しないでください。
最初のコントラクト
Remix IDEを開き、SimpleStorage.solを作成します。コンパイラーで0.8系を選び、Deploy & Run Transactionsの環境をRemix VMにすると、ブラウザだけで実行できます。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SimpleStorage {
uint256 private storedNumber;
function set(uint256 newNumber) external {
storedNumber = newNumber;
}
function get() external view returns (uint256) {
return storedNumber;
}
}Deploy → get → 0
set に 42 を入力して実行 → get → 42setは状態を変更するためトランザクションになり、getは値を読むだけです。Remixのログとボタンの表示で違いを確認してください。
言語の基礎
Solidityでは、変数の型、可視性、関数の状態変更可否をコード上で明示します。JavaScriptと似た記号が登場しますが、整数の扱い、アドレス、ブロックチェーン固有の値に注意が必要です。
contract ScoreBoard {
uint256 public score;
bool public passed;
function judge(uint256 value) external {
score = value;
passed = value >= 60;
}
}judge(75) → score: 75 / passed: true
judge(40) → score: 40 / passed: falsepublicな状態変数には値を読むgetterが用意されます。ただし、配列やmappingの全要素を自動で一覧できるわけではありません。
状態と関数
スマートコントラクトの設計では、「誰が」「どの状態を」「どの条件で」変更できるかを決めます。msg.senderは現在の呼び出し元、addressはアカウントやコントラクトのアドレスです。
contract Counter {
address public owner;
uint256 public count;
constructor() {
owner = msg.sender;
}
function increment() external {
require(msg.sender == owner, "owner only");
count += 1;
}
}Account 0でincrement() → count: 1
Account 1でincrement() → revert "owner only"Remixでアカウントを切り替え、所有者以外でincrementを実行してみます。条件に合わない呼び出しはrevertし、状態変更は残りません。
安全性を最初から考える
スマートコントラクトは公開され、攻撃者もコードを読めます。入力値、権限、Etherの送金、外部コントラクト呼び出し、再入可能性などを、機能実装と同時に検討します。
コンパイルできることと、安全であることは別です。テスト、レビュー、静的解析、監査を行い、秘密鍵をソースコードやブラウザへ貼り付けないでください。
詳細は安全なコントラクト設計で、Checks-Effects-Interactions、pull payment、整数計算、アクセス制御を実例で確認します。
練習と次の一歩
まずはSolidity練習問題で、状態変数、mapping、イベント、権限、送金の設計を自分で書いてみましょう。その後、ABIを使ったフロントエンド連携、OpenZeppelin Contracts、HardhatやFoundryによるテストへ進みます。