論理知識ある程度まとめたので、実際にスマートコントラクトを作成したいです。
他の言語もありましたが、Solidityのほうが一番情報多いので、Solidityで進めます。
-
Serpent · ethereum/wiki Wiki
- python ライクの言語
- Augur(REP)チームが使っていたが、重大な脆弱性問題があったので、現在オススメされない Serpentに脆弱性 AugurはSolidityへ移行 | ビットコインの最新情報 BTCN|ビットコインニュース
-
LLL PoC 6 · ethereum/cpp-ethereum Wiki
- LISP ライクの言語
Solidity
基本的には JavaScript
ライク、静的な型付けプログラミング言語である
- 大文字小文字は区別する
- 文(Statement)最後にはセミコロン
基本記法
contract SingleNumRegister {
uint storedData;
function set(uint x) {
storedData = x;
}
function get() constant returns (uint retVal) {
return storedData;
}
}
特別の箇所だけ抜粋
-
contract
でコントラクトを定義 -
function
で関数定義- 戻り値ある場合、明示にデータ型を定義する必要がある
- 戻り値ない場合、定義なし
データ型
カテゴリ | 定義 | 意味 |
---|---|---|
基本型 | bool | ブーリアン |
int | 符号付き整数 | |
uint | 符合なし整数 | |
address | アドレス専用のデータ型 補足1 | |
enum | 列挙 | |
function | 関数 | |
参照型 | array | 配列 |
structs | ストラクト | |
その他 | mapping | キーバリューのマップ |
- 参照型(配列とストラクと)は、
データの保存場所(Data location)
という概念がある-
memory
またはstorage
-
memory
の場合は、処理中だけ保持され、終わったら保持されない -
storage
の場合は、処理後、ブロックチェーンに保持される
-
- 変数の定義コンテキストによって、デフォルト値をもっていて、強制的に変更も定義できる
- 関数のパラメータはデフォルト
memory
- ローカル変数の場合はデフォルト
storage
- 関数のパラメータはデフォルト
- ステート変数の場合は強制的に
storage
- ステート変数と言うのは、上記基本記法のサンプルにある
storedData
です。 - オブジェクト指向の考え方から例を上げると、たとえ ruby で言いますと、コントラクトはクラスであり、ステート変数と言うのは、インスタンスである
- インスタンス変数を保持する必要があるので、強制的に
storage
になる
- ステート変数と言うのは、上記基本記法のサンプルにある
- 実はまた3個目の場所
calldata
がある。外部に公開する関数の場合、そのパラメータに渡される値はこれに該当する。ほとんどmemory
と同じ動作になる。違うのは、値の変更は不可なところです
-
- mapping も参照型だと理解していますが、公式ドキュメントはそう分類されてないので、
その他
カテゴリにしています- mapping は
JavaScript
の連想配列と同じ感じですが、特別なのは、キーを保存せず、キーのkeccak256
値を保存するので、mapping のサイズ、キー集合、値集合は取得できない。取得したい場合は、右記のように自分で実装する必要がある dapp-bin/iterable_mapping.sol at master · ethereum/dapp-bin
- mapping は
単位とグローバル値
- 1 ether == 10^8 wei
- 時刻単位: 1 hour == 60 minutes
- ブロックチェーン周り(よく使うものを抜粋)
- block.gaslimit (uint): 当該ブロックの gas limit
- block.number (uint): 当該ブロックの番号
- block.timestamp (uint): 当該ブロックのタイムスタンプ、秒数
- msg.sender (address): 当該呼び出しの呼び出し元アドレス
- now (uint): block.timestamp と同じ
- tx.gasprice (uint): 当該トランザクションの gas price
関数とステート変数のアクセス範囲定義
- external
- コントラクトのインタフェースであり、他のコントラクトやトランザクションから呼び出せる。内部で直接に呼び出せない。
f()
はだめでthis.f()
はOK
- コントラクトのインタフェースであり、他のコントラクトやトランザクションから呼び出せる。内部で直接に呼び出せない。
- public:
- コントラクトのインタフェースであり、内部か、メッセージ経由で呼び出せる。パブリックなステート変数の場合、自動的に
getter
関数が生成される
- コントラクトのインタフェースであり、内部か、メッセージ経由で呼び出せる。パブリックなステート変数の場合、自動的に
- internal:
- 現在のコントラクトまたは派生コントラクトから呼び出せる
- private:
- 現在のコントラクトのみ呼び出せ、派生コントラクトから呼び出せない