LoginSignup
0
0

More than 1 year has passed since last update.

FlutterでDApp開発 その3(野良パッケージ化)

Posted at

はじめに

昨日はDev Protocolのコントラクト実行を試してみましたが、今日はその処理をパッケージ化して使ってみたいと思います。
いずれはDev ProtocolのJavaScript/TypeScriptのインターフェースであるdev-kit-jsのDart実装のようなものを提供できればなと考えています。

パッケージ化に当たっては、web3dartを参考にさせていただきました。

実装

パッケージ化の準備

まず昨日までに実装したDev Protocolのステーキング数を取得する処理をパッケージ化します。

devkit.dartフォルダを作成し、プロジェクトを開始します。
dart createコマンドでも作成できるみたいなのですが、今回は小さいプロジェクトのなの何もない状態から作成していきます。)

まずはパッケージの情報や依存パッケージの定義を行う pubspec.yamlを作成します。

pubspec.yaml
name: devkit
description: (Unofficial) Dart library to Dev Protocol Interface
version: 0.0.1
homepage: https://github.com/hhatto/devkit.dart

environment:
  sdk: '>=2.12.0 <3.0.0'

dependencies:
  web3dart: ^2.3.3

見様見真似なので、sdkバージョンの違いとかまだよく分かってない部分が多々あります。

これもよく分かってないですが、パッケージの依存解決するために dart pub getしておきました。

$ dart pub get

これでpubspec.lock作成されるのですが、他の言語とかだとlock系のファイルは保存しなかったりすると思うのですが、Dartはどうなんでしょうか。
一旦ファイルは作っておきます。(.gitignoreとかに追加しておくのかな...?)

これでパッケージ作成の準備は整いました。

パッケージの処理実装

先にディレクトリ構成だけ記載しておきます。

$ tree -L 4
.
├── lib
│   ├── devkit.dart
│   └── src
│       ├── abi
│       │   ├── lockup.dart
│       │   └── registry.dart
│       └── core.dart
├── pubspec.lock
└── pubspec.yaml

3 directories, 6 files

lib ディレクトリ以下を少し説明しておきます。

  • lib/devkit.dart はパッケージの定義やimport/exportを管理したりする最小限のファイルです。(別にここに処理書いてもいいとは思いますが、web3dartに合わせました。)
  • lib/src/core.dart はコントラクト実行等を行うメインの処理
  • lib/src/abi/... はコントラクト用のABIの定義(昨日の記事で書いたものと同じです。)

まずlib/src/devkit.dartは以下のような感じです。

lib/devkit.dart
library devkit;

export 'src/core.dart';

library でライブラリ(パッケージ)定義してるのと、src/core.dartの処理をエクスポートして、パッケージ使用者側から使えるようにしています。

次にlib/src/core.dartは以下のような感じです。
処理自体は昨日実装したものをほぼ転用した形です。

lib/src/core.dart
import 'package:http/http.dart';
import 'package:web3dart/web3dart.dart';

import './abi/lockup.dart';
import './abi/registry.dart';

class DevKitClient {
    DevKitClient(String apiUrl) {
        var httpClient = new Client();
        var ethClient = new Web3Client(apiUrl, httpClient);
        _client = ethClient;
    }

    late final Web3Client _client;

    registryContractFactory() {
        EthereumAddress contractAddress = EthereumAddress.fromHex('0x1D415aa39D647834786EB9B5a333A50e9935b796');
        final contract = DeployedContract(ContractAbi.fromJson(registryAbi, 'registry'), contractAddress);
        return {
            'lockup': () {
                return _client.call(contract: contract, function: contract.function('lockup'), params: []);
            }
        };
    }

