2

I want to accept payments on my website. The idea is that for every user I create his own private key from a temporary address and when he sends some tokens to this address - I transfer money from this account to my one with the private key for which only I have access. But I don't have an idea of how to pay for transactions from a temporary account to my one without gas. I see only two ways that are not comfortable enough for me:

  1. Force users to send an additional 0.01 ETH to the temporary wallet after every transaction
  2. Send 0.01 ETH from my own wallet to the temporary wallet to allow the temporary wallet to send back tokens to me

Are there better ways?

3
  • why creating a private key? not seeing the point here, you can do it through a smart contract instead.
    – Adam Boudj
    Commented Dec 22, 2020 at 23:09
  • Could you provide an example of such contract?
    – Vassily
    Commented Dec 22, 2020 at 23:51
  • You can use meta-transactions, medium.com/@austin_48503/….
    – Ismael
    Commented Dec 23, 2020 at 19:04

1 Answer 1

1

You actually don't need to create/manage private keys for users or pay for their transactions when receiving tokens: you just need a contract that receives tokens (or ethers) so that you can manage afterwards what to do with them.

Below is an example of a simple smart contract that registers ERC20 token addresses and receives either ERC20 tokens or ethers:

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";

contract Example {

    address public owner;
    address private ZERO_ADDRESS = 0x0000000000000000000000000000000000000000;
    mapping(string => address) public contractAddressERC20;
    
    constructor() public {
        owner = msg.sender;
    }

    //Register the contract address of an ERC20 Token
    function registerTokenERC20(string memory tokenName, address tokenContractAddress) external onlyAdmin() isToken(tokenName) {
        require(contractAddressERC20[tokenName] == ZERO_ADDRESS, 
            "token address is already registered");
        require(bytes(tokenName).length < 25, 
            "token name too long");
        contractAddressERC20[tokenName] = tokenContractAddress;
    }
    
    // Unregister the contract address of an ERC20 Token
    function unRegisterTokenERC20(string memory tokenName) external onlyAdmin() isToken(tokenName) {
        require(contractAddressERC20[tokenName] != ZERO_ADDRESS, 
            "token address is not registered yet");
        contractAddressERC20[tokenName] = ZERO_ADDRESS;
    }

     // Transfer ERC20 token from sender address to contract address
    function depositERC20Token(string memory tokenName, uint256 amount) external {
        require(contractAddressERC20[tokenName] != ZERO_ADDRESS, 
            "token is not registered into the platform");
        require(IERC20(contractAddressERC20[tokenName]).allowance(msg.sender, address(this)) >= amount, 
            "token amount to be transferred is not yet approved by User"); 
        IERC20(contractAddressERC20[tokenName]).transferFrom(msg.sender, address(this), amount);
    }

    // Transfer ether from sender address to contract address
    function depositEther() external payable {
        require(msg.value > 0, "amount must be greater than 0 ethers");
    }
    
    // Modifier to require that 'tokenName' is not empty
    modifier isToken(string memory tokenName) {
        bytes memory bytesTokenName = bytes(tokenName);
        require(bytesTokenName.length != 0, "tokenName can't be empty");
        _;
    }

    // Modifier to require that only the contract owner is allowed
    modifier onlyAdmin() {
        require(msg.sender == owner, "only admin");
        _;
    }
    
    // Get contract balance in weis
    function getBalance() public view returns (uint256) {
        return payable(address(this)).balance;
    }
}

Some considerations:

  1. You need to register first the address of the ERC20 smart contract that you will accept. For instance, if you are in Ropsten network:

     "DAI", "0xad6d458402f60fd3bd25163575031acdce07538d"
     "UNI", "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"
     "WETH", "0xc778417e063141139fce010982780140aa0cd5ab"
     ...
    
  2. You need to add withdrawal functions (admin only) to retrieve the deposited tokens or ethers and do whatever with them. Here you will have to pay the gas fees.

  3. Users have to approve first the transfer of their ERC20 tokens to this smart contract from their accounts (from a UI-perspective, check out how Uniswap does when swapping tokens).

Again, this is just a basic example to start from, but you can add much more features on top of this depending on your requirements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.