Solidity

Solidity練習問題

要件を読み、状態・権限・イベント・失敗条件を自分で設計してみましょう。

Solidity入門の講座一覧

01

問題1:カウンターを作る

誰でも呼べるincrement、所有者だけが0へ戻せるreset、現在値を返すcurrentを持つCounterを作ってください。

確認ポイント
  • ownerをconstructorで保存する
  • resetにアクセス制御を付ける
  • reset後の値が0であることを確認する
解答例SOLIDITY
contract Counter {
    address public owner;
    uint256 public count;

    constructor() { owner = msg.sender; }
    modifier onlyOwner() {
        require(msg.sender == owner, "owner only");
        _;
    }

    function increment() external { count += 1; }
    function reset() external onlyOwner { count = 0; }
    function current() external view returns (uint256) {
        return count;
    }
}
実行結果OUTPUT
increment() → count: 1
ownerでreset() → count: 0
owner以外でreset() → revert "owner only"
02

問題2:一人一票の投票

候補者名を配列に追加し、アドレスごとに投票済みかをmappingで記録してください。投票時には候補者番号を受け取り、範囲外ならrevertし、Votedイベントを発行します。

解答の中心部分SOLIDITY
mapping(address => bool) public voted;
uint256[] public votes;
event Voted(address indexed voter, uint256 indexed candidate);

function vote(uint256 candidate) external {
    require(!voted[msg.sender], "already voted");
    require(candidate < votes.length, "invalid candidate");
    voted[msg.sender] = true;
    votes[candidate] += 1;
    emit Voted(msg.sender, candidate);
}
実行結果OUTPUT
Account 0でvote(0) → votes[0]: 1
Account 0で再度vote(0) → revert "already voted"
Account 1でvote(1) → Votedイベント、votes[1]: 1

候補者の追加を誰でもできるのか、投票期間を設けるのかは別の要件です。仕様にない権限を勝手に追加せず、必要なら設計として明記します。

03

問題3:入金箱を設計する

Etherを受け取り、入金者の累計額を記録し、所有者だけが全額を引き出せるTipJarを作ってください。入金時にはイベントを出し、送金失敗時はrevertし、送金前に状態を更新します。

解答例は学習用

Etherを扱う本番コントラクトには、再入可能性、ガス制限、権限管理、緊急停止、監査など追加の検討が必要です。

最小の骨格SOLIDITY
mapping(address => uint256) public deposited;
event Deposited(address indexed from, uint256 amount);

function deposit() external payable {
    require(msg.value > 0, "zero value");
    deposited[msg.sender] += msg.value;
    emit Deposited(msg.sender, msg.value);
}
実行結果OUTPUT
Account 0でdeposit(0.1 ether) → deposited[Account 0]: 0.1 ether
Depositedイベント → from: Account 0, amount: 0.1 ether
04

振り返り

各問題を解くときは、コードを書く前に「状態」「権限」「成功条件」「失敗条件」「外部へ知らせるイベント」を表にします。次の発展テーマは、OpenZeppelinの既存実装、ERC-20/ERC-721、フロントエンドとのABI連携、HardhatやFoundryの自動テストです。