    lockupContractFactory(String lockupContractAddress) {
        EthereumAddress contractAddress = EthereumAddress.fromHex(lockupContractAddress);
        final contract = DeployedContract(ContractAbi.fromJson(lockupAbi, 'lockup'), contractAddress);
        return {
            'getPropertyValue': (String propertyAddress) {
                EthereumAddress address = EthereumAddress.fromHex(propertyAddress);
                return _client.call(contract: contract, function: contract.function('getPropertyValue'), params: [address]);
            }
        };
    }
}

DevKitClientにEthereumプロバイダ用のURLを渡しつつ、クライアント生成して、各コントラクトの処理を呼び出す感じです。Dart語彙力低いので、ここもよくわからず実装している感じはあります。

一応パッケージの実装はこれで終わりです。

Flutter側から呼び出す

今回はpub.devやGitHubにもあげていないので、ローカル環境のファイルパスを指定して、使います。

pubspec.yamlに対象となるディレクトリのファイルパスを指定して、flutter pub getします。

diff --git a/pubspec.yaml b/pubspec.yaml
index 1de5307..23d2968 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -35,6 +35,8 @@ dependencies:
   # Use with the CupertinoIcons class for iOS style icons.
   cupertino_icons: ^1.0.2
   web3dart: ^2.3.3
+  devkit:
+    path: /Users/hattori/work/devkit.dart

 dev_dependencies:
   flutter_test:
$ flutter pub get

pubspec.lockにも反映されました。これで使用可能になります。

diff --git a/pubspec.lock b/pubspec.lock
index 536017b..730c4fe 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -141,6 +141,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "2.2.1"
+  devkit:
+    dependency: "direct main"
+    description:
+      path: "/Users/hattori/work/devkit.dart"
+      relative: false
+    source: path
+    version: "0.0.1"
   fake_async:
     dependency: transitive
     description:

アプリのメインの処理があるlib/main.dartを以下のように変更しました。

diff --git a/lib/main.dart b/lib/main.dart
index de3c27b..4f10121 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:http/http.dart';
 import 'package:web3dart/web3dart.dart';
+import 'package:devkit/devkit.dart';

 import 'abi/lockup.dart';
 import 'abi/registry.dart';
@@ -39,21 +40,16 @@ class _MyHomePageState extends State<MyHomePage> {

   void getBalance(String address) async {
     var apiUrl = "http://localhost:8545";
-    var httpClient = new Client();
-    var ethClient = new Web3Client(apiUrl, httpClient);
+    var client = new DevKitClient(apiUrl);

     EthereumAddress propertyAddress = EthereumAddress.fromHex(address);

-    EthereumAddress registryContractAddress = EthereumAddress.fromHex('0x1D415aa39D647834786EB9B5a333A50e9935b796');
-    final registryContract =
-      DeployedContract(ContractAbi.fromJson(registryAbi, 'registry'), registryContractAddress);
-
-    final lockupContractAddresses = await ethClient.call(contract: registryContract, function: registryContract.function('lockup'), params: []);
-    print(lockupContractAddresses);
-    final lockupContract =
-      DeployedContract(ContractAbi.fromJson(lockupAbi, 'lockup'), lockupContractAddresses[0]);
-    final lockupValue = await ethClient.call(contract: lockupContract, function: lockupContract.function('getPropertyValue'), params: [propertyAddress]);
-
+    final registryContract = client.registryContractFactory();
+    final lockupContractAddress = await registryContract['lockup']();
+    print(lockupContractAddress);
+    final lockupContract = client.lockupContractFactory(lockupContractAddress[0].toString());
+    final lockupValue = await lockupContract['getPropertyValue'](propertyAddress.toString());
+    print(lockupValue);
     _balance = (lockupValue[0] / BigInt.from(10).pow(18)).toDouble();
   }

これで実行すると昨日と同じプロパティのステーク数が表示されるようになります。

おわりに

最小限の処理をパッケージ化し、Flutter側から使ってみました。
devkit.dart拡充したいですね。まずは冬休みにDart勉強してDart力を高めようと思います。

Dart/Flutter、サクサク開発できておもしろいです!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0