У меня есть 2 контракта, первый — это токен openzeppelin ERC20, а второй — лотерейный контракт, где игроки могут делать ставки на число.
pragma solidity ^0.8.4;
import "./Token.sol"; //import ERC20 token
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract Lottery is Ownable {
Token token;
constructor(Token _token) public {
token = _token;
}
// store information about player's bet
struct PlayersStruct {
uint betAmount;
uint betOnNumber;
}
mapping(address => PlayersStruct) public balances;
function enterLottery(string memory _betOnNumber) public payable {
address player = msg.sender;
uint amount = msg.value;
// transfer token from player's wallet to lottery contract
token.transferFrom(player, address(this), betAmount);
balances[player].betAmount += amount ;
balances[player].betOnNumber = _betOnNumber;
}
И вот как я это называю из ReactJS
async function stakeBet() {
const amount = ethers.utils.parseEther("10");
const maxAmount = ethers.utils.parseEther("1000000");
// approve token once so player can save on gas in future
await token.approve(stakingContract.address, maxAmount);
// bet 10 tokens on number 20
await lottery.enterLottery(20, {value: amount,});
}
Я тестирую в тестовой сети Kovan.
В вашей функции stakeBet
вы вызываете эти функции по порядку:
await token.approve(stakingContract.address, maxAmount);
// bet 10 tokens on number 20
await lottery.enterLottery(20, {value: amount,});
Когда вы вызываете утверждение, вы фактически обновляете сопоставление allowance
. Сообщите в контракте, что вы разрешаете определенную сумму за разрешенный адрес. Это должно быть реализовано так:
function approve(address _spender, uint _value)public returns (bool success){
// allowance tells how many tokens can be sent
allowance[msg.sender][_spender]=_value;
// This event must trigger when a successful call is made to the approve function.
emit Approval(msg.sender,_spender,_value);
return true;
}
Передача токена или передача монет фактически обновляет состояние внутри контрактов. С помощью функции approve
вы обновили пособие. Теперь
token.transferFrom
должен быть реализован следующим образом:
// my address is allowing your address for this much token
mapping(address=>mapping(address=>uint)) public allowance;
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success){
// check the allowance
require(_value <=allowance[_from][msg.sender]);
// update the balances
balanceOf[_to]+=_value;
balanceOf[_from]-=_value;
allowance[_from][msg.sender]-=_value;
// emitting an event
emit Transfer(_from,_to,_value);
return true;
}
Все адреса кошельков Ethereum совместимы с ERC20. Более того, это означает, что каждый перевод ERC20 может происходить между двумя адресами кошелька Ethereum или адресами, совместимыми с ERC20. Обычно это включает в себя все блокчейны, совместимые с EVM. Вы отправляете токен weth, и пользователь может поменяться местами в метамаске:
Для 1-я часть вы сделали то, что намеревались сделать, т. е. вы установили разрешение на максимальную сумму, чтобы пользователю не приходилось каждый раз платить за вызывающую транзакцию для allow().
MetaMask запрашивает ваше разрешение на комиссию за газ (в ETH) за отправку токенов на сумму «betAmount» в контракт.
Я новичок в эфириуме, но сталкивался с подобными обстоятельствами в своих проектах. Так это в моем понимании.
Кроме того, для 2-я проблема, как я уже говорил ранее, MetaMask запрашивает ваше разрешение на оплату комиссии за газ (которую он берет в ETH, но фактическая передача токенов также должна иметь место. Только некоторое количество ETH тратится на «Газовые сборы».
У меня есть очень хорошая статья, обсуждающая то же самое. Ссылка: https://medium.com/ethex-market/erc20-approve-allow-explained-88d6de921ce9
Вы можете увидеть демонстрацию того, что я только что сказал. Вы можете видеть, что плата за газ взимается в ETH. Кроме того, если бы вы не установили лимит раньше на максимум, вам пришлось бы заплатить плата за газ два раза за транзакцию с вашим контрактом, сначала для вызова Approval() для лимита, а затем для получения количества переданных токенов «betAmount». к контракту.
Спасибо. Ваш ответ помогает с 1-й частью. Но что я имел в виду во второй части, так это то, что я хочу передать свой токен ERC20, но после одобрения Metamask отправляет ETH. Это не то, чего я хочу. Я хочу отправить свою монету.