Rust/DApp実習 - 技術調査(NEAR SDKもうすこしくわしく)#1
今日は設計のために今少し技術的な調査をしていく日だった。near_sdk - Rustについて理解していく。少し考えた結果、先にもう少し調査をすることにした。画像は、NEARのIBC(Inter-Blockchain Communication)、レインボーブリッジっていうのちょっといいな、の図です。
先日、自分でも非常に簡単な調査↓をして、概要は理解しました。
しかし、これだけでアーキテクチャ設計、スマコンのプログラム設計に自信が持てません。もうすこしくわしく確認する。
「イーサリアムを学ぶノートで理解した要点の再確認(1.ふりかえり)」、「2.NEAR SDK使い方確認」「(NEAR SDKを)3. 使う上での注意点確認」をという感じでやっていく。そして最後にまとめる(体力が残っていれば)
ふりかえり
7月のイーサリアムを学ぶ時間で理解したことを思い返すお時間。
学んだことの中で自分の記憶に残っているのは以下の点。
かなりざっくりしてる。
ブロックチェーン独自の標準規格。ERC-721(Non Fungible Token)・EIP-20(Fungible Token)・ERC-1155(Multi Token Standard)・EIP-5192(Minimal Soulbound NFTs)など。おおむね皆これに準拠して実装している。SDKなどの実装提供してるわけではない。そして、ERC-721などは独自の派生型も存在したし、必ずしも標準規格準拠していないものもありつつ、おおむね規格に沿ってる模様(トークン規格)
スマートコントラクトを実装する際、プログラム実行(実行時のメモリアクセス)に対して発生する費用の概念。いわゆるガス代 の存在。正確なガス代の計算式のEIPどれだったっけ..?(ガス代)
プログラムを実装する際、コンストラクタや関数の可視性の設定や、送金と状態変数更新の順序を誤っただけで、重大なセキュリティホールにつながること。ウォレットのすべての資産を失わせる程のトラブルに繋がる。OpenZeppelinはすごい(セキュリティ)
スマートコントラクトはブロックチェーン上で動くアプリケーション。従ってというべきか、ブロックチェーン上に永久記録される。ブロックチェーン/Web3の醍醐味でもあり、通常のアプリケーションのように気軽にアップデートできないということでもある。(永久記録)
スマートコントラクトのコードサイズにも上限がある(イーサリアムメインチェーンでは24KB)。(コードサイズ上限)
コントラクトABIを通じて、スマートコントラクト同士を連携させることも可能(スマコン連携/コントラクトABI)
IBC(Inter-Blockchain Communication)という概念も存在する。異なるブロックチェーン間の連携も考慮する(IBC)
ブロックチェーンの外との橋渡しの概念=オラクル。イーサリアムではChainlinkとBandがオラクルの社会実装としてよく知られていた。神の意を伺う的な意味だっけ?おー神よ(オラクル)
↑なんとなく、思い出してきた。
NEAR SDK使い方確認
地道に確認していきます。最初に全体ざっくりは読んで理解した。
読んで理解
Getting Started
プロジェクト作成方法から解説がある(↓後で環境導入)
Structure of a Contract
サンプルコードでソースの構成が説明されている。
標準ライブラリのstd::collectionsを使うとガス代が高くなる→NEAR SDK独自の代替コレクションタイプを使うことが推奨されている。
Contract Interface
Public Method Types: 外部から呼び出す関数は #[near_bindgen]注釈付のimplの中でpub修飾子をつけて実装するルール。そうするとそのメソッドは、コンパイルされてWASMバイトコードに含まれるようになる。
これは、traitでインターフェース定義された関数を実装する場合もimplブロックに#[near_bindgen]注釈さえつけていれば、同様にコンパイルされてWASMバイトコードに含まれるようになるらしい
Private Methods: リモートコントラクト呼び出しでリモートコントラクトからのコールバックを受け取るための関数を定義する場合、#[private]注釈をつけると、自分自身のコントラクトだけに実行を許可する制御を簡単に行える。
Contract Mutability: 不変性(mutable or not)は、rustらしく引数のselfの渡し方で制御。つまり mutキーワードを付けない渡し方 イコール immutable。トランザクション終了時にステート変更が発生しない仕組み。&self(=参照渡し)か self(値渡し)かは選べる。また、solidityのpure functionと同じものを実装したい場合、selfを引数に含めない(メソッドではなく関連関数として実装)。
Payable Methods: payable関数(=入金受付できる関数)を実装したい場合 関数に `#[payable]注釈` つける。
Serialization Protocols: ステート管理する際、シリアライゼーションの形式が2種類ある。JSONとBorsh。JSONがデフォルト。コントラクト間の連携を挟む場合JSONがよく使われる。Developer Experienceの観点がメイン。BorshはNEARが開発したバイナリオブジェクト仕様。高速ではありそう
Cross-Contract Calls(読んでる途中)
Building Contracts(読んでる途中)
Upgrading Contracts(読んでる途中)
Reducing Contract Size(読んでる途中)
Best practices(読んでる途中)
ついでに開発環境を導入
導入はかなり簡単だ。
rustup 「wasm32-unknown-unknown」
$ rustup target add wasm32-unknown-unknown
NEARが提供する create-near-appでプロジェクトを作成
nodejs>=16が必要
$ asdf global nodejs 16.14.0
$ npx create-near-app my-project --contract=rust --frontend react --tests rust
スマートコントラクトのサンプル確認
NEAR SDK(Rust)を使った一番簡単なスマートコントラクトのコード
以下のコードの「Counter」が1つのスマートコントラクトに該当
#[near_bindgen]注釈 #[derive(BorshDeserialize, BorshSerialize, Default)]注釈は必要。おまじない。
increment、get_countがその処理。
それぞれweb3クライアントからコールできる。
new(#[init]注釈 がついている関数)はカスタム初期化関数(コンストラクタ)。#[init]注釈をつける仕様とのこと。これはカスタムと言うだけあって実装自体が任意。実装しない場合デフォルトの初期化処理が機能するという仕様。
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::near_bindgen;
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize, Default)]
pub struct Counter {
value: u64,
}
#[near_bindgen]
impl Counter {
pub fn increment(&mut self) {
self.value += 1;
}
pub fn get_count(&self) -> u64 {
self.value
}
#[init]
pub fn new(value: u64) -> Self {
log!("Custom counter initialization!");
Self { value }
}
}
NEAR SDKを読んでお勉強(脱線)
いい機会だからついでにNEAR SDKのソースコードを見て学んでいこう
(実はこれがやりたかった。実例で学習する時間。)
ちょっと理解した。あと、SmartContractのことだいぶ忘れかけていた。思い出した。でも、NEAR 吸収するのにもう少し時間かかる。というよりもう少しちゃんと見たい。
またあした!
この記事が気に入ったらサポートをしてみませんか?