HiÐΞClassic

JPYC QR 決済アプリのコードのご紹介①

Nuko
4 years ago
JPYC QR 決済アプリのコードのご紹介①サマリーはじめにQR コードへ決済情報の埋め込み支払い用の URLQR コードを描画する方法実際のコードMetaMask 等のブラウザ拡張ウォレットと連携してアドレスを取得するスマートフォンの Metamask ブラウザで QR Pay を開くその他リンク

JPYC QR 決済アプリのコードのご紹介①

サマリー

  • JPYC QR Pay を実現するために書いたコードを紹介します
  • すべてのソースコードは github で公開していますので、pull-request を送ったり、ご自身でさらに素晴らしいアプリ開発のお役に立てると嬉しいです

はじめに

先日、JPYC を店頭などで簡単に決済できるよう JPYC QR Pay というウェブアプリを公開しました。この記事ではこのアプリを作製するにあたり、書いたコードや調べた内容について紹介したいと思います。

JPYC をはじめとした暗号通貨が広く日本で広まるためには、多くの便利なアプリケーションが登場し、利便性が向上したり、多くのユースケースが出てくることが重要であると考えております。

ソースコードはすべて github で公開してはおりますが、これから暗号通貨のアプリケーションを開発したいと思っている方に、少しでもご参考になればという思いで、少しブレイクダウンしてご紹介致します。

QR コードへ決済情報の埋め込み

リアル店舗で MetaMask を使って JPYC を送金する場合、従来であれば、支払者(お客さん)による決済情報の入力(Network の選択、通貨の選択、送金額の入力、送金先の入力)が必要でした。これは今後 JPYC の店舗決済が広まるうえで非常に大きなハードルとなると考えたので、QR コードにこれらすべての内容を埋め込むことにより、QR コードをスキャンしてタップするだけで送金できるようにしました。

こちらの記事でも少し書いています。

JPYC と xWIN の QR コード決済アプリを作ってみた

支払い用の URL

Ethereum と ERC20 トークンの支払い情報を URL で記載する方法は Ethereum Improvement Propos (EIP)-681 で定義されています。

EIP-681 URL Format for Transaction Requests

Polygon や Binance Smart Chain 上の ERC20 コインを送る場合は次のようなフォーマットになります。

ethereum:pay-[コントラクトアドレス]@[チェイン ID]/transfer?address=[送付先]&uint256=[送る金額]

なお、送金額は atomic unit (wei)で記載します。3e18 とは 3 x 1018 を意味します。(ガス代の指定などもできますが、ここでは省略します。)

例えば、3 JPYC on Polygon を私の投げ銭アドレスに送る場合は下記のようになります。

title variable example
JPYC コントラクトアドレス jpyc_contract_addr 0x6ae7dfc73e0dde2aa99ac063dcf7e8a63265108c
Polygon Chain ID polygon_chain_id 137
送付先アドレス dest_addr 0xafd382aCC893127D6fbb197b87453070Fc14D43d
送付額 amount 3e18

ethereum:pay-0x6ae7dfc73e0dde2aa99ac063dcf7e8a63265108c@137/transfer?address=0x330668C9EF59dD4F3b9b32EE978719Ee756D4b44&uint256=3e18

具体的なコードは次のようになります(不要かと思いますが。。。)。

let code =
  "ethereum:pay-" +
  jpyc_contract_addr +
  "@" +
  polygon_chain_id +
  "/transfer?address=" +
  dest_addr +
  "&uint256=" +
  amount +
  "e18";

QR コードを描画する方法

次に、前のセクションを QR コードに埋め込む方法についてご紹介します。

QR コードを JavaScirpt で描画するためのライブラリはいくつか出ていますが、私は html の canvas に描画できるQRCode.jsを使いました。またこれを fork して、支払いコードを簡易的に生成できるライブラリにしました(QRCodePay.js)。

実際のコード

QRCode.js を使う場合

HTML

<head>
  <script type="text/javascript" src="qrcodepay.min.js"></script>
</head>
~~~
<div id="qrcode"></div>

JavaScript

