This project deploys a bike-sharing service using self-issued ft as utility tokens.
- End users can use, inspect and return bikes
- To use a bike, End users need to spend ft.
- End-users can receive ft as a reward for inspecting bikes
Link of deployed project: NEAR-bikesharing.
※ A Test NEAR wallet is required in advance.
The UI will look like this:
It is not enough to type a few commands to build this project because it is built on the assumption that:
- You have deployed contracts (especially ft-contracts) in your account
- You create a near-app specifying 3.1.0.
Not sure why, since cloning this project andnpm install
will not result in the same environment, executenpx [email protected]
locally.
If you want to try all functions, you need to deploy ft contract as well, see NEAR-BikeShare Section1-Lesson1.
The following is how to start the application to use some of its functions (bike contract).
yarn install
yarn deploy
yarn dev
Access the URL displayed in the terminal.
以下レポジトリの説明・まとめ
fungible token(以降 ft)を発行, 転送するコントラクト
- Rust Rust で記述したコードを wasm 形式にコンパイルしてデプロイします.
- Library
- near_sdk NEAR のコントラクトを書く上で標準的な機能を提供します.
- near_contract_standards::fungible_token ft としての(転送などの)機能を提供します.
- cross contract call あるコントラクトが別のコントラクトのメソッドを呼び出すことを可能とする機能. near_sdk から利用できます.
contract
├── Cargo.toml
└── src
└── lib.rs
Cargo.toml
バージョン管理ファイル.src/lib.rs
FT コントラクトの基本機能の実装と簡易的なテストをしています. (機能の実装はほとんどライブラリを使用しているのでコード量は少ないです)
フロントエンド側とコントラクトの接続はfrontend/assets/js/near/utils.js
(以降 utils.js
)で行っているため,
基本的にフロントからコントラクトのメソッド呼び出しはutils.js
を使用します.
トークン所有者の id, 供給総量, メタデータを引数にnew
メソッドの呼び出し.
フロントとは繋がず, コントラクトのデプロイ時にnew
メソッドの呼び出しまで済ませます.
ft のコントラクトでは, ft のやり取りをするアカウントが増えるほど使用するストレージが増えるため,
アカウントにストレージの使用量を支払うことを求める仕組みになっています.
これをアカウントの登録と呼ぶことにします.
フロント側でユーザーアカウントの登録を確認し, 登録が済んでいなければ登録を促します.
登録の確認にはフロントのutils.js
を通してユーザアカウントが
ft コントラクトのstorage_balance_of
メソッドを呼び出し,
登録にはstorage_deposit
メソッドを呼び出します.
フロントのutils.js
を通してユーザアカウントがft_transfer
メソッドを呼び出します.
フロントのutils.js
を通してユーザアカウントがft_transfer
メソッドを呼び出します.
本プロジェクトで作るアプリでは ユーザがバイクを使用する際, 決まった量の ft をバイク管理のコントラクト(がデプロイされているアカウント)へ支払う必要があります. それには以下の一連の処理を同期的に行う必要があります.
- ユーザが ft コントラクトの ft 転送メソッドを呼び出す
- ft コントラクトはバイク管理のコントラクトへ ft を転送
- ft を受信したバイク管理のコントラクトはユーザによるバイクの使用処理を進める
この処理は ft コントラクトにft_transfer_call
,
バイク管理のコントラクトにft_on_transfer
というメソッドを用意することで実現できます.
よってフロントのutils.js
を通してユーザアカウントがft_transfer_call
を呼び出します.
バイクのシェアリングサービスを提供するためのバイク管理コントラクト
(各 stack の説明はContract-1 のセクションを参照)
- Rust
- near_sdk
- cross contract call
contract
├── Cargo.toml
└── src
└── lib.rs
Cargo.toml
バージョン管理ファイル.src/lib.rs
バイクを管理するコントラクトの実装とユニットテストの実装をしています.
ft コントラクトと同じく,
フロントエンドからコントラクトのメソッド呼び出しはフロント側のutils.js
を通して行われます.
ft コントラクトのセクション で説明したft_on_transfer
メソッドを使用します.
フロントのutils.js
を通してユーザアカウントが ft コントラクトのft_transfer_call
を呼び出し,
それがトリガーとなりft_on_transfer
を実行します.
フロントのutils.js
を通してユーザアカウントがinspect_bike
メソッドを呼び出します.
フロントのutils.js
を通してユーザアカウントがreturn_bike
メソッドを呼び出します.
- 点検からの返却時
点検をしてくれたユーザアカウントには報酬として ft を送信するため, 内部で
ft コントラクトの
ft_transfer
メソッドを呼び出しています(cross contract call). bike コントラクトからユーザアカウントに ft を転送します. また, ft の転送処理と返却処理を同期的に行うため, 転送処理の結果に応じて返却処理を行うコールバック関数を用意しています.
- javascript
- React
- near-api-js near のコントラクトと連携するためのライブラリ
frontend/
├── App.js
├── assets
│ ├── css
│ │ └── global.css
│ ├── img
│ │ ├── bike.png
│ │ ├── favicon.ico
│ │ ├── logo-black.svg
│ │ └── logo-white.svg
│ └── js
│ └── near
│ ├── config.js
│ └── utils.js
├── index.html
└── index.js
frontend/App.js
フロントエンドの表示部分を担当するファイルです. ユーザが触れる各ボタンとコントラクトのメソッドを呼び出す関数(utils.js
内に定義)を繋げています.frontend/App.js/assets/css/global.css
css の設定をまとめています.frontend/App.js/assets/img/
表示に必要な画像が入っています.frontend/App.js/assets/js/near/utils.js
near-api-js
を利用してコントラクトとの接続を行っています.frontend/App.js/assets/js/near/config.js
frontend/App.js/assets/js/near/utils.js
に必要な設定を定義しています.
App.js
からutils.js
に定義したlogin
関数を呼び出すことで,
ユーザアカウントに bike コントラクトのメソッドを呼び出す権限を与えます.
これにより bike のコントラクトの(token の移動を伴わない)メソッド呼び出しはサインなしで行うことができます.
またその情報をリセットすることでサインアウトします.
ft コントラクトのセクションで説明したアカウントの登録に関して処理します.
App.js
のnewUserRegister
関数からutils.js
に定義した ft コントラクトのメソッドを呼び出します.
まず, App.js
からutils.js
に定義した bike コントラクトのメソッドを呼び出しバイクの総数を取得します.
次にバイクの数だけ loop 処理を行い, 各バイクのデータを取得(同じく bike コントラクトのメソッド呼び出し).
取得したデータとログイン中のアカウントの id を照合して,
ログイン中のユーザにとって各バイクが使用可能/点検可能/返却可能かのデータを
フロントエンド側で用意したデータ型allBikeInfo
に格納します.
前項で取得した全てのバイクの情報を loop 処理でリストアップします.
App.js
の関数からutils.js
に定義した ft コントラクトのft_transfer_call
メソッドを呼び出します.
App.js
の関数からutils.js
に定義した bike コントラクトのメソッドを呼び出します.
App.js
の関数からutils.js
に定義した ft コントラクトのメソッドを呼び出します.
root
├── FT_contract/
└── NEAR_sharing_economy/
├── contract/
├── frontend/
├── integration-tests/
└── package.json
ft コントラクトのディレクトリ(FT_contract
)が独立したディレクトリ,
bike コントラクト(NEAR_sharing_economy/contract/
)と
フロントエンド(NEAR_sharing_economy/frontend/
)が同じディレクトリ内に属します.
ft コントラクトは独立した機能を持っているため別のディレクトリとして分離させました.
- near-api-js Using JavaScript API to interact with NEAR | NEAR Documentation
- sighnIn で付与している権限について Access Keys | NEAR Documentation
- ft コントラクトのコードの参考にしたもの(コードの内容は全て同じです) GitHub - near-examples/FT: Example implementations of money-like tokens, where one token is the same as any other, using the NEP-141 spec (similar to ERC-20)
- FT の規約 Fungible Token | NEAR Protocol Specification
- コントラクトに課せられるストレージステーキングの話 Storage Staking | NEAR Documentation
- コントラクトがストレージの使用量をどのように管理するかの話 Storage Management | NEAR Protocol Specification
- 書き方, 文法, ガス代の付け方など Callbacks | NEAR SDK docs
- トランザクションとレシートのやり取りの流れ Cross-Contract Call | NEAR Protocol Specification
ft_transfer_call
の説明 Fungible Token | NEAR Protocol Specification- callback 関数に使用する
#[private]
macro の意味 Adding cross-contract calls, access key shuffling, etc. | NEAR SDK docs
- unite test Unit Tests | NEAR SDK docs
- integration test
Integration Tests | NEAR SDK docs
- ライブラリ(m1 mac では新バージョンが対応していないことについても書いてある) GitHub - near/workspaces-rs: Write tests once, run them both on NEAR TestNet and a controlled NEAR Sandbox local environment via Rust
- コンパイルに使用する parcel について Targets
- コントラクト内のメソッドで, U128 や Promise という型をどう扱うかについて Sending $NEAR | NEAR SDK docs
- コントラクト内のメソッドにおいて,
#[near_bindgen]
macro や init 関数の説明 near_bindgen | NEAR SDK docs - ガス代について Gas | NEAR Documentation