//tips
//smart contract
最後にswap完了時にevent情報をもとにuserへの通知を行えるようにする。
Dexのcontractでトークン送金後にemitで記載されているもの。
token.transfer(msg.sender, _amount);
emit buy(msg.sender, _tokenAddr, _cost, _amount);
App.jsのbuytoken,selltokenに追記する。
async function buyToken(){
const tokenAddr=tokenInst._address;
return new Promise((resolve,reject)=>{
dexInst.methods
.buyToken(tokenAddr,finalInput,finalOutput)
.send({value:finalInput})
.then((receipt)=>{
//eventを監視して通知を行う
const eventData=receipt.events.buy.returnValues;
//weiに直し、数値化する
const amountDisplay=parseFloat(web3.utils.fromWei(eventData._amount,"ether"));
const costDisplay=parseFloat(web3.utils.fromWei(eventData._cost,"ether"));
const tokenAddr=eventData._tokenAddr;
alert(`
Swap success! \n
Token address:${tokenAddr} \n
Amount:${amountDisplay.toFixed(7)} ${token} \n
Cost: ${costDisplay.toFixed(7)} ETH
`)
resolve();
})
.catch((err)=>reject(err));
});
async function sellToken(){
//dexからuserにtokenを渡すのにallowanceという制約がかかっているので
//token側からdexに許可を与えるケースを想定する
const allowance=await tokenInst.methods.allowance(user,dexAddr).call();
if(parseInt(finalInput)>parseInt(allowance)){
try{
await tokenInst.methods.approve(dexAddr,finalInput).send();
}catch(err){
throw(err);
}
}
//swap実装
try{
const tokenAddr=tokenInst._address;
const sellTx= await dexInst.methods
.sellToken(tokenAddr,finalInput,finalOutput)
.send();
//eventを監視して通知を行う
const eventData=sellTx.events.sell.returnValues;
//weiに直し、数値化する
const amountDisplay=parseFloat(web3.utils.fromWei(eventData._amount,"ether"));
const costDisplay=parseFloat(web3.utils.fromWei(eventData._cost,"ether"));
const _tokenAddr=eventData.tokenAddr;
alert(`
Swap success! \n
Token address:${_tokenAddr} \n
Amount:${amountDisplay.toFixed(7)} ETH \n
Cost: ${costDisplay.toFixed(7)} ${token}
`)
}catch(err){
throw(err);
}
これにより売買swap完了時にメッセージを表示することができた。
Kickstartとweb3経由でのインスタンスの生成について見比べていたが、特に変わったところはなかった。
dexInst=new web3.eth.Contract(abi.dex,dexAddr,{from:user});
のように基本的には引数にabiとアドレスなどを取る。
一方、provider接続を行うweb3インスタンスは
$(document).ready(async () => {
if(window.ethereum){
web3 = new Web3(Web3.givenProvider);
}
のみ記載していたが実際にはメタマスクを持たない人にも表示させたいのでelseでinfura経由でweb3インスタンス生成も付加してあげた方が親切であることがわかる。
import Web3 from "web3";
let web3;
if (typeof window !== "undefined" && typeof window.ethereum !== "undefined") {
// We are in the browser and metamask is running.
window.ethereum.request({ method: "eth_requestAccounts" });
web3 = new Web3(window.ethereum);
} else {
// We are on the server *OR* the user is not running metamask
const provider = new Web3.providers.HttpProvider(
"https://rinkeby.infura.io/v3/15c1d32581894b88a92d8d9e519e476c"
);
web3 = new Web3(provider);
}
export default web3;
一旦復習と比較はここまでにしてpolygonでのDappdeploy準備に入る。ethereumはガス代が高すぎて無理なため。
Maticのfaucetからtokenを獲得。
よく見てみるとmainnetだったのでtestnetで始めることにした。下記がメタマスクへの設定。
Mumbai Testnet
Network Name: Polygon Testnet
New RPC URL: https://matic-mumbai.chainstacklabs.com
ChainID: 80001
Symbol: matic
Block Explorer URL: https://mumbai-explorer.matic.today/
Remixを使うと簡単にdeployできそうなので実施してみる。
まずは下記をremixの新規ファイルとして貼り付け。
//define which compiler to use
pragma solidity ^0.5.0;
//contract name is MyFirstPolygonContract
contract MyFirstPolygonContract {
string private name;
uint private amount;
//set
function setName(string memory newName) public {
name = newName;
}
//get
function getName () public view returns (string memory) {
return name;
}
//set
function setAmount(uint newAmount) public {
amount = newAmount;
}
//get
function getAmount() public view returns (uint) {
return amount;
}
}
environmentをinjected web3とし、metamaskの現在の接続ネットワークにデプロイするようにする。
Deployをクリックするとmetamaskが起動するので、confirm。
metamaskのtransaction履歴からpolygon testnet scanを起動させて中身を確認。
きちんとdeployされていた。
Soucecodeが表示されないなあと色々探してみたらdeployerが自分でアップするもののよう。
すでにこれと同じものがdeployされていたので同じbytecodeはverifyできないとのエラーがscanから返ってきた。
きちんとコントラクト内容が同一のものは弾くようにできているらしい。
Remixではなく、ローカル環境などからdeployする方法も見つけた。
Truffle-config箇所に下記記述を加え、infuraでmumbaiのurlを取得しておけば、polygon testNetworkへのdeploy設定はできそう。
matic: {
provider: () => new HDWalletProvider(process.env.MNEMONIC,
`https://rpc-mumbai.maticvigil.com/v1/process.env.PROJECT_ID`),
network_id: 80001,
confirmations: 2,
timeoutBlocks: 200,
skipDryRun: true,
networkCheckTimeout: 100000,
},
},
一度infuraを使用して簡単なdeployが確認できたら、SVG形式の画像をデプロイしてみる。