var qrcode = new QRCode(document.getElementById("qrcode"), {
    width: 300,
    height: 300,
  });

let code =
  "ethereum:pay-" +
  jpyc_contract_addr +
  "@" +
  polygon_chain_id +
  "/transfer?address=" +
  dest_addr +
  "&uint256=" +
  amount +
  "e18";

qrcode.makeCode(code);

QRCodePay.js を使う場合

QRCodePay.js では前のセクションで記載したトランザクションの URL 生成を組み込んでいますので、JPYC on Polygon の送付の場合は、送付額とアドレスだけ引数に指定するだけでQRコードを生成できます。

HTML

<head>
  <script type="text/javascript" src="qrcodepay.min.js"></script>
</head>

~~
<div id="qrcode2"></div>

JavaScript

new QRCodePay( document.getElementById("qrcode2"), amount, dest_addr );

MetaMask 等のブラウザ拡張ウォレットと連携してアドレスを取得する

web3対応のブラウザ拡張ウォレットを導入しているとethereumオブジェクトがインジェクトされています。

アドレスをとるだけの最小コードは次のようになります。accountsにアドレスの配列が入ります。通常はaccounts[0]を使えばよいと思います。

window.web3 = new Web3(ethereum);
await ethereum.enable();
accounts = await web3.eth.getAccounts();

redditかどこかで紹介されていたコードは次のようになっています。

/** web3 */
window.addEventListener("load", async () => {
  let accounts = [];
  if (window.ethereum) {
    window.web3 = new Web3(ethereum);
    try {
      await ethereum.enable();
      accounts = await web3.eth.getAccounts();
    } catch (error) {
      // User denied account access...
    }
  }

~~~

  if (accounts.length > 0) {
    set_dest_addr(accounts[0]);
  }
  get_dest_addr();
});

スマートフォンの Metamask ブラウザで QR Pay を開く

リアル店舗ではスマートフォンでQRコードを生成すると思いますが、Safari等のスマートフォンのデフォルトブラウザはMetaMask等のブラウザ拡張ウォレットに対応していません。そのため、スマートフォンでMetaMask連携をさせようとすると、MetaMaskのウェブブラウザでJPYC QR Payを表示する必要があります。

MetaMaskのブラウザで表示するという手順が面倒だと考えましたので、iPhoneのSafari等で開いた場合に、MetaMask内のブラウザに飛ばすようにしました。

実はMetaMaskのオフィシャルページにdeep link generatorがあり、MetaMask内のブラウザに飛ばしてくれる機能があります。

MetaMask deep link generator

今回は、前セクションのウォレットアドレスをとってくるコードの部分で、ethereumオブジェクトがなかった場合に、ポップアップ表示をしてMetaMaskで開くかどうかのリンクを表示しています。

具体的には次のコードです。

/** web3 */
window.addEventListener("load", async () => {
  let accounts = [];
  if (window.ethereum) {
    window.web3 = new Web3(ethereum);
    try {
      await ethereum.enable();
      accounts = await web3.eth.getAccounts();
    } catch (error) {
      // User denied account access...
    }
  }
  // Legacy dapp browsers...
  else if (window.web3) {
    window.web3 = new Web3(web3.currentProvider);
    accounts = await web3.eth.getAccounts();
  }
  // ↓ ここで、ポップアップを表示している
  else {
    $("#modal").modal("show");
  }

ポップアップのボタンを押したときにdeep linkに飛ばすのは次のコードです。

$("#openMetamask").on("click", () => {
  window.location.href =
    "https://metamask.app.link/dapp/nuko973663.github.io/jpycpayqr/";
});

その他

長くなったので、①と②に分けました。②では苦労した着金確認の方法について記載します。

リンク


コメント
いいね
投げ銭
最新順
人気順
Nuko
4 years ago
コメント
いいね
投げ銭
最新順
人気順
トピック
アプリ

Astar Network

DFINITY / ICP

NFT

DAO

DeFi

L2

メタバース

BCG

仮想通貨 / クリプト

ブロックチェーン別

プロジェクト

目次
Tweet
ログイン