Photo by Shubham Dhage on Unsplash
How to Accept ERC20 tokens into a Smart Contract as Payment instead of Ether
payable function modifier provides a way to receive ethers in your smart contract. But what if you want to receive ERC20 Tokens into your smart contract. In this article, We will have a look at how you can do this.
In order to accept tokens into the contract, you need to import the token contract into your custom contract.
import "./ExampleToken.sol";
create a global variable to store the contract instance as shown below:
ExampleToken private token;
In the constructor of your contract, accept the address of the token contract, create a token contract instance and store it into the token
variable as given below:
constructor(address _token) payable {
owner = msg.sender;
TokenAddress = _token;
token = ExampleToken(_token);
}
Now create a function that is going to accept tokens as payment.
function AcceptTokens(uint256 _amount) public {
token.transferFrom(msg.sender, address(this), amount);
}
In order to use the transferFrom(address _from,address _to, uint256 _amount)
in AcceptTokens(uint256 _amount)
, we first need to first call approve(address _spender, uint256 _value)
from the ERC20 Token contract. To learn more about this, you can read this Article.
const Web3 = require("web3");
const RPC_URL = 'place RPC URL here';
const token_abi = 'place token contract abi here';
const token_address = 'place token contract address here';
const smart_contract_address = 'place smart contract address here';
const smart_contract_abi = 'place smart contract abi here';
const web3 = new Web3(RPC_URL);
const admin_address = " place admin EOA address here";
// creating token contract and Custom Smart contract Instance
const tokenContractInstance = new web3.eth.contract({
token_abi , token_address
});
const smartContractInstance = new web3.eth.contract({
smart_contract_abi , smart_contract_address
});
//calling approve method from ERC20 token contract
const approve_reciept = await tokenContractInstance.methods
.approve(smart_contract_address, 10 )
.send({from : admin_address});
// calling AcceptTokens method from your custom smart contract.
const AcceptTokensReciept = await smartContractInstance.methods
.AcceptTokens(10)
.send({ from : admin_address });
In this way, you can receive tokens in your smart contract as payment. This flow is known as the withdrawal flow. But as you can correctly point out, this flow makes a dull user experience as the user needs to conduct two transactions to accomplish a single task. Batch transactions to the rescue. We can batch both of these transactions (approve method call and AcceptTokens method call). To learn more about this, you can have a look at this article.