Solidity – Make Value in Smart Contract Accessible Only by the Owner

contract-designremixsolidityweb3js

Hey everyone I am trying to implement the game Chinese Whisper as a smart contract.
It works as intended, but there are two issues I have.
I will explain the contract idea quickly:
So WalletA can send a message to WalletB by setting the whisper in the changeOwner function. I have the isOwner modifier which checks if the user is the owner and allows only that person to read the current whisper that WalletA set before.
Below is the contract in its current state:

contract ChineseWhisper {

    address private owner;
    string whisper;
    
    // event for logging
    event OwnerSet(address indexed oldOwner, address indexed newOwner);
    
    // modifier to check if caller is owner
    modifier isOwner() {
        require(msg.sender == owner, "Caller is not owner");
        _;
    }
    
    /**
     * @dev Set contract deployer as owner and set whisper to default value
     */
    constructor() {
        owner = msg.sender;
        whisper = "Let the game begin";
        emit OwnerSet(address(0), owner);
    }

    /**
     * @dev Changes owner and sets sent message as new whisper
     * @param newOwner address of new owner
     * @param message message for setting the whisper
     */
    function changeOwner(address newOwner, string memory message) public isOwner {
        emit OwnerSet(owner, newOwner);
        whisper = message;
        owner = newOwner;
    }

    /**
    * @dev Return current whisper
    * @return whisper of last owner
    */
    function getWhisper() public isOwner returns (string memory) {
        return whisper;
    }

    /**
     * @dev Return owner address 
     * @return address of owner
     */
    function getOwner() external view returns (address) {
        return owner;
    }
}

But there are two issues!

The first one is already when switching the owner, the Input (including the whisper) can be seen on etherscan (Here the example just click on input as UTF-8: https://rinkeby.etherscan.io/tx/0x7b5b9114d55bed65eb6ded536973846674cb6d5a46ff09282516451045cb78c3)

The second issue is that when using web3js to query the current whisper, it bypasses the isOwner function

const runGetWhisper = async (contract, walletAdress) => {
  contract.methods
    .getWhisper()
    .call({ from: walletAdress })
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.log(err.message);
    });
};

In theory, I can just change the "from" value so anybody that knows the currentOwner by calling getOwner() can use that walletAdress in order to query the current value.

Any ideas on how to fix both of the issues?

Best Answer

I agree with Meriadoc you can't secret anything in Ethereum.Your First issue If your contract is verified on etherscan then it always decoded in etherscan. your second issue solved by simple if else condition.

Check out the updated getWhisper function.

    function getWhisper() public view returns (string memory) {
        if (msg.sender == owner){
        return whisper;
        }
        else{
            return "You are not allowed";
        }
    }
Related Topic