署名確認データをOracleにアップするdApp

今回つくるもの

dAppで署名したデータを署名したメッセージをスマートコントラクトで確認し、Oracleにアップします。実現するシーケンスは下の図の通りですが、あくまでも実験的な目的で作成しています。

コードは以前の投稿OracleによるSmart Contractと外部サーバーとの連携を拡張して作ります。

作業としては以下を行います。

  • スマートコントラクトEmitOracleとやりとりするdAPpの実装
  • スマートコントラクトEmitOracle側での署名処理
  • スマートコントラクトからOracle向け(ならびにフロント側での確認も兼ねた)のイベント発行

実行環境は以下の通りです

$ truffle version
Truffle v5.1.0 (core: 5.1.0)
Solidity v0.5.12 (solc-js)
Node v10.16.2
Web3.js v1.2.2

スマートコントラクトEmitOracleとやりとりするdAPpの実装

GitHubのリポジトリをクローンして、配下のsrcフォルダでnpx create-react-app dappを実行して、クライアントを作成します。

~/git/Oracletest/src$ npx create-react-app dapp
npx: installed 91 in 3.247s

Creating a new React app in /home/hajime/git/Oracletest/src/dapp.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts...

> core-js@2.6.10 postinstall /home/hajime/git/Oracletest/src/dapp/node_modules/babel-runtime/node_modules/core-js
> node postinstall || echo "ignore"

> core-js@3.2.1 postinstall /home/hajime/git/Oracletest/src/dapp/node_modules/core-js
> node scripts/postinstall || echo "ignore"

+ react-dom@16.12.0
+ react@16.12.0
+ react-scripts@3.2.0
added 1475 packages from 693 contributors and audited 904933 packages in 46.419s
found 0 vulnerabilities

Success! Created dapp at /home/hajime/git/Oracletest/src/dapp
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd dapp
  npm start

Happy hacking!

これにより以下のようなディレクトリやファイルが作成されます。

GitHubにはJavaScriptの拡張子をReactに合わせてjsxに変えています。今回はあまり意味ありませんので、おまじない的なものです。

テンプレートに加えて、

  • drizzzleOptions.jsx
  • MyContainer.jsx
  • MyConsumer.jsx
  • MyComponent.jsx
  • middleware/index.js
    を作成し、コアの処理はMyComponent.jscに実装しています。スマートコントラクトのイベント処理はmiddleware/index.jsxでおこなっています。イベントを受け取ると、ReactのToas機能を使った以下の例のようなポップアップがブラウザ画面上に表示されます。

ちなみに、今回の例では、drizzleから利用できるようにスマートコントラクトコンパイル後のartifactsの出力先をtruffle-config.jsファイルの中で以下のように設定しています。

