[スマートコントラクト・プログラミング]Solidityの変数

プログラミング

スマートコントラクトを作成するためのプログラミング言語であるSolidityの変数について記載します。

Solidityの変数

Solidity は静的に型付けされたプログラミング言語です。

よって、変数の宣言時に状態(値が入っているか等)または変数の型を指定する必要があります。

宣言された変数には、常にその型に基づいたデフォルトの値が定義されており、”undefined”または”null”の概念はありません。

Solidity 変数名の命名規則

Solidity で変数に名前を付けるときは、次の規則に従う必要があります。

  • Solidityの変数名は、数字 (0 ~ 9) で始めることは出来ません。文字またはアンダースコア文字で始まる必要があります。たとえば、0xbrokersは頭文字が0のため数値です。変数としては無効ですが、_0xbrokerは有効な変数名として定義できます。
  • Solidity 変数名は大文字と小文字が区別されます。たとえば、_0xBrokers と _0xBROKERS は 2 つの異なる変数として判断されます。
  • Solidity の予約済みキーワードを変数名として使用出来ません。

Solidityで事前に定義されている予約語の一覧はこちらを参照ください。

[スマートコントラクト・プログラミング]Solidityの基本文法
スマートコントラクト,DAppsを作成するためのプログラミング言語であるSolidityの基本文法について記載します。 スマートコントラクト,DAppsとは スマートコントラクトおよびDAppsとは、ブロックチェーンに保存され、...

3つ種類の変数

Solidityには主に下記3つの種類の変数が用意されています。

  1. ローカル変数
  2. グローバル変数
  3. ステート変数

Local変数(ローカル変数)

値が定義されている関数内でのみ使用でき、関数が実行されるまで値が存在する変数。

ローカル変数は通常、一時的に変数に値を格納するために使用することを想定しています。

下記のSampleLocalコントラクトでは、ローカル変数aとbを宣言し、2 つのローカル変数の合計をローカル変数のresultへ格納し、resultを返すgetファンクション(関数)を定義しています。

Global変数(グローバル変数)

Solidityではブロックチェーンに関する情報を取得するために全てのスコープからアクセスできるグローバル変数を用意しています。

Solidityのグローバル変数は下記の通り。

名前 戻り値
blockhash(uint blockNumber)

returns (bytes32)

指定されたブロックのハッシュ – 現在のブロックを除く、最新の 256 個のブロックに対してのみ有効
block.coinbase(address payable) 現在のブロックのマイナーのアドレス
block.difficulty(uint) 現在のブロック難易度
block.gaslimit(uint) 現在のブロックガスリミット
block.number(uint) 現在のブロックナンバー
block.timestamp(uint) 現在のunixのタイムスタンプ(秒)
gasleft() returns (uint256) 残りのガス
msg.data(bytes calldata) コールデータ
msg.sender(address payable) メッセージの送信者 (現在の発信者)
msg.sig(bytes4) calldataの最初の 4 バイト(ファンクションの識別子)
msg.value(uint) メッセージとともに送信された wei の量
now(uint) 現在のブロックのタイムスタンプ(block.timestampのエイリアス)
tx.gasprice(uint) トランザクションのガス代
tx.origin(address payable) トランザクションの送信者

下記のSampleGlobalコントラクトでは、グローバル変数であるmsg.senderを使用して、コントラクトを展開している人物のアドレスにアクセスするコントラクトを定義しています。

State変数(ステート変数)

ステート変数は、日本語では状態変数とも呼ばれています。

ステート変数で定義された変数およびその変数の値はコントラクトのストレージに永続的に保存される仕様となっています。

イーサリアムであれば、ステート変数で定義された値はブロックチェーンの台帳へ保存をされることを意味します。

下記のSampleStateコントラクトの例ではvauleをState変数(状態変数)として定義しています。

ステート変数の4つのスコープ

ローカル変数のスコープは、それらが定義されている関数で利用される場合に限定されていますが、このState変数(状態変数)には4種類のスコープを持つことができる仕様となっています。

Public

Publicステート変数には、メッセージを介してだけでなく内部的にもアクセスできる仕様となっています。

public 状態変数の場合、自動 getter 関数が生成されます。

下記ソースコードは、publicステート変数を定義したコントラクトです。

publicステート変数であるdataのデフォルト値は10、getファンクションを呼び出した場合、100を設定するコントラクトなっています。publicなので外部からも呼び出しが可能です。

下記は外部コントラクトのanotherContractからSampleDataコントラクトのpublicステート変数を取得するコードです。

publicステート変数は外部コントラクトからのアクセスも可能な変数です。

Internal

Internalステート変数は、現在のコントラクトまたはそのコントラクトから派生したコントラクトから内部的にのみアクセスできる仕様となっています。

SolidityではState変数にスコープ範囲を明記しなかった場合、このInternalがデフォルトで設定される仕様となっています。

下記例では、インターナルState変数としてiDataを定義し、getファンションの中でpublic変数のdataにiDataを設定するスマートコントラクトを記載しています。

下記は外部コントラクトからSampleDataコントラクトのinternalステート変数であるdataにアクセスしようとしているソースコードです。

このソースコードではmember data not found or not visibleというコンパイルエラーが発生し,Solidityをコンパイルすることが出来ません。

外部コントラクトからinternalステート変数にアクセスしようとしているためです。

Private

Privateステート変数は、コントラクト内でのみアクセスできます。

プライベート関数は、他の関数に継承できない唯一の関数でもあります。

下記例では、同一のコントラクト内でprivateステート変数にアクセスしているスマートコントラクトとなります。

基本的に同じコントラクト内で利用する場合は、Internalステート変数と同じ処理です。

下記は外部コントラクトからSampleDataコントラクトのprivateステート変数であるdataにアクセスしようとしているソースコードです。

このソースコードではmember data not found or not visibleというコンパイルエラーが発生し,Solidityをコンパイルすることが出来ません。

挙動はInternalステート変数と全く同じになりますが、外部コントラクトからprivateステート変数にアクセスしようとしているためコンパイルエラーとなっています。

InternalとPrivateの違い

InternalとPrivateの違いですが、クラスを継承してアクセスをした場合に違いが出てきます。

  • Internal:アクセス可能
  • Private:アクセス不可能

下記例では、SampleDataを継承したSampleData2のコントラクトから継承元のinternalステート変数を呼び出しています。internalステート変数の場合は問題なく利用可能です。

一方下記の例では、privateステート変数で宣言しているため、継承先からもアクセスが出来ない形となります。

declaration error undeclared identifierというSolidityのコンパイルエラーが発生してコンパイルできない形となります。

最後に

今回紹介したSolidityの仕様やコードをRemix IDEHardhatで実際に実行やテストをして確認してみましょう。

実際に動かしたり、テストすることで理解が深まるかと思います。

hardhatのインストール手順

Ethereum(イーサリアム)のDApps開発環境Hardhatのインストール手順
Ethereum(イーサリアム)のローカル開発環境であるHardhatのインストール手順を記載します。 Hardhatとは? Hardhatは、Solidityなどで開発したイーサリアムのスマートコントラクト、Dappsをコ...

HardhatでスマートコントラクトのDeploy手順

[Hardhat]SolidityでHello Worldのスマートコントラクトを作成
Solidityを使ってHello Worldを作成してみましょう SolidityでHello World! 前提条件 ・Hardhat デフォルト・フォルダ構成 Hardhatについては下記記事を参照ください。 ...
タイトルとURLをコピーしました