値型を使う
uint256は0以上の整数、int256は負数も扱う整数、boolは真偽値、addressは20バイトのアドレスです。金額を小数で保存せず、最小単位で整数として扱う設計が基本です。
値型の例SOLIDITY
contract TypesExample {
uint256 public points;
bool public active = true;
address public creator;
constructor() {
creator = msg.sender;
}
function addPoints(uint256 amount) external {
points += amount;
}
}実行結果OUTPUT
デプロイ後 points: 0
addPoints(25) 後 points: 25
active: true配列とmapping
配列は順番を持つ値の集合、mappingはキーから値を引く辞書です。mappingはキーの一覧を自動で持たないため、一覧が必要なら別の配列にキーを記録します。
参加者を記録するSOLIDITY
contract Registry {
address[] public members;
mapping(address => bool) public registered;
function join() external {
if (!registered[msg.sender]) {
registered[msg.sender] = true;
members.push(msg.sender);
}
}
function memberCount() external view returns (uint256) {
return members.length;
}
}実行結果OUTPUT
Account 0でjoin() → memberCount(): 1
Account 0で再度join() → memberCount(): 1
Account 1でjoin() → memberCount(): 2同じアカウントで何度もjoinしても、ifで重複を防ぎます。複数アカウントに切り替えるとmembersの件数が増えます。
structとenum
状態をまとめるSOLIDITY
contract TaskBoard {
enum Status { Todo, Done }
struct Task {
string title;
Status status;
}
Task[] public tasks;
function add(string calldata title) external {
tasks.push(Task(title, Status.Todo));
}
function finish(uint256 index) external {
tasks[index].status = Status.Done;
}
}この例は
structとenumのデータ構造を説明するためのものです。誰でもfinishを呼べるため、実際のタスク管理では所有者や担当者の権限チェックを追加します。確認OUTPUT
add("Solidityを読む")
tasks(0) → title: "Solidityを読む", status: Todo
finish(0)
tasks(0) → status: Done条件分岐と整数計算
if、for、whileを使えますが、ブロックチェーンではループ回数を増やしすぎるとガス不足になります。0.8系では整数のオーバーフロー・アンダーフローが標準で検出され、条件に合わない計算はrevertします。
合格判定SOLIDITY
function result(uint256 score) external pure returns (string memory) {
if (score >= 80) return "A";
if (score >= 60) return "B";
return "C";
}実行結果OUTPUT
result(92) → "A"
result(65) → "B"
result(40) → "C"練習
mapping(address => uint256)で各アカウントの点数を保存し、合計人数を別の変数で管理してみましょう。次はコントラクトと状態です。