坚固 - 执行恢复(如何在混音中调试)
我正在创建使用我自己的ERC20令牌的区块链彩票智能合约。
这个想法很简单。玩家购买他们想要的任何门票。购买的每个票都存储为一对地址和 TicketID 。
当经理调用 pickWinner()函数时,会生成一个随机号码,并选择一张票作为获胜。
一切都很好,直到我称 pickWinner()函数为止。尝试称呼它后,我会收到以下错误:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted { "originalError": { "code": 3, "data": "0x4e487b710000000000000000000000000000000000000000000000000000000000000032", "message": "execution reverted" } }
问题是,这不是告诉我问题在哪里。我不知道如何在不尝试逐线删除并查看问题的情况下进一步进行。
这是代码:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Lottery {
event TicketsBought(address playerAddress, uint256 quantity, uint256 ticketPrice);
event WinnerPicked(ticket ticket, uint256 amount);
struct ticket {
address walletAddress;
uint256 ticketId;
}
uint256 currentTicketId = 0;
address gamblinoAddress = 0xE9FEA6A6A1a8BB99E0C888c93A06D22f804A5fFA;
uint public ticketPrice = 50 * 10**18;
address public manager;
ticket public winner;
ticket[] public tickets;
uint256 public balance;
constructor() {
manager = msg.sender;
balance = 0;
}
function getPlayerAddresses() private view returns (address[] memory) {
address[] memory addresses;
for(uint i = 0; i < tickets.length; i++) {
addresses[i] = tickets[i].walletAddress;
}
return addresses;
}
function buyTickets(uint256 quantity) public payable {
uint256 amount = ticketPrice * quantity;
GamblinoToken gamblinoToken = GamblinoToken(gamblinoAddress);
uint256 allowance = gamblinoToken.allowance(msg.sender, address(this));
uint256 playerBalance = gamblinoToken.balanceOf(msg.sender);
require(playerBalance >= amount, 'Check token balance');
require(allowance >= amount, 'Check the token allowance');
balance = balance + amount;
for (uint i = 0; i < quantity; i++) {
ticket memory t = ticket(msg.sender, currentTicketId);
tickets.push(t);
currentTicketId++;
}
gamblinoToken.transferFrom(msg.sender, address(this), amount);
emit TicketsBought(msg.sender, quantity, ticketPrice);
}
function random() public view returns (uint) {
return uint(keccak256(abi.encodePacked(block.difficulty, block.timestamp, getPlayerAddresses())));
}
function pickWinner() public {
uint index = random() % tickets.length;
uint256 amount = balance;
GamblinoToken gamblinoToken = GamblinoToken(gamblinoAddress);
// the entitre balance of this contract to the winner.
gamblinoToken.transfer(tickets[index].walletAddress, balance);
// set balance to 0
balance = 0;
// set winner
winner = tickets[index];
// reset ticket id
currentTicketId = 0;
// clear players and start over.
delete tickets;
emit WinnerPicked(winner, amount);
}
function getTickets() public view returns (ticket[] memory) {
return tickets;
}
// restrict to only the manager (the contract creator)
modifier restricted() {
require(msg.sender == manager);
_;
}
}
interface ERC20Interface {
function totalSupply() external view returns (uint256);
function balanceOf(address tokenOwner) external view returns (uint balance);
function allowance(address tokenOwner, address spender) external view returns (uint remaining);
function transfer(address to, uint tokens) external returns (bool success);
function approve(address spender, uint tokens) external returns (bool success);
function transferFrom(address from, address to, uint tokens) external returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
contract GamblinoToken is ERC20Interface {
function totalSupply() public override view returns (uint256) {}
function balanceOf(address tokenOwner) public override view returns (uint) {}
function transfer(address receiver, uint numTokens) public override returns (bool) {}
function approve(address delegate, uint numTokens) public override returns (bool) {}
function allowance(address owner, address delegate) public override view returns (uint) {}
function transferFrom(address owner, address buyer, uint numTokens) public override returns (bool) {}
}
I am creating blockchain lottery smart contract that is using my own ERC20 token.
The idea is simple. Players buy any amount of tickets they want. Each ticket that is bought is stored as a pair of address and ticketId.
When the manager calls the pickWinner() function, a random number is generated and one ticket is chosen as the winning one.
All is working good until I call the pickWinner() function. After I try to call it I get the following error:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted { "originalError": { "code": 3, "data": "0x4e487b710000000000000000000000000000000000000000000000000000000000000032", "message": "execution reverted" } }
The problem is, it's not telling me where the problem is. I don't know how to proceed further without trying removing line by line and see where's the problem.
Here's the code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Lottery {
event TicketsBought(address playerAddress, uint256 quantity, uint256 ticketPrice);
event WinnerPicked(ticket ticket, uint256 amount);
struct ticket {
address walletAddress;
uint256 ticketId;
}
uint256 currentTicketId = 0;
address gamblinoAddress = 0xE9FEA6A6A1a8BB99E0C888c93A06D22f804A5fFA;
uint public ticketPrice = 50 * 10**18;
address public manager;
ticket public winner;
ticket[] public tickets;
uint256 public balance;
constructor() {
manager = msg.sender;
balance = 0;
}
function getPlayerAddresses() private view returns (address[] memory) {
address[] memory addresses;
for(uint i = 0; i < tickets.length; i++) {
addresses[i] = tickets[i].walletAddress;
}
return addresses;
}
function buyTickets(uint256 quantity) public payable {
uint256 amount = ticketPrice * quantity;
GamblinoToken gamblinoToken = GamblinoToken(gamblinoAddress);
uint256 allowance = gamblinoToken.allowance(msg.sender, address(this));
uint256 playerBalance = gamblinoToken.balanceOf(msg.sender);
require(playerBalance >= amount, 'Check token balance');
require(allowance >= amount, 'Check the token allowance');
balance = balance + amount;
for (uint i = 0; i < quantity; i++) {
ticket memory t = ticket(msg.sender, currentTicketId);
tickets.push(t);
currentTicketId++;
}
gamblinoToken.transferFrom(msg.sender, address(this), amount);
emit TicketsBought(msg.sender, quantity, ticketPrice);
}
function random() public view returns (uint) {
return uint(keccak256(abi.encodePacked(block.difficulty, block.timestamp, getPlayerAddresses())));
}
function pickWinner() public {
uint index = random() % tickets.length;
uint256 amount = balance;
GamblinoToken gamblinoToken = GamblinoToken(gamblinoAddress);
// the entitre balance of this contract to the winner.
gamblinoToken.transfer(tickets[index].walletAddress, balance);
// set balance to 0
balance = 0;
// set winner
winner = tickets[index];
// reset ticket id
currentTicketId = 0;
// clear players and start over.
delete tickets;
emit WinnerPicked(winner, amount);
}
function getTickets() public view returns (ticket[] memory) {
return tickets;
}
// restrict to only the manager (the contract creator)
modifier restricted() {
require(msg.sender == manager);
_;
}
}
interface ERC20Interface {
function totalSupply() external view returns (uint256);
function balanceOf(address tokenOwner) external view returns (uint balance);
function allowance(address tokenOwner, address spender) external view returns (uint remaining);
function transfer(address to, uint tokens) external returns (bool success);
function approve(address spender, uint tokens) external returns (bool success);
function transferFrom(address from, address to, uint tokens) external returns (bool success);
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
contract GamblinoToken is ERC20Interface {
function totalSupply() public override view returns (uint256) {}
function balanceOf(address tokenOwner) public override view returns (uint) {}
function transfer(address receiver, uint numTokens) public override returns (bool) {}
function approve(address delegate, uint numTokens) public override returns (bool) {}
function allowance(address owner, address delegate) public override view returns (uint) {}
function transferFrom(address owner, address buyer, uint numTokens) public override returns (bool) {}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论