Lisk Elements で遊ぼう #7
今更ながらスプラトゥーン2を始めてTwitterのLisk界隈の方々とナワバリやったり、TipLisk WEBを修正してみたりして、type3トランザクション周りを書くことを若干忘れてた万博おじです。
ごめーんなさーい🙇
はじめに
今回はType3(cast vote)トランザクションを生成してLiskのチェーンにブロードキャストするところをやります😆
前回同様、コーディングサンプルはテストネット上で行っています。
アプリを作成する際は必ずテストネットで動作確認してからメインネットで使用するようにして下さい。
そしてこれまた前回同様、テストネットの参加方法はこちらをご覧ください。
※今noteで作成したものをもう少しきれいに見られるようにしたのがこちら
サンプルで使用するテストネット用アカウント
アドレス
3905013786800090105L
パスフレーズ
chicken problem whip mobile shield angry hard toast disease chronic code category
※自分で作成したアカウントを使用する際はパスフレーズは絶対に公開しないで下さい!
※テストネット上からメインネットで使用しているアカウント宛に送金してもメインネット上で使用できるLSKにはなりません。(テストネット上からメインネットで使用しているアドレス宛への送金自体をしないことをお勧めします)
コーディング
<!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.createTestnetAPIClient();
// ↓メインネットを使用する場合はこっち↓
// const client = lisk.APIClient.createMainnetAPIClient();
let votes;
let offset = 0;
let addDelegates = [];
let removeDelegates = [];
/**
* デリゲート情報取得
*/
const getDelegates = async () => {
try {
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 result = await client.votes.get({
address: "3905013786800090105L",
limit: 101
});
let publicKeys = [];
result.data.votes.forEach(function(val) {
publicKeys.push(val.publicKey);
});
return publicKeys;
} catch (err) {
console.log(err);
return [];
}
};
/**
* 追加処理
*/
const add = elem => {
if (elem.checked) {
addDelegates.push(elem.value);
} else {
addDelegates = addDelegates.filter((v) => v !== elem.value);
}
};
/**
* 取消処理
*/
const remove = elem => {
if (elem.checked) {
removeDelegates = removeDelegates.filter((v) => v !== elem.value);
} else {
removeDelegates.push(elem.value);
}
};
/**
* 表示内容を取得
*/
const getContent = async () => {
const delegates = await getDelegates();
let content = "";
delegates.forEach(function(delegate) {
content += `<div>`;
if (votes.indexOf(delegate.account.publicKey) >= 0) {
content += `<div style="display:inline-block;"><input type="checkbox" value=${delegate.account.publicKey} onclick="remove(this)" checked></div>`;
} else {
content += `<div style="display:inline-block;"><input type="checkbox" value=${delegate.account.publicKey} onclick="add(this)"></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 = "検索中です..";
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();
};
/**
* voteボタン処理
*/
const castvote = async () => {
try {
// vote用トランザクション生成
const transaction = await lisk.transaction.castVotes({
passphrase:
"chicken problem whip mobile shield angry hard toast disease chronic code category",
votes: addDelegates,
unvotes: removeDelegates
});
alert(
`↓生成したトランザクション情報↓\n${JSON.stringify(transaction)}`
);
// 生成したトランザクションをブロードキャスト
await client.transactions.broadcast(transaction);
alert(`voteしました!`);
} catch (err) {
// エラーがあったら表示
alert("入力内容に誤りがあります。");
alert(err);
}
};
window.onload = search;
</script>
</head>
<body>
<div>
<button onclick="castvote()">vote</button>
</div>
<div id="contents"></div>
<div>
<button onclick="next()" id="btn-next" style="display:none;">さらに読み込む</button>
</div>
</body>
</html>
適当な名前でHTMLファイルを作成したらそのファイルをブラウザで開いて下さい。
そうすると、delegateの一覧が表示されるはずです。
(#5で作成したサンプルに手を加えたものなので説明は省略します)
[サンプルソースの仕様]
・delegateの一覧を1~101位まで表示
・使用するテストネット用アカウントに記載のLiskアドレスがvoteしているものはチェックボックスにチェック付で表示
・チェック付からチェックを外した場合は、取消処理(関数:remove)を実行し、変数:removeDelegatesに追加
・チェックなしからチェックした場合は、追加処理(関数:add)を実行し、変数:addDelegatesに追加
・voteボタンを押下すると、使用するテストネット用アカウントに記載のLiskアドレスのvote状態を変更する
※voteボタンを押下後、Lisk Explorerなどでトランザクションの状態を確認してください。
メインネットで実行した場合→Lisk Blockchain Explorer(Mainnet)
テストネットで実行した場合→Lisk Blockchain Explorer(Testnet)
※使用するLiskアドレスを変更する場合は以下を修正してください。
関数:getVotes の address パラメータ
関数:castvote の passphrase パラメータ
[今回のポイント]
関数:castvote 内で実施しているlisk.transaction.castVotes。
これがvote用のトランザクション生成APIになります。
[パラメータ説明]
passphrase:Liskアカウントのパスフレーズ
例) chicken problem whip mobile shield angry hard toast disease chronic code category
votes:追加したいDelegateのPublickKeyを配列で設定
unvotes:取消たいDelegateのPublickKeyを配列で設定
どうでしょうか?
実際にはvoteの上限数(現在101)のチェックや、vote+unvoteの合計が33を超えないかどうかのチェック等が必要ですが、これでvoteアプリの完成です!
Lisk Elementsにはまだまだ色々な機能がありますが、今回でLisk Elementsに関するnoteは終わりです。
自分専用のLiskExplorer的な何かを作ることもできますね(*'ω'*)
※他の機能を使いたい場合でも、実行するAPIを調べて、適切にパラメータを指定するだけでなので興味がある方はLisk Elementsのドキュメントページをご覧くださいませ。
今日はここまで!
おつかれさまでした!
リンク
Lisk Elements ドキュメント(Transactions)
Lisk Elements ドキュメント(Transactions Resource)
次なに書こうかなー。。
応援
「おもろいやんけ!」と思ってもらえたら、コメントや万博おじへtweetしてくれると嬉しいです。
Lisk Japanもよろしくね!