Is it possible, in Web3, to call a function which would require the user to first hold an ERC20 token before an image/text is visible? This would be similar to a password requirement, but instead of typing a password for the function to take effect, they would simply have to hold at least 1 ERC20 token. Now, in solidity I've been able to write a function that simply returns a text line if msg.sender has at least one ERC20. I want to do this but in web3 that would reveal a .jpg image of instructions:
function Reveal()override public view returns (string memory) {
require(ERC20Token(0xB0Bd09D....).balanceOf(msg.sender) >= 1 wei, "Error");
return 'Thank you for collecting an ERC20Token, the instructions will be sent out shortly';
}
On a website I have a .jpg image that has instructions written on it for the msg.sender, but only want them to have this image visible to viewers that hold a token. I have a button labeled "Reveal" with an OnClick that would fire something like this:
//sender presses "reveal" button, function checks if sender has at least 1 ERC20Token. If true, then "Instructions" image is made visible. If not, textbox appears.
contract.methods.reveal.call()({
if(ERC20Token(0xB0Bd09D....).balanceOf(msg.sender) >= 1 wei); {
document.getElementById("instructions").style.visibility="visible";
} else{
//Tell viewer that they require ERC20 token
buttonx.innerHTML = " You require at least 1 ERC20Token to proceed";
I'm probably going about this wrong in Solidity, but trying to figure it out. So far I've been using Metamask and selecting the current users account with window.web3.currentProvider.selectedAddress
which I should incorporate as well?
A) It is matter of taste but would it not be better to rename Reveal() to hasERC20() and return "bool"? Also for me it seems that "require" validation is a bit unnecessary in this situation so Solidity code could look like:
function hasERC20() public view returns (bool memory) {
return (ERC20Token(0xB0Bd09D....).balanceOf(msg.sender) >= 1);
}
B) You don't have to use ERC20Token() for the second time because it is already in Solidity code so the code could look like:
const msgSenderHasERC20 = await contract.methods.hasERC20().call();
if (msgSenderHasERC20){
document.getElementById("instructionsHasERC20_true").style.visibility="visible";
document.getElementById("instructionsHasERC20_false").style.visibility="hidden";
} else {
document.getElementById("instructionsHasERC20_true").style.visibility="hidden";
document.getElementById("instructionsHasERC20_false").style.visibility="visible";
}
C) You should not use "window.web3.currentProvider.selectedAddress" because it is DEPRECATED. Use ethereum.request({ method: 'eth_accounts' }) instead. The "currently selected" address is the first item in the array returned by eth_accounts.