Reputation: 103
My contract needs LINK token in order to function.
I want to let users fund LINK tokens to the contract via a function on the contract, and then do some logic for the user based on their funding.
How can i make this possible within the contract? I've tried to do calls like this.
LINK.balanceOf(walletaddress) does work, (It gets the link amount that's in the wallet). However, this function below does not work for some reason. It goes through and all, but with like empty data.
Metamask shows differently when i do the same call from their front-end button. (I assume it does the same as remix does)
https://testnet.bscscan.com/token/0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06#readContract
Here is how i try to get my contracts approval.
function approveTransfer(uint256 amount) public returns(string memory) {
uint256 approveAmt = amount * 10**18;
LINK.approve(_msgSender(),approveAmt);
approvedAmount = approveAmt;
}
Upvotes: 1
Views: 743
Reputation: 103
Okay, so i kept searching and searching and searching....
Until i found something amazing on their discord channel. (It's most likely written somewhere else too).
Harry | Chainlink
The LINK token is an ERC677 with transferAndCall functionality. So depending on how your smart contract function call that generates the random number is made, you can change it to be a 'transferAndCall' function instead of one that just does the VRF request, with the idea being that it will transfer enough LINK to fulfill the VRF request. Then in your consuming contract that does the VRF request, you implement the 'onTokenTransfer' function which simply calls your other function that does the VRF request. The end result of this is that when the user transfers LINK to the contract, it automatically does a VRF request all in the 1 single transaction.
So instead of the user pressing a button which calls the function in your consuming contract to do the VRF request, they press a button which does a 'transferAndCall' function from the LINK token contract, which in turn transfer LINK to your consuming contract and calls the 'onTokenTransfer' function in your consuming contract, which then calls your function to do the VRF request, which will be successfully fulfilled because it just received LINK for the request See an implementation of this in my previous hackathon entry "Link Gas Station"
https://github.com/pappas999/Link-Gas-Station/blob/master/contracts/WeatherCheck.sol https://github.com/pappas999/Link-Gas-Station/blob/master/src/relayer/relayer.js
So in short, this is possible because my contract have the
function onTokenTransfer(address from, uint256 amount, bytes memory data) public {
receivedTokenTransfer = true;
lastDepositer = from;
lastDepositerAmountInLink = amount / 10**18;
}
I can therefor instead of sending LINK to my own contract, i can send LINK to LINK's contract address, with the data payload transferAndCall , MycontractAddress, and the amount of LINK my contract should receive.
Upon this payment is sent, chainlink will send my contract the payment and call the function called onTokenTransfer
(On my contract). :)))
Ho0pe this helps someone in the future.
Upvotes: 4
Reputation: 43491
Not possible from within your contract, unless the external contract explicitly allows it or contains a security flaw using deprecated tx.origin
instead of msg.sender
.
See the last paragraph and code snippet in this answer to see how it could be misused if it were possible.
When your contract
executes LINK's function, msg.sender
in the LINK contract
is now your contract
- not the user.
Both transfer()
and approve()
(in order to call transferFrom()
later) functions rely on msg.sender
, which you need to be the user. But it's not - it's your contract.
When your contract
delegates a call to LINK's function, the state changes are stored in your contract
- not in the LINK.
But you'd need to store the state changes in the LINK contract, so this is not an option either.
Upvotes: 1