3
Help us understand the problem. What are the problem?

posted at

updated at

誰でも簡単にブロックチェーンアプリを作る。マイ残高確認アプリを作ろう

こんにちは。営業をやっていたりエンジニアっぽい事をやっています。ブロックチェーンをアプリに組み込むのって難しそうに感じますか?実は各ブロックチェーンプロジェクトからは開発用のSDKが公開されている事があり、これを利用することで簡単に組み込む事が出来ます。

今回の記事は マイ残高確認アプリを作ろう です。前回の記事の続きになるので、まだ読んでいない、やっていない方は以下の記事の手順を踏んでからこの記事に来て下さい

誰でも簡単にブロックチェーンモバイルアプリを開発する - Qiita
https://qiita.com

本記事は連載の最後です(短期連載)

誰でも簡単にブロックチェーンモバイルアプリを開発する
誰でも簡単にブロックチェーンアプリを作り、送金する
誰でも簡単にブロックチェーンアプリを作り、マイ残高確認アプリを作る

環境準備

端末

パソコン ... Windows/Mac
スマホ ... iOS/Android

環境

Node.js
Expo-cli@5.3.0

最初に

前回の記事では取り敢えずアプリにブロックチェーンを組み込んで、チェーン内で活動する為のアカウント作成まで行いました。一旦、問題なく前回の記事の内容を修了出来ているか、以下の通りまずは確認して下さい

前回作業をしたフォルダを開く

前回の記事の通りに作業をして頂いた場合、ホームディレクトリ(デスクトップやダウンロードのフォルダがある所)に作成されています。
以下の通り実行してみましょう

Macの方(ターミナルにて)

open ~/blockchain-project 

Windowsの方(コマンドプロンプトにて)

explorer %HOMEPATH%¥blockchain-project

前回作業した時のファイルはありますか?
もしなければ前回の手順を踏んでいないと思われるのでやり直すか探して下さい

送金用のコードを追加する
問題なく前回のファイルがあればファイル「App.tsx」をメモ帳(Windows) or テキストエディット(Mac)にて開いて下さい。開けたらコードを以下のように差し替えて下さい

App.tsx
import "./shim";
import { Button, StyleSheet, Linking, TextInput } from 'react-native';
import React, { useState } from "react";
import { StatusBar } from "expo-status-bar";
import { Address, NetworkType, RepositoryFactoryHttp } from "symbol-sdk";
import { View, Text } from "react-native";

type Value = {
  mosaicId: string;
  amount: number;
  networkType: NetworkType;
};

const example = async (address: string): Promise<Value> => {
  /**
   * まずはブロックチェーンにアクセスする為のノード(サーバー)に接続します
   * networkType = 接続したノードがメインネットかテストネットか?を返します
   * currency = 接続したブロックチェーンの基軸通貨情報を取得します
   */
  const nodeUrl = "https://test.hideyoshi-node.net:3001";
  const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
  const networkType = await repositoryFactory.getNetworkType().toPromise();
  const { currency } = await repositoryFactory.getCurrencies().toPromise();

  /**
   * 入力されたアドレスより残高情報を取得します
   * 取得した残高情報の数値はそのままだと使えません。どんな計算をしているかはこちらを参照ください
   * https://docs.symbol.dev/concepts/mosaic.html#divisibility
   */
  const info = await repositoryFactory.createAccountRepository().getAccountInfo(Address.createFromRawAddress(address)).toPromise();
  const mosaic = info.mosaics.find(e => e.id.toHex() === currency.mosaicId?.toHex());
  if (mosaic === undefined) {
    throw new Error("残高情報の取得に失敗しました");
  }
  const amount = mosaic.amount.compact() / Math.pow(10, currency.divisibility);

  /**
   * 結果を返します
   */
  return {
    amount: amount,
    mosaicId: currency.mosaicId?.toHex() as string,
    networkType: networkType,
  };
};

export default function App() {
  const [value, setValue] = useState<Value>({ amount: 0, mosaicId: "---", networkType: NetworkType.TEST_NET });
  const [address, setAddress] = useState<string>("");

  const onButtonPress = async () => {
    try {
      const v = await example(address);
      setValue({ ...v });
    } catch (e) {
      console.error(e);
    }
  };

  return (
    <View style={styles.container}>
      <Text style={{ textAlign: "center" }}>Hello Symbol BlockChain!!</Text>
      <View style={{ marginVertical: 10, alignItems: "stretch", width: "90%" }}>
        <TextInput value={address} onChangeText={setAddress} style={{ width: "100%", marginVertical: 30, borderBottomWidth: 0.5 }} placeholder="残高を確認するアドレスを入力" />
        <Text style={{ textAlign: "left", marginBottom: 30, color: "grey" }}>本デモ版で入力可能なアドレスはテストネットで発行されたものに限ります</Text>
        <Button title="確認開始" onPress={onButtonPress} />
        <View style={{ height: 10 }} />
        <View style={{ marginVertical: 30 }}>
          <Text style={{ textAlign: "left", marginVertical: 5 }}>対象モザイクID</Text>
          <Text style={{ textAlign: "left", marginVertical: 1 }}>{value.mosaicId}</Text>
          <Text style={{ textAlign: "left", marginVertical: 5 }}>只今の残高</Text>
          <Text style={{ textAlign: "left", marginVertical: 1 }}>{value.amount}</Text>
          <Text style={{ textAlign: "left", marginVertical: 5 }}>現在のネットワークタイプ</Text>
          <Text style={{ textAlign: "left", marginVertical: 1 }}>{NetworkType[value.networkType]}</Text>
        </View>
        <Button title="エクスプローラーで開く" disabled={address === ""} onPress={() => {
          Linking.openURL(`https://testnet.symbol.fyi/accounts/${address}`);
        }} />
      </View>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',

  },
});

補足
ブロックチェーンは多くのサーバーが接続先として稼働しています。コード内に https://test.hideyoshi-node.net:3001とありますが、今回はそのうちの一つを本記事向けに記載致しました。もしこのサーバーに繋がらなくなった際には以下ノードリストより他の稼働中のサーバーを探し接続して下さい
メインネット(本番環境) https://symbolnodes.org/nodes/
テストネット(検証環境) https://symbolnodes.org/nodes_testnet/

実行してみよう

以下画像のような画面が立ち上がったら成功です。早速押してみましょう。テストネットで発行したSymbolアカウントのアドレスを入力し、確認開始を押せば情報が取得出来ます

補足
アカウントの発行方法はこちら

なお一度もトランザクションを発行していないアドレスを入力してもエラーとなります。ネットワーク側に情報が登録されていないためです。


Screenshot_20220401-025817.png

これで無事にマイ残高確認アプリが完成致しました!!
CSSを変更すればもっと格好良く、オリジナリティ溢れる残高確認アプリも作ることが出来ます。是非色々お試し下さい

本記事の内容はここまでです。もっと深く勉強したい、もっと色々やってみたいという方は本記事最後にリンクしているTwitterアカウント宛に質問を投げてみるか、各種リファレンスをご確認下さい

最後に

今回コードの修正は全てOS標準のテキストエディターにて行いましたが、実際にはもっとちゃんとコードを編集する為のソフトがあります。私のオススメはVisual Studio Codeです。もっと機能開発をしていきたい、触っていきたいという方は是非こちらもインストールして色々試してみて下さい

オススメの記事、相談先のTwitterについて

ドキュメント

Twitter

Discord

最後にオススメ記事(私の記事ではありません)

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
3
Help us understand the problem. What are the problem?