【Solidity基礎】address.sendとaddress.transferの違い




sendもtransferも送金を行う

send

現在はセキュリティ面から主流ではなさそう。理由としてはsendを使って送金に失敗してもfalseが返ってくるだけなのでエラーが伝搬されず、revert(処理をなかったことにする)されないからです。失敗時のハンドリングを自分でしないといけないので扱いが難しいそうですね。

下記はSolidityの公式ドキュメントのサンプルコードです。Re-Entryと呼ばれるバグを含んだソースコードなのですが、送信先のコントラクトがfalseを返すと何度でも再送信ができてしまいます。理解が浅いかもしれませんが、送信先のアドレスがコントラクトアドレスの場合、好きなように値を返せるからなのかなと理解しています。

pragma solidity ^0.4.0;

// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract Fund {
    /// Mapping of ether shares of the contract.
    mapping(address => uint) shares;
    /// Withdraw your share.
    function withdraw() public {
        if (msg.sender.send(shares[msg.sender]))
            shares[msg.sender] = 0;
    }
}

transfer

現在はtransferを使うのが推奨みたいです。下記も公式ドキュメントのサンプルコードです。上記のRe-Entryのバグを改善したものになります。修正点はshares[msg.sender] に0を代入してからtransferで送金を行なっています。transferを使うことで失敗時は絶対にrevertされるし、先に残高を0にするので別のバグで再送金されても送れない仕組みになっています。

pragma solidity ^0.4.11;

contract Fund {
    /// Mapping of ether shares of the contract.
    mapping(address => uint) shares;
    /// Withdraw your share.
    function withdraw() public {
        var share = shares[msg.sender];
        shares[msg.sender] = 0;
        msg.sender.transfer(share);
    }
}

まとめ

Solidityはまだまだ言語仕様的に未熟なとこが多いのでセキュリティ面を意識して学ばないといけないですね。あとはブロックチェーン上でどうやって処理がどうやって実行されているのか理解しながらプログラムできるとより安全なスマートコントラクトが実装できそうだなと思いました。

今後もセキュリティ面を含めたSolidityの情報を書いていくので間違い等ありましたら教えていただけたらと思います。

オススメの書籍

Ethereumを使ったDApps開発を学びたいなら今だとこの1冊が1番良いです!開発環境の構築から使うべきツール、フレームワーク、実装方法・注意点まで網羅的に解説されている書籍なのでおすすめです。出版も2018年1月ということでかなり新しい本で、DMM Bitcoinを作っているネクストカレンシー所属の方が書いているので信頼できます。

ビットコインとブロックチェーンの詳細をしっかりと学びたい方にはこちらの書籍が非常におすすめです。ウォレットの仕組み、楕円曲線暗号、P2Pプロトコル、公開鍵暗号などビットコインを支える技術について詳細に解説されています。また、サンプルコードを通して実際に手を動かして学べるので非常に濃い内容となっています。

The following two tabs change content below.

髙妻智一

2013年CyberAgent新卒入社 スマホゲームを作る子会社に所属し、サーバーサイドのエンジニアを担当。2年目の終わりから新規子会社の立ち上げに参加し、サーバーサイドのエンジニアリーダーとしてサービースのリリースから運用までを担当。 2018年仮想通貨のスマホウォレットを提供するGinco Incにブロックチェーンエンジニアとして入社。






よく読まれている関連記事はこちら




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です