withdraw()の実装
実現したいこと
指定されたアドレスに対し、トークンコントラクトのアドレスからETHを送金したい。
コード
とりあえずシンプルなコードを書いてみた。
code:withdraw
//第一引数:送金先アドレス、第二引数:送金するETH
function withdraw(address payable _to, uint256 withdraw_amount) public {
_to.transfer(withdraw_amount);
}
実験
トークンコントラクトには1ETHが入金済み。
とりあえず、以下のコマンドでaddress5に1ETH送金してみる ReportToken.deployed().then(instance => {instance.withdraw(accounts[5] ,1000000000000000000)})
結果
意味のわからんログがでる(途中で止めたのが次のスクリーンショット)
https://gyazo.com/a8f7d899529efcb66dcfdbd6cb9cb1df
最後まで待つとRuntimeErrorがでる
https://gyazo.com/a567a3f883e09f2ae856441fd63942cd
ganache上でも、Txは作成されていない。
withdraw()は機能していない模様
もちろん、ETHの動きもない
疑問
1.ときたまこのようなログがでるが、これは何が原因??
2.send と transferの違いって?→ 解決
3.value型の部分(transferの引数)にuint256型の値(withdraw_value)を代入していることが原因か?
考えたこと、やったこと
3.について考える。でもvalue型って宣言できない...
下のリンクを参考にしてみる
具体的にはconstructorの記述を関数に書き込む感じ
(msg.sender を _toに差し替え、mostSent を withdrae_amountに差し替え)
→結果同じ
→新たな疑問
やってることほぼ同じでは?
宛先のみ
直接、transferに値を渡してみる
code:withdraw
//第一引数:送金先アドレス
function withdraw(address payable _to) public {
_to.transfer(1000000000000000000);
}
ReportToken.deployed().then(instance => {instance.withdraw(accounts[5])})
気持ち悪いログはでない
https://gyazo.com/2b3c0ad761366e9d0fbcd4eeb074e9c9
Ganacheでも、Txが作成されたことがわかる
(Valueに値が入っていない?けど)
https://gyazo.com/fa883f6f6ad6adf0e38bde95e73ba498
送金先にも反映されている。(4ETH送金した)
コントラクトアドレスも残高が減っていることを確認した
https://gyazo.com/bf4ae33ea4552310b6da50aebbce3f55
送金額のみ
code:withdraw
//第一引数:送金先アドレス
function withdraw(uint withdrawAmount) public {
msg.sender.transfer(uint withdrawAmount);
}
ReportToken.deployed().then(instance => {instance.withdraw(1000000000000000000})
→例の意味わからんエラーがでる
引数なし
1ETHをコントラクトアドレスから、msg.senderに送金する
code:withdraw
//第一引数:送金先アドレス
function withdraw() public {
_to.transfer(1000000000000000000);
}
https://gyazo.com/94dae018ffee24d9ca14f99d6f1a9ba1
コントラクトアドレスからmsg.sender(address1)に1ETH送金された 結論
総金額の引数(withdrawAmount)が悪さしている
型の問題か?
uint256 withdrawAmount にしてみる
同じエラー
withdraw()の実装2
はじめに
ETHが入金される、purchaseToken()にて、トークンコントラクトの残高を記録するcontractAmountを追加した。
これにより、
これをwithdraw()に適応してみた。↓
code:token.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract ReportToken is ERC20 {
//event setup
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
//mapping
mapping(address => uint256) public balances;
mapping(address => mapping(address => uint256)) public allowed;
uint256 private contractAmount;
constructor(uint initialSupply) public ERC20 ('ReportToken', 'RPT'){
_mint(msg.sender, initialSupply);
}
function purchaseToken(address _to, uint256 _value) public payable returns (bool){
contractAmount += msg.value;
_mint(_to, _value);
emit Transfer(msg.sender, _to, _value);
return true;
}
function withdraw(address payable _to) public returns (bool){
_to.transfer(contractAmount);
return true;
}
}
コントラクトアドレスからaccounts5に対して、全額送金する。 ReportToken.deployed().then(instance => {instance.withdraw()})
こちらも、1ETHの増減の増減を確認した。
コントラクトアドレスの残高が0になって、accounts5に1ETH送金された。 やりたいこと
全額を1つのアドレスに全額送金したいわけではないので、任意の値で送金できるようにwithdrawの引数を増やしてみる。
code:s
function withdraw(address payable _to,uint256 sendAmount) public returns (bool){
_to.transfer(sendAmount);
return true;
}
→トランザクション自体が発火されない。
引数を
withdrawの発火
やりたいこと
ユーザーがボタンを押すと、ETHが送金される仕組みを実装中
具体的にはReportTokenコントラクトのwithdraw()をフロントから発火させたい。
以下がそのソース
withdraw()の仕様はこんな感じ
code:withdraw()
function withdraw(address payable userAddress) external {
userAddress.transfer(1000000000000000000);
}
フロントはNuxt.jsを使用
Scriptの中身はこんな感じ
code:front
async reward() {
let ret = await this.$reportTokenContract.methods
.withdraw(this.ownAddress)
.send({
from: this.$reporTokenAddress,
});
console.log(ret)
},
全体のソースはこちら
やったこと
発火させようとしたときの動画
????
code:error
inpage.js:1 MetaMask - RPC Error: Invalid parameters: must provide an Ethereum address.
確認したこと
・truffle consoleにてwithdraw()を用い正常に送金できた
・