♦️
Solidityにおけるtransfer、send、callの違い
SolidityでETHを送金する方法は主に3つあります。transfer
、send
、call
です。それぞれ異なる動作をするため、状況に合わせて使い分けることが重要です。
1. 動作
-
transfer
:- 最も基本的な送金方法
- 2300 gasを消費
- エラーが発生した場合、例外を送出
- 呼び出し元コントラクトのコード実行を継続
- 非推奨
-
send
:-
transfer
と似ている - 2300 gasを消費
- エラーが発生した場合、
false
を返す - 呼び出し元コントラクトのコード実行を継続
- 非推奨
-
-
call
:- 任意の量のgasを設定可能
- エラーが発生した場合、例外を送出
- 呼び出し元コントラクトのコード実行を継続
- 推奨
2. 注意事項
-
transfer
とsend
は、payable
アドレスにのみ使用可能 -
call
は、address
型に送金可能 -
call
は、fallback
関数またはreceive
関数を呼び出す -
call
は、他のコントラクトとのデータ交換にも使用可能 -
transfer
とsend
は、将来のバージョンで廃止される可能性があります
3. 使用例
-
transfer
:- 少額のETHを送金する場合
- 送金先の信頼が高い場合
-
send
:-
transfer
よりも多くのgasが必要な場合 - 送金先の信頼が低い場合
-
-
call
:- 他のコントラクトとデータ交換する場合
- 複雑な送金処理を行う場合
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract SendEther {
function sendViaTransfer(address payable _to) public payable {
// This function is no longer recommended for sending Ether.
_to.transfer(msg.value);
}
function sendViaSend(address payable _to) public payable {
// Send returns a boolean value indicating success or failure.
// This function is not recommended for sending Ether.
bool sent = _to.send(msg.value);
require(sent, "Failed to send Ether");
}
function sendViaCall(address payable _to) public payable {
// Call returns a boolean value indicating success or failure.
// This is the current recommended method to use.
(bool sent, bytes memory data) = _to.call{value: msg.value}("");
require(sent, "Failed to send Ether");
}
}
4. まとめ
機能 | transfer | send | call |
---|---|---|---|
動作 | 基本的な送金 | 拡張的な送金 | 汎用的な呼び出し |
gas | 2300 | 2300 | 設定可能 |
エラー処理 | 例外 | false |
例外 |
使用例 | 少額送金 | 信頼性の低い送金 | データ交換 |
推奨 | 非推奨 | 非推奨 | 推奨 |
それぞれの特徴を理解して、適切な方法で使い分けることが重要です。
参考資料
- Solidity チュートリアル - Sending Ether: https://solidity-by-example.org/sending-ether/
Discussion