26
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

nemAdvent Calendar 2021

Day 12

ローコード開発ツールRetoolで爆速Symbolブロックチェーンウォレット開発(前編)

Last updated at Posted at 2022-03-06

今回はローコードアプリ開発プラットフォームとして注目されているRetoolを用いて、目的特化型機能限定ウォレットを爆速で開発してみましょう。

対象となる読者

JavaScriptで送金ができるようになったので、アプリを簡単に作成してみたい初心者の方
大体何でも作れるのでローコード開発の勘所だけ知って爆速開発したい上級者の方

JavaScriptでの送金についてはこちらの記事をご参考ください。

作れるもの

ブロックチェーンを活用したシステムの管理ツール的な位置づけです。
不特定多数に公開するというよりは、ブロックチェーンでビジネス展開する場合に
運用サイドにリリースするようなものを作る、とイメージすると分かりやすいかもしれません。

Retoolについて

主役となるローコード開発ツール「Retool」について簡単に説明しておきます。

Retoolは2017年に設立されたが、2020年10月に企業の評価額が10億ドルに達したユニコーン企業だ。

ローコードツールとしてRetoolを選択したのはJavaScriptによる拡張開発が容易なためです。
今回は以下のようなウォレットを爆速開発します。さてあなたは何分で作れるでしょうか?

image.png

基本機能
  • 秘密鍵を読み込んでアカウント管理
  • 送信先アドレス、XYM送信量、メッセージ欄入力
  • トランザクション送信と結果通知

環境構築

ブランクアプリケーションの作成

ホームから新しいアプリを作成します。
create a blank appを選択してください。
image.png

適当にアプリケーションの名前を付けましょう

image.png

symbol-sdkの設定

ヘッダー部分の…からscripts and stylesを選択します。
image.png

LibrariesタブからAdd newを選択し、
image.png

browserify化されたsymbol-sdkを指定します。

image.png

以下の文字列をコピペしてください。

https://xembook.github.io/nem2-browserify/symbol-sdk-pack-2.0.0.js

今回は私がメンテナンスしているこちらのライブラリを使用します。

次にJavaScriptタブを開き、下記のように windowに共通で使用したいスクリプトを埋め込んでおきます。

image.png

以下のスクリプトをコピーしてご利用ください。

window.NODE = "https://sym-test.opening-line.jp:3001";
//window.NODE = "https://sym-main-10.opening-line.jp:3001";

window.sym = require("/node_modules/symbol-sdk");
window.qr = require("/node_modules/symbol-qr-library");
window.op = require("/node_modules/rxjs/operators");
window.rxjs = require("/node_modules/rxjs");

window.repo = new sym.RepositoryFactoryHttp(NODE);
window.txRepo = repo.createTransactionRepository();
window.nsRepo = repo.createNamespaceRepository();
window.receiptRepo = repo.createReceiptRepository();
window.transactionService = new sym.TransactionService(txRepo, receiptRepo);

window.wsEndpoint = NODE.replace('http', 'ws') + "/ws";
window.listener = new sym.Listener(wsEndpoint,nsRepo,WebSocket);

(async() =>{
window.generationHash = await repo.getGenerationHash().toPromise();
window.epochAdjustment = await repo.getEpochAdjustment().toPromise();
window.networkType = await repo.getNetworkType().toPromise();
window.networkCurrency = (await repo.getCurrencies().toPromise()).currency;

})();
listener.open().then(() => {
  listener.newBlock();
});

他にも必要な呼び出しがあれば、以下の記事を参考に追加してみてください。

これで基本的な開発環境の構築は完了です。

画面配置

画面右側パネルからコンポーネントをドラッグし、以下のように配置します。

image.png

Header領域

[秘密鍵] Password:password1
[読込ボタン] Button:button1
[読込ボタンの右側にアドレス表示] Text:text1
[読込ボタンの右側に残高表示] Text:text2

Main領域

[送信先アドレス] Text Input:textInput1
[XYM送信量] Number Input:numberInput1
[メッセージ] Text Area:textArea1
[送信ボタン] Button:button2

秘密鍵を読み込んでアカウント管理

左下のパネルから New -> JavaScript queryを選択します。

image.png

下側パネルにquery1の編集画面ができるので、
password1に入力された秘密鍵を元に、アドレスと残高をそれぞれtext1、text2に出力するコードを記述します。

query1
const account =  sym.Account.createFromPrivateKey(password1.value,window.networkType);

const accountRepo = repo.createAccountRepository();
const accountInfo = await accountRepo.getAccountInfo(account.address).toPromise();
const amount = accountInfo.mosaics.find(mosaic => mosaic.id.toHex() === "3A8416DB2D53B6C8").amount.toString();

text1.setValue(account.address.plain());
text2.setValue(amount + " μXYM"); 

コードの記述を終えたら 実際に秘密鍵を入力してSave->Runと実行してみましょう。
うまく動かない場合はqueryの最後に

return accountInfo

などと入力してRunすることでデバッグ出力できます。
もう一つデバッグの方法として console.logを記述しておき、
開発者コンソールで出力した部分から呼び出し元のソースコードを捕捉してbreakpointを設置するという方法もあります。

query1が完成したら読込ボタンをクリックして右側パネルのInspectからEvent handlers->Addをクリックします。
自動的に最後に編集したquery1がTrigger queryとしてセットされます。
image.png

トランザクション送信と結果通知

指定された送信先、送信量、メッセージを指定して送信します。

const address = sym.Address.createFromRawAddress(textInput1.value);
const tx = sym.TransferTransaction.create(
    sym.Deadline.create(window.epochAdjustment),
    address, 
    [window.networkCurrency.createRelative(numberInput1.value)],
      sym.PlainMessage.create(textArea1.value),
    window.networkType
  ).setMaxFee(100);


const account = sym.Account.createFromPrivateKey(password1.value,window.networkType);
const signedTx = account.sign(tx,window.generationHash);

const transactionService = new sym.TransactionService(txRepo, receiptRepo);
transactionService.announce(signedTx,window.listener)
.subscribe(x=>{

  utils.showNotification({ 
    title: "成功", 
    description: "トランザクションが承認されました", 
    notificationType: "success",
  });
})

return "https://testnet.symbol.fyi/transactions/" + signedTx.hash

コードを入力したらqueryタブの Advancedを選択して
QUERY RUNNING FEEDBACKのShow a confirmation modal before runnnigをチェックして、
Confirmation messageに トランザクションを送信します。よろしいですか?などと入力しておきます。
image.png

query2の登録が完了したら、さきほどと同様にbutton2をクリックしてEvent handlersにquery2を割り当てます。

これですべての実装が完了しました。

実施

さて、それでは作成したウォレットを使用してみましょう。
画面右上のPreviewで実行できます。

Symbolは開発が簡単と表現されますが、その意味を十分に感じていただけたでしょうか?
大風呂敷を広げて巨額の資金で全て自分達で作ろうとする他のブロックチェーンとくらべて、Symbolブロックチェーンは「すでにユニコーンな企業の作り上げたプラットフォームと自由に接続可能」であるという点に興味をもっていただければ嬉しいです。ローコードだけでなく、今後はメタバースなどREST APIが提供されるあらゆるプラットフォームにスマートコントラクト検証可能なデータ参照機能を丸ごとぶち込むことができる、それがSymbolブロックチェーンです。

さて、後編ではウォレット開発に必須なノウハウをRetoolで実装していきます。こちらも爆速実装を予定しているので、ぜひともご期待ください。

26
14
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
26
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?