Cryptocurrency Research Lab.

Cryptocurrency関連技術についての調査・研究

【Flare Networks】Coston Testnet ②Smart Contract

Flare Networksとは・・・

Flare Networksは、XRPにEthereum Virtual Machine (EVM)互換のスマートコントラクト機能を提供するものである。
XRPL上に直接スマートコントラクト機能を実装するのではなく、Flare Networks上にXRPにペッグされた『FXRP』というトークンを発行して、Flare Networks上で実現する仕組みのようだ。 Ethereum上のBTCペッグされたWBTC (Wrapped Bitcoin)や、あるいはBinance Chain上にペッグされたBTC(BEP2)やXRP(BEP2)と似たような感じだろうか。

現在のEthereumは、処理できるトランザクション数が多くないことやスマートコントラクトを実行するにもGas代が高いといった課題がある。これらの課題を改善すべく、数年にわたりEthereum 2.0の開発が進められているという話だけども、本番稼働までにはまだ時間がかかるだろう。

そこで、XRPを現在のEthereum上にペッグするというアプローチではなく、Ethereumが生み出したスマートコントラクト技術とそれを取り巻く周辺技術やツール群をうまく活用できないかと考え出されたのが、Ethereum Virtual Machine (EVM)を統合したFlare Networksではないかと勝手に推測する。

かつてのIBM PC/AT互換機のように、『World Computer』を冠するEthereumの、EVM互換となるスマートコントラクト実行基盤は今後も登場してくることだろう。
その一つがFlare Networksであり、本番稼働が近いBinance Smart ChainもまたEVM互換のようだ。

スマートコントラクトの作成

スマートコントラクトについては初学者なので、まだ手探り状態ではあるけれど、先月に書いた『【Ethereum】はじめてのSolidity』ように、RemixというWebアプリケーションを使って、まずは簡単なサンプルをつくってみたい。

f:id:halifax:20200829161653p:plain

どこかにあったWebページのサンプルを参考に、ここでは『Hello, Flare Networks』と出力するだけのコントラクトを試してみる。
こんな意味のないコントラクトをパブリックブロックチェーン上に刻もうものなら批判を受けてしまいそうな気もするが、Testnet上なのでご容赦願いたい。

HelloFlareNetworks.sol
pragma solidity ^0.4.0;

contract HelloFlareNetworks {
    string greeting = "Hello, Flare Networks";

    function hello() public view returns(string) {
        return greeting;
    }
}

コンパイル

つくったプログラムを配備する前に、あらかじめコンパイルしておく必要がある。

f:id:halifax:20200829161824p:plain

配備

先月書いた『【Ethereum】はじめてのSolidity』で、ブラウザ内の仮想環境上で動作確認するという手順は解説した。
Flare Networks上に配備して実行するには、配備・実行先を[JavaScript VM]ではなく、Flare Networksに変えればよいと推測できることから、少し試してみたところ、[Injected Web3]を選択して、MetaMaskやBrave BrowserのCrypto Walletsを経由して配備・実行ができそうなことが分かった。

Flare Networksに接続するには、あらかじめMetaMaskやCrypto Walletsのネットワークに設定を追加しておく必要がある。
前回書いた『【Flare Networks】Coston Testnet ①FXRP送金』、もしくは https://github.com/flare-eng/coston#xrp-on-metamask を参考にするとよいだろう。

[Deploy]ボタンを押すと以下のような確認画面が出る。
これまでJavaScript VMにしか配備したことが無かったのでTestnetとはいえ初めての配備なのでドキドキする。
しかも、配備先がEthereumではなくFlare NetworksのCoston Testnetなので、あらゆる点で分からないことがだらけで試行錯誤の連続だ。だけど、それがまた楽しくもある。

f:id:halifax:20200829162446p:plain

配備にはコストがかかるので、Crypto Walletsで[Confirm]をクリックしてGas代を支払う。

f:id:halifax:20200829163506p:plain

実行

Remix上で配備したプログラムは、[Deployed Contracts]から実行することができる。
サンプルプログラム内の関数に合わせて[hello]というボタンが表示されるので、実行すると右下のコンソールに実行ログが出力され、[hello]ボタンのすぐ下に実行結果が表示される。
どうやらちゃんと動いているようだ。

f:id:halifax:20200829163842p:plain

Web上でのスマートコントラクト実行

本当にブロックチェーン上にコントラクトが刻まれているのかをどのように確認できるのかを少し調べてみたところ、Webページからでもスマートコントラクトを実行できることが分かった。
『そりゃ当たり前だろ・・・』というつっこみを頂いてしまうかもしれないが、今までEthereum関連は触れてこなかったので、MetaMaskやCrypto Walletsなどのブラウザーウォレットと連携するWebサービスがいかに画期的なのか、ということにまるで気がついていなかった。

web3.js』というEthereum JavaScript APIが用意されており、これを使ってWalletと連携してFlare NetworksのTestnetに配備したスマートコントラクトを実行することができるようだ。

test.html

細かいエラーハンドリングはとくに行わないが、こんな感じで行けそうだ。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <button id="buttonExec" onclick="execute();">Execute</button>

    <script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>
    <script type="text/javascript">
      let web3js;
      window.addEventListener('load', function () {
          if (typeof web3 !== 'undefined') {
              web3js = new Web3(web3.currentProvider);
          } else {
            alert('Wallet not enabled.');
            document.getElementById('buttonExec').disabled = true;
          }
      });

      async function hello() {
        return new Promise((resolve, reject) =>{
          const contractAddress = "0xE1110d101f56F056cAe2F684713913D7D4ba341D";
          const abi = [{
            "constant": true,
            "inputs": [],
            "name": "hello",
            "outputs": [{
              "name": "",
              "type": "string"
            }],
            "payable": false,
            "stateMutability": "view",
            "type": "function"
          }];
          const contract = web3.eth.contract(abi).at(contractAddress);
          contract.hello.call((err, res)=>{
            if (err) {
              reject(err);
            } else {
              resolve(res);
            }
          });
        });
      }

      async function execute() {
        const greeting = await hello();
        alert(greeting);
      }
    </script>
  </body>
</html>
実行結果

f:id:halifax:20200829171020p:plain