day11. Solidity基本文法 – 単位・特殊変数・関数 – 

Solidityには事前に定義されている特殊な用途のための変数=特殊変数があります。 このガイドでは、単位および特殊変数のうち代表的なものについて、説明します。

Solidityには事前に定義されている特殊な用途のための変数=特殊変数があります。
このガイドでは、単位および特殊変数のうち代表的なものについて、説明します。

目次

通貨単位

Day 4でも解説していますが、Ethereumの通貨単位としては、Ether, Gwei, Weiの3つがあります。Solidityの中でもether, gwei, weiとして使うことができます。

次の例では、1 gwei1e9(=1000000000)が同じであるかどうかをチェックしています。このcheckGweiを実行した場合、isEqualの値はtrueになります。

Solidity
contract Units {
  bool public isEqual = false;
  ...
  function checkGwei() public {
    if (1 gwei == 1e9) {
      isEqual = true;
    }
  }
  ...
}

時間単位

時間単位を表すのに、seconds, minutes, hours, days, weeksを使うことができます。

  • 1 == 1 seconds
  • 1 minutes == 60 seconds
  • 1 hours == 60 minutes
  • 1 days == 24 hours
  • 1 weeks == 7 days

ブロック・トランザクションに関する特殊変数

block

blockは、現在のブロックに関連する情報を提供する特殊変数です。
Day6でも見ましたが、Etherscanでブロックの実例と照らし合わせると理解がしやすくなります。

  • block.number: 現在のブロックの番号を表します(EtherscanにおけるBlock Heightと同じです)
  • block.timestamp: 現在のブロックのタイムスタンプ(UNIX時間)を表します
  • block.difficulty: 現在のブロックの難易度を表します

msg

msgは、現在のトランザクションやメッセージに関連する情報を提供する特殊変数です。
Day6のトランザクション情報の項目も合わせてご参照ください。

  • msg.sender: トランザクションを送信したアドレスを表します(EtherscanにおけるFromと同じです)
  • msg.value: トランザクションと一緒に送信されたEtherの量を表します

address型のメンバー

address型は、Day8でも言及した通り、イーサリアムのアドレスを表すデータ型です。いくつかよく利用されるメンバー関数・変数があります(メンバーとは、データ型等が含んでいる要素のことです)。

  • balance: address型のインスタンスの残高(Etherの量)を表す変数です。
  • transfer(): address型のインスタンスからイーサを別のアドレスに転送するための関数です。転送が成功すると宛先アドレスにEtherが送信されます。失敗すると、例外が発生します。
  • send(): address型のインスタンスからイーサを別のアドレスに転送するための関数です。転送が成功すると、真(true)が返されます。転送に失敗すると、偽(false)が返されます。
  • call()は、address型のインスタンスに対して外部関数呼び出しを行うための関数です。

次の例は、Fundingというコントラクトで、fund(投資する)、 withdraw(引き出す)、 getOwnersBalance(コントラクト所有者の残高を取得する)という3つの関数を定義しています。
fundで、誰がいくら投資したかを記録し、withdrawでコントラクト所有者が引き出すことが可能です。withdrawonlyOwner modifierが付加されており、所有者しか呼ぶことができません。getOwnersBalanceは、Ownerがどのくらいの残高かを確認する(実際に動作しているかをチェックするために必要となる)関数です。

withdrawでは、”payable(i_owner).transfer(total);“で、所有者のアドレス(i_ownerは所有者のアドレス)向けにtotal(トータル金額)を送金しています。
また、getOwnersBalanceでは、i_owner.balance(所有者の残高)を返しています。

Solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

contract Funding {
  address[] private s_funders;
  mapping(address => uint256) private s_addressToAmount;
  address public i_owner = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
  
  modifier onlyOwner() {
    require(msg.sender == i_owner, "Only contract owner can call this function");
    _;
  }
  
  function fund() public payable {
    s_funders.push(msg.sender);
    s_addressToAmount[msg.sender] += msg.value;
  }
  
  function withdraw() public onlyOwner {
    uint256 total = 0;
    for (uint256 i = 0; i < s_funders.length; i++) {
      address funder = s_funders[i];
      total += s_addressToAmount[funder];
      s_addressToAmount[funder] = 0;
    }
    
    payable(i_owner).transfer(total);
  }
  
  function getOwnersBalance() public view returns (uint256) {
      return i_owner.balance;
  }

}

27行目のtransferは、次の例のいずれかの形で書くことも可能です。sendtransferと似たような記載の仕方ですが、実行結果をbool型で返します(この一文に続けて、結果が成功か失敗かによって異なる処理を入れることができる)。

callは低レベルの方法で別のアドレスのコントラクトの関数を呼ぶことが可能です。(“”)の()の中に本来は、呼び出したい関数をエンコードした文字列を入れますが、ここでは関数を呼び出すことが目的ではなく、金額を送ることが目的なので、この部分は””(空)です。callが呼び出される際に金額を送ることが可能であり、その部分は{value: total}によってなされています。

Solidity
bool sendSuccess = payable(i_owner).send(total); // sendを使った場合の記載例
(bool callSuccess, bytes memory dataReturned) = payable(i_owner).call{value: total}(""); // callを使った場合の記載例

msg、block、addressについては、よく使われるものを列挙していますが、上記以外にもメンバー変数・関数はあります。詳細は、Solidityの公式ガイド等もあわせてご参照ください。

ご意見をお聞かせください!

web3チュートリアルシリーズについてのご意見を是非お聞かせください。

この記事、または、web3チュートリアル全体について、是非、あなたのご意見をお聞かせください。
アンケートはこちらからご回答いただけます。

無料相談承ります

ITの専門家が無料相談を受け付けます。web3以外のテーマでもOKです。

オンラインでの無料相談を承っています。ご希望の方は、お問い合わせフォームよりご連絡ください。
ITの専門家があなたのご質問にお答えいたします。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

After joining IBM in 2004, the author gained extensive experience in developing and maintaining distributed systems, primarily web-based, as an engineer and PM. Later, he founded his own company, designing and developing mobile applications and backend services. He is currently leading a Tech team at a venture company specializing in robo-advisory.

コメント

コメントする

CAPTCHA


目次