【Solidity】第3章第7回:支払い可能関数(payable)の基本

本記事では、Solidityにおける支払い可能関数(payable)の基本について解説します。支払い可能関数を正しく理解し使用することで、ETHの送受信が可能なスマートコントラクトを構築できます。
0. 記事の概要
この記事を読むメリット
- payable関数の基礎を理解:ETHを扱うスマートコントラクトを構築する方法を学べます。
- セキュリティ向上:ETHの送金や受け取りを安全に行う方法を習得します。
- 実践的な知識の獲得:payableを活用した応用的なスマートコントラクト設計が可能になります。
この記事で学べること
- 支払い可能関数の定義方法
- ETHの送受信の実装
- よくあるエラーとその解決策
1. 支払い可能関数(payable)とは?

1.1 payableの役割
支払い可能関数(payable)は、ETHをコントラクトに送信するための特別な関数です。この修飾子を持つ関数が定義されている場合のみ、ETHを受け取ることができます。
1.2 payableの基本構文
以下は、支払い可能関数の基本構文例です:
// payable関数の基本構文
contract PayableExample {
address public owner;
constructor() {
owner = msg.sender;
}
// ETHを受け取る関数
function deposit() public payable {
// 受け取ったETHの量を確認
uint256 amount = msg.value;
}
}
動作解説
この関数はmsg.value
を使用して送金されたETHの量を確認し、それを記録または処理に使用できます。
2. 支払い可能関数の基本的な使い方

2.1 ETHを受け取る
ETHを受け取るためには、関数にpayable
修飾子を付与する必要があります。
// ETHを受け取る関数
contract ReceiveETH {
function deposit() public payable {
// コントラクトがETHを受け取る
}
}
2.2 ETHを送信する
ETHを送信するには、address.transfer
またはaddress.send
を使用します。
// ETHを送信する関数
contract SendETH {
function sendETH(address payable recipient) public payable {
recipient.transfer(msg.value);
}
}
動作解説
この関数は、送信者がmsg.value
として指定したETHをrecipient
に送信します。
3. payableを活用した実践例

3.1 シンプルな貯金箱コントラクト
// 貯金箱コントラクトの例
contract SavingsBox {
address public owner;
constructor() {
owner = msg.sender;
}
function deposit() public payable {}
function withdraw() public {
require(msg.sender == owner, "所有者のみが引き出し可能です");
payable(owner).transfer(address(this).balance);
}
}
動作解説
このコントラクトでは、所有者がETHを引き出すことが可能な貯金箱の機能を提供します。
4. よくあるエラーとその解決策
4.1 payable修飾子の付与忘れ
ETHを受け取る関数にpayable
修飾子を付け忘れると、トランザクションは失敗します。
// 修正例
function deposit() public payable {
// ETHを受け取る
}
4.2 ガス不足エラー
送金時にガス不足が発生する場合があります。これを回避するには十分なガスを指定する必要があります。
// 修正例
recipient.call{value: msg.value}("");
5. 練習問題
以下の課題に挑戦してみましょう:
- 特定のアドレスにのみ送金を許可する関数を作成してください。
- コントラクトの所有者が引き出し可能な貯金箱を改良し、複数の所有者を設定可能にしてください。
6. まとめ
本記事では、Solidityにおける支払い可能関数(payable)の基本について学びました。この関数修飾子を正しく使用することで、安全かつ効率的なETHの送受信を実現できます。次回は、ガス消費を抑える関数設計について解説します。