Dev Protocol HandsOn - ステーキング一覧と引き出し

Kawakami
所要時間, 8分
初級

ステーキングしているプロパティの一覧表示とステーキングの引き出しをする

このハンズオンでは、ステーキングしているプロパティ情報をGraphQLから取得します。はじめにGraphQLを利用してステーキングしているプロパティ一覧を取得してみましょう。GraphQLは以下のリンクからアクセスすることができます。

メインネット環境
https://explorer.graphql.devprotocol.xyz/

account_lockupのwhereにaccount_address を指定して_ilikeの値に、以下のアドレスを設定して実行してください。いくつかのデータが取得できると思います

0x262A038D0bc05B4112c7D58BBfd407810bcfE2aB

このデータがステーキングしているプロパティのデータになります。このデータを利用してハンズオンを行なっていきます。
※Ropsten環境では現在account_lockupの検索は行えません。

はじめに今回作成する完成品を紹介します。

または、以下のURLにアクセスしてください
https://61lsg.csb.app/

このアプリケーションは、アクセス時にGraphQLからアクセスしている人がステーキングしているプロパティリストを取得して、最初の1件のみを表示させています。プロパティには「1 DEV」を引き出すボタンがあり、このボタンを押すとステーキングの引き出しが行われます。
※Ropsten環境では現在account_lockupの検索が行えないため、前回のハンズオンでステーキングしたプロパティのアドレスを直接指定しています。

それではハンズオンに入ります。 permalink

以下のURLにアクセスしてCodesandboxを開いてください。
https://codesandbox.io/s/your-staking-and-withdrow-build-hfzmb?file=/src/index.ts

左側のExploreからsrc/index.tsを選択して、ソースコードを表示させてください。
今回は①〜②をコーディングしていきます。

①:ここではページが表示されたらGraphQLからアクセスしている人がステーキングしているプロパティリストを取得してきます。スクロールしてgetStakingPropertyFromRopsten関数をみつけます。getStakingPropertyFromRopsten関数を以下のようにコーディングします。

async function getStakingPropertyFromRopsten(address) {
// GraphQLからプロパティ情報を取得する
const response = await fetch(
"https://devprtcl-event-ropsten.azurewebsites.net/v1/graphql",
{
method: "POST",
headers: {
"X-Requested-With": "xhr",
"Content-Type": "application/json",
"x-hasura-admin-secret": "SjV2f9iWscDxFj4KU"
},
body: JSON.stringify({
query: `
query MyQuery {
property_meta(limit: 3) {
name
property
}
}
`

})
}
);
const json = await response.json();
const convert = Array.from(json.data.property_meta).map((value) => {
return {
value: "20000000000000000000",
property_meta: value,
property_address: "0xb42612a90d05785c005b292f635871ca28aa10e0"
};
});
return convert;
}

GraphQLへの問い合わせはfetchを使用して問い合わせています。fetchbodyqueryでは、GraphQLで発行したクエリをそのまま貼り付けることができます。
※現在はRopsten環境ではステーキングしているプロパティ一覧を取得できないためコードに手を加えています。

コーディングが終わったら実行してプロパティ名が変わることを確認してみましょう

getStakingPropertyFromRopsten関数はRopsten環境のプロパティを取得するものです。メインネット環境からプロパティを取得するgetStakingPropertyFromMain関数もコーディングしてみましょう

getStakingPropertyFromMain関数を以下のように変更します。

async function getStakingPropertyFromMain(address) {
const response = await fetch("https://api.devprotocol.xyz/v1/graphql", {
method: "POST",
headers: {
"X-Requested-With": "xhr",
"Content-Type": "application/json"
},
body: JSON.stringify({
query: `
query Staking_properties {
account_lockup(
where: {account_address: {_ilike: "
${address}"}}
) {
value
property_meta {
name
}
property_address
}
}
`

})
});
const json = await response.json();
const allStakingInfo = json.data.account_lockup;
return allStakingInfo;
}

query内のwhereには、引数で渡されているaddressを設定します。

