Solidityには事前に定義されている特殊な用途のための変数=特殊変数があります。
このガイドでは、単位および特殊変数のうち代表的なものについて、説明します。
通貨単位
Day 4でも解説していますが、Ethereumの通貨単位としては、Ether, Gwei, Weiの3つがあります。Solidityの中でもether
, gwei
, wei
として使うことができます。
次の例では、1 gwei
と1e9
(=1000000000)が同じであるかどうかをチェックしています。このcheckGwei
を実行した場合、isEqualの値はtrueになります。
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
でコントラクト所有者が引き出すことが可能です。withdraw
はonlyOwner
modifierが付加されており、所有者しか呼ぶことができません。getOwnersBalance
は、Ownerがどのくらいの残高かを確認する(実際に動作しているかをチェックするために必要となる)関数です。
withdraw
では、”payable(i_owner).transfer(total);
“で、所有者のアドレス(i_ownerは所有者のアドレス)向けにtotal
(トータル金額)を送金しています。
また、getOwnersBalance
では、i_owner.balance
(所有者の残高)を返しています。
// 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
は、次の例のいずれかの形で書くことも可能です。send
もtransfer
と似たような記載の仕方ですが、実行結果をbool
型で返します(この一文に続けて、結果が成功か失敗かによって異なる処理を入れることができる)。
callは低レベルの方法で別のアドレスのコントラクトの関数を呼ぶことが可能です。(“”)の()の中に本来は、呼び出したい関数をエンコードした文字列を入れますが、ここでは関数を呼び出すことが目的ではなく、金額を送ることが目的なので、この部分は””(空)です。callが呼び出される際に金額を送ることが可能であり、その部分は{value: total}によってなされています。
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チュートリアル全体について、是非、あなたのご意見をお聞かせください。
アンケートはこちらからご回答いただけます。
無料相談承ります
オンラインでの無料相談を承っています。ご希望の方は、お問い合わせフォームよりご連絡ください。
ITの専門家があなたのご質問にお答えいたします。
コメント