以太坊彩票智能合约由于资金不足而恢复。我的代码在哪里消耗太多汽油?
我正在实验坚固,我面临一个无法找到解决方案的问题。 该计划应以预设价格让地址购买票,所有者可以启动“滚动骰子”功能,该功能随机选择获胜者并将资金转移到该地址。
我相信,通过映射而不是数组会更容易,但是获得数组的经验是该程序的主要目的。
当用户调用buyticket函数时,发生错误。根据我的回应,我相信合同的气体太多。有人可以告诉我为什么不起作用吗?我感谢有关该代码其余部分的其他帮助评论:)
预先感谢!
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Lottery {
constructor () {
owner = msg.sender;
}
address[] public Players;
address private owner;
uint public ticketPrice;
uint public price;
uint public nonce;
uint public variations;
address payable winner;
bool hasTicketAnswer;
event Winner(address _winner);
event PriceSet(uint _setPrice);
event TicketBought();
function setTicketPrice(uint _ticketPrice) public {
require(msg.sender == owner, "Only Owner...");
ticketPrice = _ticketPrice;
emit PriceSet(_ticketPrice);
}
function hasTicket(address _sender) private returns(bool) {
hasTicketAnswer = false;
for (uint i = 0; i < Players.length; i++) {
if (Players[i] == _sender) hasTicketAnswer = true;
}
return hasTicketAnswer;
}
function buyTicket() external payable {
require(ticketPrice > 0, "Price did not set, be patient...");
require(hasTicket(msg.sender) == false, "You cannot have two tickets...");
require(msg.sender.balance <= ticketPrice, "Insufficient funds...");
payable(address(this)).transfer(ticketPrice);
Players.push(address(msg.sender));
price += msg.value;
emit TicketBought();
}
function checkBalance() public view returns(uint) {
return address(this).balance;
}
function rollTheDice() public payable {
variations = Players.length;
winner = payable(Players[uint(keccak256(abi.encodePacked(msg.sender, nonce, block.timestamp))) % variations]);
winner.transfer(price);
emit Winner(winner);
}
receive () external payable {
}
}
I am experimenting with solidity and I faced an issue for what I could not find a solution.
The program should let addresses buy ticket at a preset price, and the owner can start the "roll the dice" function which randomly selects the winner and transfer the funds to that address.
I beleive that this program would be easier with mapping instead of array, but getting experience with array was the main purpose of this program.
The error happens when the user calls buyTicket function. Based on the response I beleive the contract comsumes too much gas. Can someone tell me why it doesnt work? I appreciate any other helping comment regarding the rest of the code:)
Thanks in advance!
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Lottery {
constructor () {
owner = msg.sender;
}
address[] public Players;
address private owner;
uint public ticketPrice;
uint public price;
uint public nonce;
uint public variations;
address payable winner;
bool hasTicketAnswer;
event Winner(address _winner);
event PriceSet(uint _setPrice);
event TicketBought();
function setTicketPrice(uint _ticketPrice) public {
require(msg.sender == owner, "Only Owner...");
ticketPrice = _ticketPrice;
emit PriceSet(_ticketPrice);
}
function hasTicket(address _sender) private returns(bool) {
hasTicketAnswer = false;
for (uint i = 0; i < Players.length; i++) {
if (Players[i] == _sender) hasTicketAnswer = true;
}
return hasTicketAnswer;
}
function buyTicket() external payable {
require(ticketPrice > 0, "Price did not set, be patient...");
require(hasTicket(msg.sender) == false, "You cannot have two tickets...");
require(msg.sender.balance <= ticketPrice, "Insufficient funds...");
payable(address(this)).transfer(ticketPrice);
Players.push(address(msg.sender));
price += msg.value;
emit TicketBought();
}
function checkBalance() public view returns(uint) {
return address(this).balance;
}
function rollTheDice() public payable {
variations = Players.length;
winner = payable(Players[uint(keccak256(abi.encodePacked(msg.sender, nonce, block.timestamp))) % variations]);
winner.transfer(price);
emit Winner(winner);
}
receive () external payable {
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
除了发现问题外,我还读了一些我想评论的东西。
您的问题
您遇到“资金不足”错误的原因是因为条件正在返回错误。您要要求售票处的余额小于或等于(&lt; =),何时应该超过或相等(&gt; =)。
假设爱丽丝的余额为0.05 ETH,并且与票价为0.001 ETH的合同相互作用...
观察
我很好奇,如果您故意以这种方式编码BuyTicket功能。它实际上要做的是检查MSG.Sender是否有足够的ETH在其钱包中购买票,这并不意味着用户在交易中有效发送ETH(可以使用交易中发送的WEI金额msg.value,您可以阅读有关它的更多信息在这里)。
)
我的最后一个观察结果是
应付(地址(this))。转移(ticketprice)
代码行,因为不必这样做,一旦应付函数收到ETH,就可以保存到合同...在那条线上,您只是签订了鲍勃的合同将ETH送到鲍勃的合同中,该合同只是无缘无故地浪费了气体毫无疑问问我
Besides probably finding the problem, I've read some things that I'd like to comment on.
Your problem
The reason why you're getting the "Insufficient funds" error is because the condition is returning false. You're asking the msg.sender balance to be less than or equal (<=) to ticketPrice, when it should be more than or equal (>=).
Let's say Alice has a balance of 0.05 ETH and interacts with the contract whose ticket price is 0.001 ETH...
Observations
I'm curious if you're intentionally coding the buyTicket function in that way. What it actually does is checking if the msg.sender has enough ETH to buy a ticket in its wallet, which doesn't mean that the user is effectively sending ETH in the transaction (the amount of wei sent in the transaction can be checked with msg.value, you can read more about it here).
My last observation is the
payable(address(this)).transfer(ticketPrice)
line of code, because it's not necessary to do so, once a payable function receives ETH, it is saved into the contract... In that line you're just making the Bob's contract to send ETH to the Bob's contract, which just wastes gas without reasonI hope I've helped with you and if I wasn't completely clear in any thing I've said don't doubt in asking me