Blockchain code Metaverse VR

Crypto×VR×SmartContract(414)

スポンサーリンク

//tips

//smart contract

Dexコントラクトを作成し、truffle compileしてコンパイルファイルを生成。

//SPDX-License-Identifier:MIT
pragma solidity 0.8.4;

import"./ERC20.sol";

contract Dex{

event buy(address account,address _tokenAddr,uint256 _cost,uint256 _amount);
event sell(address account,address _tokenAddr,uint256 _cost,uint256 _amount);

mapping(address=>bool)public supportedTokenAddr;

modifier supportsToken(address _tokenAddr){
require(supportedTokenAddr[_tokenAddr]==true,"this token is not supported");
_;
}

//対応可能トークンを定義
constructor(address[] memory _tokenAddr){
for(uint i=0;i<_tokenAddr.length;i++){
supportedTokenAddr[_tokenAddr[i]]=true;
}

}

//userのethを受け取り、他のトークンを返す
//ethを受け取るのでpayable
//ERC20を通じてcontructorで生成される各トークンにオリジナルのアドレスが設けられることになるので_tokenAddr
function buyToken(address _tokenAddr,uint256 _cost,uint256 _amount)external payable supportsToken(_tokenAddr){

//この時点ではERC20contructorでトークンの生成は完了している
//コントラクト内のアカウント取得。要確認。
ERC20 token=ERC20(_tokenAddr);

//この際のmsg.valueとは?
//msg.value is a member of the msg (message) object when sending (state transitioning) transactions on the Ethereum network.
//msg.value contains the amount of wei (ether / 1e18) sent in the transaction.
//トランザクション発生時の送付値。これはユーザーベース
require(msg.value == _cost,"insuficient fund");
require(token.balanceOf(address(this))>=_amount,"Token sold out");

//tokenを購入者へ送付
token.transfer(msg.sender,_amount);

emit buy(msg.sender,_tokenAddr,_cost,_amount);

}

function sellToken(address _tokenAddr,uint256 _cost,uint256 _amount)external supportsToken(_tokenAddr){

ERC20 token=ERC20(_tokenAddr);

//売り手が売り分を保有しているかの確認
require(token.balanceOf(address(msg.sender))>=_cost,"insufficient token balance");

require(address(this).balance >= _amount,"dex does not have enough funds");

//tokenを売主からdexへ送付。ERCには戻す必要がないため
token.transferFrom(msg.sender,address(this),_cost);

//call関数を呼ぶ
//これで上記のトランザクションをチェックできる
(bool success,)=payable(msg.sender).call{value:_amount}("");
require(success,"eth transfer failed");

emit sell(msg.sender,_tokenAddr,_cost,_amount);

}

}

ERC20とDexコントラクトを作成する中で、理解の辻褄が合わなくなってきたので整理。

ERC20コントラクトは複数トークンの生成と送付、各ユーザーの残高記録を行う部分で、各ユーザーのwalletそのものではない点に注意。

Dexを通して、各ユーザーが通貨の取引を行う際には、DexがERC20の保有残高などを確認しつつ、ユーザーのトランザクションを実行する。また、ERC20とのパスが必要なのでimportにより接続している。

この接続の時点ではすでにERCはチェーン状にデプロイされている状態なので、

ERC20 token=ERC20(_tokenAddr);

で取得するのはweb3接続しなくても大丈夫なのかは疑問。truffleだから大丈夫なのか。

また、transferfromで第三者間の送金メソッドを実行した際の検証を

(bool success,)=payable(msg.sender).call{value:_amount}("");

で行っていたが、このcall関数の仕組みがいまいちわからなかったので確認。

これを読んでいくと、やはりtruffleとweb3接続とでは若干やり方が違うよう。違うという点を認識しておく。

The regular way to interact with other contracts is to call a function on a contract object (x.f()).

All three functions call, delegatecall and staticcall are very low-level functions and should only be used as a last resort as they break the type-safety of Solidity.

ただ、これは今では送金の際にgasを記載する影響で.sendから.call{}()の形で記述が一般的に行われる形に移ってきているので注意。call()にも

All contracts can be converted to address type, so it is possible to query the balance of the current contract using address(this).balance.

(bool success,)=payable(msg.sender).call{value:_amount}("");
require(success,"eth transfer failed");

ここの箇所の由来は、

(bool success, bytes memory data) = callee.call(abi.encodeWithSignature("add(uint256,uint256)", _x, _y));
require(success);

にあり、calleeは別のコントラクトのaddressなので、そこのバイトコードの中身をabi.encodeWithSignatureで呼び出している。

実際に呼び出しだけでなく、送金もできるものなので注意が必要。

the abi object that contains encodeWithSignature() method is he standard way to interact with contracts in the Ethereum ecosystem.

When it is a function in the called contract, that function is called when the abi.encodeWithSignature() method is called. So in the code example in the question, the called contract has a function:function foo(string var1, uint256 var2){} that is called every time abi.encodeWithSignature("foo(string,uint256)", "call foo", 123) method is called in the caller contract.

また,callの後に(””)をつけるのは必ずstringを返さなければいけないからとのこと。

.call() needs 1 string argument, the function being called. The empty string is the way to call the fallback function. I

参考になる例が下記にあったので一部抜粋。

contract SendToFallback {
function transferToFallback(address payable _to) public payable {
_to.transfer(msg.value);
}

function callFallback(address payable _to) public payable {
(bool sent, ) = _to.call{value: msg.value}("");
require(sent, "Failed to send Ether");
}
}

このようにtransferがきちんと実行されているかを確認できる。

人気の記事

1

皆さん、ついに、エアラインでも、サブスクリプションが始まったのはご存じですか? まだ実験段階ですが、ANAが、定額全国住み放題サービスを提供する「ADDress」と組んで、国内線を4回まで定額利用可能 ...

2

無料でネットショップを開けるアプリとして多くの人に驚きを与えたBASE株式会社が、2019年10月25日東証マザーズに上場しました。2020年2月時点で90万店を超えるショップを抱えるまでに成長してい ...

3

2011年にサービスを開始してから圧倒的な成長率を誇るインテリア通販サイト 【FLYMEe/フライミー】を皆さんご存じでしょうか。 「自分のイメージするインテリア、本当に欲しいインテリアがどこにあるの ...

4

ついに、noteの月間アクティブユーザー数が4400万人(2020年3月時点)に到達しました。 そもそも、「note」とは、クリエイターが、文章やマンガ、写真、音声を投稿することができ、ユーザーはその ...

5

ボードゲームカフェが1日2回転で儲かるという記事をみつけたので興味を持ち、調べてみました。 まずは、需要がどれくらいあるのか、市場のようすからみていきましょう。 世界最大のボードゲーム市場はドイツで、 ...

-Blockchain, code, Metaverse, VR
-, ,

Copyright© BUSINESS HUNTER , 2023 All Rights Reserved Powered by AFFINGER5.