module.exports = {
  contracts_build_directory: path.join(__dirname, "src/dapp/src/contracts"),

このように設定することでdApp配下のcontractsフォルダに出力されます。

Compiling your contracts...
===========================
> Compiling ./contracts/EmitOracle.sol
> Compiling ./contracts/Migrations.sol
> Artifacts written to /home/hajime/git/Oracletest/src/dapp/src/contracts
> Compiled successfully using:
   - solc: 0.5.8+commit.23d335f2.Emscripten.clang

スマートコントラクトEmitOracle側での署名処理

今回のスマートコントラクトはEmitOracle.solとして実装しました。エラーチェックなどはここでは行っていません。

pragma solidity >=0.5.0 <0.6.0;

contract EmitOracle {
    event evError();
    event evStoreMessageHash(address, bytes32);
    function storeMessageHash(
            bytes32 msgHash,
            uint8 v,
            bytes32 r,
            bytes32 s)
        external
    {
        bytes memory garbagePrefix = "\x19Ethereum Signed Message:\n32";
        bytes32 hash = keccak256(
            abi.encodePacked(
                garbagePrefix,
                msgHash));
        address addr = ecrecover(hash, v, r, s);
        emit evStoreMessageHash(addr, msgHash);
    }
}

Truffle環境でコンパイルした出力が以下になります。

2_deploy_contracts.js
=====================

   Replacing 'EmitOracle'
   ----------------------
   > transaction hash:    0x0efe94addf3306b61a207089c4cb918f189ea972b5caf7992b9085778d64b8ab
   > Blocks: 0            Seconds: 0
   > contract address:    0xD2CFd001Ba9e1c6c469Da2528b2E8bcEaD71EaFe
   > block number:        3
   > block timestamp:     1573992534
   > account:             0x5268F2232368DDbA43541AA7a16A9C569D0f9D4f
   > balance:             99.98976518
   > gas used:            208389
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00416778 ETH

デバッグ用に下記を控えておきます。MetaMaskのトランザクションの相手先として、以下のスマートコントラクトのアドレスが表示されるので、確認しておくといいでしょう。

> contract address:    0xD2CFd001Ba9e1c6c469Da2528b2E8bcEaD71EaFe

Oracleサーバー側でのイベントパラメータ値の取り出し

Oracle側では、以下のコードでイベント待機します。

contract.events.evStoreMessageHash(
  {fromBlock: 0},

ブロックチェーンのスマートコントラクトで上記のイベントが発行されると、以下のイベント内容を受信できます。

event
{ logIndex: 0,
  transactionIndex: 0,
  transactionHash:
   '0x93d2e908c46c79daaabf55d0f26bc211177d427518b6dbd42e173e7b02f5dab7',
  blockHash:
   '0x9e84ce11bc67a94a9bee0aee72fcd6c9ec730070ea192deadaed219e25a1e93f',
  blockNumber: 7,
  address: '0xD2CFd001Ba9e1c6c469Da2528b2E8bcEaD71EaFe',
  type: 'mined',
  id: 'log_8612f9f6',
  returnValues:
   Result {
     '0': '0x04a329fb500fa491B4258aC468F37C1513D264ea',
     '1':
      '0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8' },
  event: 'evStoreMessageHash',
  signature:
   '0x7dbedf196038ad1a3c842579d950a51ef7d555f92d7d2b1be9533d753a6839e6',
  raw:
   { data:
      '0x00000000000000000000000004a329fb500fa491b4258ac468f37c1513d264ea1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8',
     topics:
      [ '0x7dbedf196038ad1a3c842579d950a51ef7d555f92d7d2b1be9533d753a6839e6' ] } }

動かしてみました

Truffle起動してブロックチェーンにスマートコントラクトをデプロイ

~/git/Oracletest$ truffle develop
Truffle Develop started at http://127.0.0.1:8545/

Accounts:
(0) 0x5268f2232368ddba43541aa7a16a9c569d0f9d4f
(1) 0x1598cf27b2d63e17fa30ce9cdac39835a600f3aa
(2) 0x4abfe47b1a8ae6e6b081726b91f3430476ac6c78
(3) 0x2ed5c2f4bc12f1b9cd4264ac7f59e92885232b8b
(4) 0xa2a8290cd545e90fa43adb97021c684a64016080
(5) 0x2a5bcd0e81c099ba976af542cfebff7f2b6815cc
(6) 0x3a5a783487a9e7d2e777c653fbc4be028a47d2fa
(7) 0xa6c698cf4d8d321659f29b5312908d96c298a3fc
(8) 0xc5dee7131510aa7058728f156880b82842ef8ac5
(9) 0x59dca29de60ecf413342f921dcf7922007beb2b3

Private Keys:
(0) 1e6be2c2e65a966a292edff239616d5dfaa24edec259f1dea43a5e70b2bf5ed6
(1) 43f22fe0ef713d1b9c83cb7cfa8a5ecb82ce9f8ee513fb22c747cc789e1027fc
(2) e45a976ba278ef07d9505d2d2b235676396d6700466dd0ea34719c0f18134213
(3) 746a13222f09fcdcd2dfe53a758cd314849bf463f2696dd84c12653fdaf084cd
(4) d600706c8bf78f10281fe4814a1162994715023356ecefcb69d78a068ebe2f64
(5) d3974684caf829d446e2a607a7599d95e17917b03c0f737fce0671f42f0ad583
(6) 4986bc0e2c86727ccf1334dd841fabd4a93c031c3dd193dad0fc5b6b6cdcb595
(7) d4e92ad94be0b9a91c2ac21356df014c501620456931c1533efca49502d3934b
(8) ba217cf769f8703e3267b4004ddb7eaeb6b04900af02ac13d001c74e12cc4ff3
(9) b7ea6d4ffed222291ea5c1fc3e4045490b48694ea253f1252c8d6651af963488

Mnemonic: digital smart swamp monster empower expire salute sustain scrap knock wing robot

⚠️  Important ⚠️  : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.

truffle(develop)> migrate --reset

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.

Oracleサーバーを起動

~/git/Oracletest/src/server$ npm run server

> oracletest@1.0.0 server /home/hajime/git/Oracletest/src/server
> webpack --config webpack.config.server.js

dAppフロントエンドを起動

~/git/Oracletest/src/dapp$ npm start

> oracletest@1.0.0 server /home/hajime/git/Oracletest/src/server
> webpack --config webpack.config.server.js

MetaMaskのアカウントは毎回レセットしておいて下さい。トランザクションが失敗してしまいます。

動作のさせ方は以下のようになります。

雑感

別の投稿でも書きましたが、dAppフロント側で今回の実装のままで署名するのは微妙そうなので、署名の方法については再度検討する必要があります。
また、動画で見られる通り、イベント発行時のポップアップがいっぱいでてきてしまうのでなんとかしないと。。。

コメント

タイトルとURLをコピーしました