見出し画像

Lisk Elements で遊ぼう #5

ニフレルは入場料がちょっと高いので、再入場可なのを利用して昼と夕方など時間をずらすのが良いと思う万博おじです。
※ホワイトタイガーのアクアちゃんのエサやりがみたい場合は朝並びましょう。

はじめに

前回はデリゲートの情報を取得したので、今回は自身のvote状況を取得します。
前回のと組み合わせ、ランク順見たときに誰に投票していて誰に投票していないかもやります!
なので、ちょっと後半、処理がいろいろ出てきますがお付き合いください😆

コーディング1

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Vote</title>
    <script src="https://js.lisk.io/lisk-elements-2.0.0.min.js"></script>
    <script type="text/javascript">
      const client = lisk.APIClient.createMainnetAPIClient();
      const getVotes = () => {
        // <div id="contents"></div>内をクリア
        document.querySelector('#contents').innerHTML = '検索中です..';
        
        // 入力されたLisk AddressのVote状況を取得
        const address = document.querySelector('#liskAddress').value;
        client.votes.get({
          address: address,
          limit: 101
        })
        .then(res => {
          // 取得結果を<div id="contents"></div>内に表示
          document.querySelector('#contents').innerHTML = '';
          const pretag = document.createElement('pre');
          pretag.innerHTML = JSON.stringify(res.data, null , 2);
          document.querySelector('#contents').append(pretag);
        }).catch(err => {
          document.querySelector('#contents').innerHTML = '検索に失敗しました。';
        });
      }
    </script>
  </head>
  <body>
    <div>
      <input type="text" id="liskAddress" placeholder="Lisk Address" style="width: 150px;"/>
      <button onclick="getVotes()">検索</button>
    </div>
    <div id="contents"></div>
  </body>
</html>

例のごとく適当な名前でHTMLファイルを作成したら、テキストボックスに自身のLiskアドレスを入れて「検索」ボタンを押しましょう。
どうでしょうか?自分のvote状況が表示されましたか?

ということで、今回のポイントはclient.votes.getです。
これがvote状況を取得するAPIですね。

条件について

limit
何人分取得するかを設定(未指定時は10人分、最大は101人分) 

address
どのLiskアドレスの情報を取得するかを設定
※今回はテキストボックスに入力したLiskアドレスの情報を取得

取得情報から読めること

address
Liskアドレス
※検索時に入れた値と同じ値

balance

保有枚数(例のごとく1億倍された値)

votesUsed
現在のvote数(最大101)

votesAvailable
vote出来る数(101 から votesUsed を引いた数)

votes
voteしているデリゲートの情報

votes 内の 
address
vote先のLiskアドレス

votes 内の balance
vote先の保有枚数(例のごとく1億倍された値)

votes 内の username
vote先のデリゲート名

これで対象のLiskアドレスのvote状況の取得が出来ましたね!
これに、前回のデリゲート情報の取得処理を混ぜます。

コーディング2

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Vote</title>
    <script src="https://js.lisk.io/lisk-elements-2.0.0.min.js"></script>
    <script type="text/javascript">
      const client = lisk.APIClient.createMainnetAPIClient();
      let votes;
      let offset = 0;
      
      /**
       * デリゲート情報取得
       */
      const getDelegates = async() => {
        try {
          // ランクの昇順で101人分のデリゲート情報を取得
          const result = await client.delegates.get({offset: offset, limit: 101,sort: 'rank:asc'});
          return result.data;
        } catch (err) {
          console.log(err);
          return [];
        }
      }
      
      /**
       * vote情報取得
       */
      const getVotes = async() => {
        try {
          const liskAddress = document.querySelector('#liskAddress').value;
          const result = await client.votes.get({address: liskAddress, limit: 101});
          
          // 取得した結果からLiskアドレスだけの配列を作る
          let voteAddress = [];
          result.data.votes.forEach(function(val){
            voteAddress.push(val.address);
          });
          return voteAddress;
        } catch(err) {
          console.log(err);
          return [];
        }
      }
      
      /**
       * 表示内容を取得
       */
      const getContent = async() => {
        // デリゲート情報取得
        const delegates = await getDelegates();
        
        // 画面描画
        let content = "";

        // 取得したデリゲート情報と取得済のvote情報を比較しながらHTML生成
        delegates.forEach(function(delegate){
          content += `<div>`;
          if (votes.indexOf(delegate.account.address) >= 0) {
            content += `<div style="display:inline-block;"><input type="checkbox" value=${delegate.account.address} checked></div>`;
          } else {
            content += `<div style="display:inline-block;"><input type="checkbox" value=${delegate.account.address}></div>`;
          }
          content += `<div style="width:100px;display:inline-block;">Rank:${delegate.rank}</div>`;
          content += `<div style="width:200px;display:inline-block;">${delegate.username}</div>`;
          content += `<div style="width:300px;display:inline-block;">${delegate.account.address}</div>`;
          content += `</div>`;
        });
        return content;
      }
      
      /**
       * 検索ボタン処理
       */
      const search = async() => {
        offset = 0;
        document.querySelector('#contents').innerHTML = '検索中です..';
        
        // vote情報取得
        votes = await getVotes();
        
        // 表示内容を取得して出力
        document.querySelector('#contents').innerHTML = await getContent();
        document.querySelector('#btn-next').style = "";
      }
      
      /**
       * さらに読み込むボタン処理
       */
      const next = async() => {
        offset += 101;
        
        // 表示内容を取得して出力
        document.querySelector('#contents').innerHTML += await getContent();
      }
    </script>
  </head>
  <body>
    <div>
      <input type="text" id="liskAddress" placeholder="Lisk Address" style="width: 200px;"/>
      <button onclick="search()">検索</button>
    </div>
    <div id="contents"></div>
    <div><button onclick="next()" id="btn-next" style="display:none;">さらに読み込む</button></div>
  </body>
</html>

組み合わせるとこんな感じになります。
コーディング1と同様にLiskアドレスを入力後に検索ボタンを押すと、自身がvoteしているデリゲートにチェックが付いた一覧が表示されますね。

簡単に説明

検索ボタン押下時
テキストボックスに入力されたLiskアドレスのvote情報とデリゲート情報(101位まで)を取得。
vote済みのデリゲートの場合はチェックボックスにチェックを付けて表示。

さらに読み込むボタン押下時
押下する度に表示中のデリゲート情報の次の101人の情報を取得し、検索ボタン押下時同様、vote済みのデリゲートの場合はチェックボックスにチェックを付けて表示。

これにさらにチェックのオン、オフでデリゲートの追加と解除を管理し、vote用トランザクションに流し込むことができればvote機能の完成です!
※実際にはエラー処理やらデザインやら気にすればするほど色々やることはありますが(笑)

どうでしょうか?
組み合わせた後の処理はJavaScriptを知っていてなんぼという感じではありますが、そこまでガッツリとプログラムを書かなくても、このような機能を作ることが出来るということがなんとなく理解出来たのではないでしょうか?
形になってくると面白いですね!

今日はここまで!
おつかれさまでした!


リンク

Lisk Elements ドキュメント(Votes)
※検索条件は Lisk Core ドキュメント 参照

応援

「おもろいやんけ!」と思ってもらえたら、コメントや万博おじへtweetしてくれると嬉しいです。
Lisk Japanもよろしくね!

この記事が気に入ったらサポートをしてみませんか?