本文へスキップ
BecomeCoder

Solidityコース · 第4章 制御・お金・安全性 ― require・payable・event · レッスン16

msg.sender と msg.value ― 「誰が・いくら」

ブラウザで完結

導入

コントラクトの関数を呼び出すとき、Solidity は「誰が呼んだか」「ETH をいくら添えたか」といった情報を自動で受け取ります。これらは msg という組み込み変数に入っています。

説明

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Context {
    address public lastCaller;
    uint256 public lastValue;

    // payable を付けた関数は ETH を受け取れる
    function ping() public payable {
        lastCaller = msg.sender;   // 呼び出した人のアドレス
        lastValue  = msg.value;    // 一緒に送られた ETH(wei単位)
    }
}
  • msg.sender … その関数を呼び出したアドレス。「本人確認」の基礎で、権限チェックに必須。
  • msg.value … 呼び出しに添えて送られた ETH の額(wei)。受け取るには関数に payable が必要。
  • ほかに block.timestamp(現在のブロックの時刻)、msg.data(呼び出しデータ)などもある。
sequenceDiagram
    participant U as 利用者 0xAb84...
    participant C as コントラクト
    U->>C: ping() を呼ぶ(0.5 ETH を添える)
    Note over C: msg.sender = 0xAb84...<br/>msg.value = 500000000000000000 wei
    C->>C: lastCaller と lastValue に記録

msg.sender は「ログインユーザー」に近い存在です。データベースセッションがなくても、呼び出しそのものに本人の署名が付いているので、コントラクトは「今誰が操作しているか」を常に確実に知ることができます。

やってみよう

msg.sender は偽装できません(正しい秘密鍵で署名されたトランザクションでしか、そのアドレスとして呼び出せない)。だから「所有者だけが実行できる関数」を msg.sender == owner のチェックだけで安全に作れます。次のレッスンでその形を学びます。

実際に動かしてみよう

下のエディタのコントラクトを「コンパイル & デプロイ」すると、ブラウザ内で本物のSolidityコンパイラ(solc)がコンパイルし、EVM(@ethereumjs)にデプロイされます。デプロイ後は public な関数がボタンになって並ぶので、引数を入れて呼び出すと戻り値・イベント・require のエラー(revert理由)まで確認できます。本文のコントラクトを書き換えて動きを試しながら進めましょう(コンパイラ本体は初回だけ読み込みに数秒かかります)。

Solidity — ブラウザ内でコンパイル & 実行

ブラウザ内で本物のSolidityコンパイラ(solc)とEVM(@ethereumjs)を動かす環境を読み込みます(コンパイラ本体は初回のコンパイル時に読み込むため、最初の実行だけ数秒かかります)。
スクロールして表示された時点でも自動で読み込まれます。