Lloyd Ramos
Lloyd Ramos

Reputation: 11

A Lottery Solidity Smart Contract Accept token as payment instead of ether

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);
    _;
  }
}

I want o change the function

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

    players.push(msg.sender);
}

Instead of ether, user use our token/erc20 to enter the lottery

Upvotes: 0

Views: 1996

Answers (1)

Petr Hejda
Petr Hejda

Reputation: 43571

You can define an interface (in your contract) of the token contract. Since you're only going to be using the transferFrom() function, this is the only function that you need to define in the interface (no matter that the token contract contains other functions as well).

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

The you can execute the transferFrom() function of the token, passing it arguments:

  • from: the user executing your enter() function
  • to: your contract
  • amount: Assuming the token has 18 decimals (most tokens do), you can use the ether helper unit, because it effectively calculates "0.01 * 10^18 (or 10^16, or 10000000000000000) of the token smallest units", which is 0.01 of the token. Otherwise, you'll need to recalculate this number based on the token decimals.
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);
}

Important: Mind that the user needs to approve() your contract to spend their tokens beforehand (from their address), otherwise the token transfer would fail. There's a security reason for that, read more about it in the bottom part of this answer.

Upvotes: 1

Related Questions