コーディングが終わったら、getStakingPropertyFromRopstenを呼び出している部分をgetStakingPropertyFromMainを呼び出すように変更してみましょう

  // ① Onboardしているプロパティの一覧を取得する
const properties = await getStakingPropertyFromMain(await getAccount());
// const properties = await getStakingPropertyFromRopsten(await getAccount());

コーディングが終わったら実行してみましょう。もしあたながStakes.socialでステーキングをしていればプロパティ名が変わります。

確認が終わったら、getStakingPropertyFromRopstenを使うように戻しておきます

②:次にWithdrowボタンが押された時の処理をコーディングしていきます。スクロールしてclickWithdrowButton関数をみつけます。clickWithdrowButton関数を以下のようにコーディングします。

async function clickWithdrawButton() {
const msg = document.getElementById("msg");
msg.classList.remove("hide");

const propertyAddress = this.dataset.propertyAddress;

// Clientを作成する
const provider = new Web3(window.ethereum);
const client = contractFactory(provider.currentProvider);

// ropstenネットワークのDevProtocolのアドレスを取得する
const registryContract = client.registry(addresses.eth.ropsten.registry);

// withdrawはlockupコントラクトに含まれているので、lockupコントラクトのアドレスを取得します
const addressLockup = await registryContract.lockup();

// 1DEV = 1000000000000000000に変換する
const amountBigNumber = BigNumber.from("1");
const amount = amountBigNumber.mul("1000000000000000000").toString();

try {
// withdraw(`プロパティのアドレス`, `引き出し額`)
const result = await client
.lockup(addressLockup)
.withdraw(propertyAddress, amount);

msg.classList.add("hide");

return result
? alert("引き出しに成功しました")
: alert("引き出しに失敗しました");
} catch (e) {
msg.classList.add("hide");
alert("もう一度Loginしてください");
console.log(e);
return;
}
}

前半は前回のハンズオンでもコーディングしたDev-kit-jsのclientを作成しているものです

  // Clientを作成する
const provider = new Web3(window.ethereum);
const client = contractFactory(provider.currentProvider);

// ropstenネットワークのDevProtocolのアドレスを取得する
const registryContract = client.registry(addresses.eth.ropsten.registry);

// withdrawはlockupコントラクトに含まれているので、lockupコントラクトのアドレスを取得します
const addressLockup = await registryContract.lockup();

今回は1DEVを引き出すのですが、DEVの単位を合わせるために18桁に変更させます。
桁数の大きな数値をJSは扱えないので、ライブラリを使用しています

  // 1DEV = 1000000000000000000に変換する
const amountBigNumber = BigNumber.from("1");
const amount = amountBigNumber.mul("1000000000000000000").toString();

lockupコントラクトのアドレスが取得できたらそのアドレスをlockupに渡し、withdraw関数を呼び出すことでステーキングの引き出しが行われます。

  // withdraw(`プロパティのアドレス`, `引き出し額`)
const result = await client
.lockup(addressLockup)
.withdraw(propertyAddress, "1");

result ? alert("引き出しに成功しました") : alert("引き出しに失敗しました");

以上でコーディングは終了となります。動作確認をしてみましょう。
はじめにログインを行い、Withdrawボタンを押して「引き出しに成功しました」とメッセージが表示されたら完了です。

Etherscanで確認してみましょう。Etherscanとはイーサリアムのトランザクションを確認できるWebサイトで、今回ステーキングしたトランザクションも記録されています。lockupコントラクトのアドレスで検索してログを見てみましょう。
https://ropsten.etherscan.io/address/0xf6ef27D18594228A851BfDF8e3139c4f90956E9A

🌈 この記事はお役に立ちましたか?

今後より良いコンテンツをお届けしていくために、ぜひご質問やフィードバックなどいただけると幸いです🌱
フォーラムはこちら

- Dev Protocol は全てOSSとして公開しています。ぜひIssueやPRを送ってください📢 時にバウンティがあります。
Dev ProtocolのGitHubはこちら

- Dev Protocol の改善提案(DIP)プロセスも公開されています。ぜひコメントをお待ちしています🌟
DIPはこちら