アルゴリズムとかオーダーとか

仕事で勉強したことなどをまとめてます

etherの受け取り可能なContractの作成

今回はetherの送金を受け付ける事ができるContractの作成方法をまとめます。
当たり前すぎな事なのか、意外に記事がなかったので。。。

Solidityの公式ドキュメントで記述のある箇所はこちら
Function Modifiers
結論を先にいうと、etherを受け取りたいメソッドに対してpayable修飾子を付加する事で、そのメソッドを呼び出し時にContractがetherを受け取る事ができる様になります。
以降は簡単なContractの実装例と説明です。


基本的にEthereumのContractに対しての送金トランザクションは否応なく失敗します。安全性のためにそう作られてるそうです。
しかし、前述した通りpayable修飾子をつけたメソッドの呼び出しトランザクションにだけetherを乗せる事ができる様になります。

では早速簡単なetherを受け取れるContractをつくってみます。
今回作るContractは作成時に送金したetherを保持して、誰でも引き出す事ができるあしなが募金箱です。

ソースコード

pragma solidity ^0.4.18;
contract AnonemouseBank {
     address public sugarDaddy;
    uint public initialBalance;
    
    function AnonemouseBank() public payable {
        sugarDaddy = msg.sender;
        initialBalance = msg.value; // wei単位で記録される
    }
    
    function getBalance() public constant returns(uint)  {
        return this.balance;
    }
    
    function withDraw(uint256 _amount) public returns(bool) {
        return msg.sender.call.value(_amount)();
    }
}
コードの説明

コンストラクタにだけpayable修飾子をつけているので、このContractは作成時にだけetherを受け取れます。
コンストラクタでは、このContractを作成したaccountをsugarDaddyに、初期のetherの量をinitialBalanceに格納しています。
getBalanceではこのコントラクトが保持しているehterの残高を返しています。(単位はwei)
withDrawでは呼び出した人に対して指定した量のetherを返しています。(ここも単位はwei)
送金されてきたetherの量を知りたい場合はmsg.valueで取得できます。

address.call.value(_value)でContractが保持しているetherを指定した量だけaddress宛てに送る事ができます。
もちろんContractが保持しているetherを超えた量の送金はできません。その場合は何も送金されずにGasだけが消費されます。