彩票 Solidity 智能合约接受代币作为付款而不是以太币

时间:2021-05-24 09:39:49

标签: solidity

pragma solidity ^0.4.21;

contract Lottery {
  address public manager;
  address[] public players;

  constructor() public {
    manager = msg.sender;
  }

  function enter() public payable {
    require(msg.value > .01 ether);

    players.push(msg.sender);
  }

  function random() private view returns (uint) {
    return uint(keccak256(abi.encodePacked(block.difficulty, now, players)));
  }

  function pickWinner() public restricted {
    uint index = random() % players.length;

    players[index].transfer(address(this).balance);

    players = new address[](0);
  }

  function getPlayers() public view returns (address[]) {
    return players;
  }

  modifier restricted() {
    require(msg.sender == manager);
    _;
  }
}

我想更改功能

function enter() public payable {
    require(msg.value > .01 ether);

    players.push(msg.sender);
}

用户使用我们的 token/erc20 代替以太币进入彩票

1 个答案:

答案 0 :(得分:0)

您可以定义代币合约的接口(在您的合约中)。由于您只会使用 transferFrom() 函数,因此这是您需要在接口中定义的唯一函数(无论令牌合约是否包含其他函数)。

interface IERC20 {
    function transferFrom(address _from, address _to, uint256 _amount) external returns (bool);
}

您可以执行令牌的 transferFrom() 函数,向其传递参数:

  • 来自:执行您的 enter() 函数的用户
  • 至:您的合同
  • amount:假设令牌有 18 位小数(大多数令牌都有),您可以使用 ether 辅助单元,因为它有效地计算了“0.01 * 10^18(或 10^16,或 100000000000000000) token 最小单位”,即 token 的 0.01。否则,您将需要根据令牌小数重新计算此数字。
function enter() public payable {
    IERC20 token = IERC20(address(0x123)); // Insert the token contract address instead of `0x123`
    require(token.transferFrom(msg.sender, address(this), .01 ether));

    players.push(msg.sender);
}

重要提示:请注意,用户需要approve()提前使用您的合约(从他们的地址)花费他们的代币,否则代币传输将失败。这是出于安全原因,请在 this answer 的底部阅读更多相关信息。