【发布时间】:2023-01-16 05:55:39
【问题描述】:
我正在构建一个彩票 dapp,我需要一些帮助来解决一个问题:我想使用我的自定义令牌而不是以太币来购买彩票。
以下是彩票合约:
pragma solidity >=0.7.0 <0.9.0;
contract Lottery {
uint256 public constant ticketPrice = 0.01 ether;
uint256 public constant maxTickets = 100; // maximum tickets per lottery
uint256 public constant ticketCommission = 0.001 ether; // commission per ticket
uint256 public constant duration = 30 minutes; // The duration set for the lottery
uint256 public expiration; // Timeout in case That the lottery was not carried out.
address public lotteryOperator; // the creator of the lottery
uint256 public operatorTotalCommission = 0; // the total commission balance
address public lastWinner; // the last winner of the lottery
uint256 public lastWinnerAmount; // the last winner amount of the lottery
address public allWinners; // get all lottery winners
uint256 public lotteryId; // get lotteryID
address payable[] public players; // return all Players
mapping(address => uint256) public winnings; // maps the winners to there winnings
address[] public tickets; //array of purchased Tickets
// modifier to check if caller is the lottery operator
modifier isOperator() {
require(
(msg.sender == lotteryOperator),
"Caller is not the lottery operator"
);
_;
}
// modifier to check if caller is a winner
modifier isWinner() {
require(IsWinner(), "Caller is not a winner");
_;
}
constructor() {
lotteryOperator = msg.sender;
expiration = block.timestamp + duration;
lotteryId = 0;
}
// return all winners
function getWinners() public view returns (address[] memory) {
return allWinners;
}
// return all the tickets
function getTickets() public view returns (address[] memory) {
return tickets;
}
// return wallet balance
function getBalance() public view returns (uint) {
return address(this).balance;
}
// return all players
function getPlayers() public view returns (address payable[] memory) {
return players;
}
function getWinningsForAddress(address addr) public view returns (uint256) {
return winnings[addr];
}
function getLotteryId() public view returns(uint256) {
return lotteryId;
}
function BuyTickets() public payable {
require(
msg.value % ticketPrice == 0,
string.concat(
"the value must be multiple of ",
Strings.toString(ticketPrice),
" Ether"
)
);
uint256 numOfTicketsToBuy = msg.value / ticketPrice;
players.push(payable(msg.sender));
require(
numOfTicketsToBuy <= RemainingTickets(),
"Not enough tickets available."
);
for (uint256 i = 0; i < numOfTicketsToBuy; i++) {
tickets.push(msg.sender);
}
}
function DrawWinnerTicket() public isOperator {
require(tickets.length > 0, "No tickets were purchased");
bytes32 blockHash = blockhash(block.number - tickets.length);
uint256 randomNumber = uint256(
keccak256(abi.encodePacked(block.timestamp, blockHash))
);
uint256 winningTicket = randomNumber % tickets.length;
address winner = tickets[winningTicket];
lastWinner = winner;
winnings[winner] += (tickets.length * (ticketPrice - ticketCommission));
lastWinnerAmount = winnings[winner];
operatorTotalCommission += (tickets.length * ticketCommission);
delete tickets;
expiration = block.timestamp + duration;
}
function restartDraw() public isOperator {
require(tickets.length == 0, "Cannot Restart Draw as Draw is in play");
delete tickets;
expiration = block.timestamp + duration;
}
function checkWinningsAmount() public view returns (uint256) {
address payable winner = payable(msg.sender);
uint256 reward2Transfer = winnings[winner];
return reward2Transfer;
}
function WithdrawWinnings() public isWinner {
address payable winner = payable(msg.sender);
uint256 reward2Transfer = winnings[winner];
winnings[winner] = 0;
winner.transfer(reward2Transfer);
}
function RefundAll() public {
require(block.timestamp >= expiration, "the lottery not expired yet");
for (uint256 i = 0; i < tickets.length; i++) {
address payable to = payable(tickets[i]);
tickets[i] = address(0);
to.transfer(ticketPrice);
}
delete tickets;
}
function WithdrawCommission() public isOperator {
address payable operator = payable(msg.sender);
uint256 commission2Transfer = operatorTotalCommission;
operatorTotalCommission = 0;
operator.transfer(commission2Transfer);
}
function IsWinner() public view returns (bool) {
return winnings[msg.sender] > 0;
}
function CurrentWinningReward() public view returns (uint256) {
return tickets.length * ticketPrice;
}
function RemainingTickets() public view returns (uint256) {
return maxTickets - tickets.length;
}
}
我尝试了以下“解决方案”,因为我只需要玩家购买门票但无法正常工作。因为我只需要 BuyTickets 函数来使用我的令牌,所以我有 IERC200 令牌地址。
function BuyTickets() public payable {
IERC20 token = IERC20(address(0x123)); // Insert the token contract address
require(
token.transferFrom(
msg.sender,
address (players),
msg.value % ticketPrice == 0,
string.concat(
"the value must be multiple of ",
Strings.toString(ticketPrice),
" Ether"
);
);
uint256 numOfTicketsToBuy = msg.value / ticketPrice;
players.push(payable(msg.sender));
require(
numOfTicketsToBuy <= RemainingTickets(),
"Not enough tickets available."
);
for (uint256 i = 0; i < numOfTicketsToBuy; i++) {
tickets.push(msg.sender);
}
}
任何帮助,将不胜感激。谢谢
【问题讨论】:
-
你能明确你的问题吗?您是否收到 ERC20 批准的问题?
-
它只适用于原生链代币。例如,如果我选择 BSC,它只允许我使用 BNB。我想使用 BSC 链中的另一个令牌而不是 BNB。
-
这是用于前端 BuyTickets 的函数: } ]);
-
我认为问题在那里,但无法弄清楚如何解决。谢谢