This can be done with ERC20. but could be tricky
The easiest way is to do it in the original standard ERC20 token contract.
Just add this function: (assume as in your question that 20 tokens are required to be able to save the data and that the payment should be done to the owner address)
function payToSave(bytes32 data) public return(bool){
balance[msg.sender] = balance[msg.sender].sub(20); // be sure to change the number to include the decimal points.
balance[owner] = balance[owner].add(20);
register[msg.sender] = data;
emit Transfer(msg.sender,owner,20)
return true;
}
but if you are not the owner of the token contract or the token contract is already deployed, you can create another contract with an instance of the token contract. Then use approveAndCall function already in standard ERC20. like this:
Assume the token contract is TheTokenContract
(you should add the interface of TheTokencontract in your new contract), then this function will do what you want:
function receiveApproval(address from, uint256 tokens, address token, bytes data) public {
TheTokenContract instanceContract = TheTokenContract(token);
instanceContract.transferFrom(from,owner,20);
register[msg.sender] = data;
}
In both examples, the mapping register is just a mapping that saves the data for each user, you can of course change this according to your needs.
Hope this helps.
EDIT after OP comment:
approveAndCall is in the token contract already if the contract is ERC20 compliant.
approveAndCall(address spender, uint tokens, bytes data) public returns (bool success)
Here spender
is your contract address. So user will call this function in the token contract and it will approve the value tokens
to be moved by your contract to the address that you decide. this function will then call the function receiveApproval
that is in your contract.
In short, users will execute approveAndCall in the token contract using the input of 20 tokens and the address of your contract. this function will call your contract on the function receiveApproval
as I wrote above. That is all.
Upon a successful transfer of an ERC20 token, an event containing the parties' addresses and the value amount transfered is emitted. The Transfer event looks like:
event Transfer(address indexed _from, address indexed _to, uint _value);
Your contract can listen to the token contract for Transfer events where your contract is the _to
parameter - you can do this off-chain using the web3 api watch event.
You may find these related questions helpful:
Detect token transaction to a contract
Call a smart contract payable function sending erc20 token
Best Answer
If I understand your problem correctly, You have an erc-20 standard token deployed, and now in another contract, you want to have functions for receiving/transferring that token.
AFAIK, you can't have any such function.
msg.value
is always the amount ofwei
send along with the transaction. So you can't have tokens asmsg.value
.However, you can have the amount of token as a function parameter.
If you have to support only one specific token transfer, you won't need to verify the type of token. You can have a function like
function tokenTransfer(unit tokenAmount)
. If you want to support multiple erc-20 tokens, you can have another parameter namedcontractAddress
as another function parameter.Yes, that is the clean approach to do so. I am not sure what your use case is, but the best way to transfer tokens is to call
transfer
function of that specific contract. But in case you want the same function in another contract you should call thetokenContract
internally when someone calls function of your contract. This will be easier than keeping track of balances in both contracts.