1

I can not run a function set to check if I am the owner of the contract.

I have tried a modifier

        string memory errorMessage = string(abi.encodePacked("Only the current owner (", addToString(currentOwner), ") can call this function.", addToString(msg.sender)));
        require(msg.sender == currentOwner, errorMessage);
    _;
    } 

I have a function to verify who the contract thinks is the owner

function getCurrentOwner() public view returns (address) {
        return currentOwner;
    }

i have tried the ownable solution. However when I send the transaction it appears to never set msg.sender or tx.origin they are always all 000s.

here is the code I use to call the contract.

<!DOCTYPE html>
<html>
<head>
  <title>Submit Transaction to Contract</title>
</head>
<body>
  <h1>Submit Transaction to Contract</h1>
  <form id="form">
    <label for="signedHash">Signed Hash:</label>
    <input type="text" id="signedHash" name="signedHash"><br><br>
    <label for="signature">Signature:</label>
    <input type="text" id="signature" name="signature"><br><br>
    <button type="submit">Submit Transaction</button>
  </form>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/web3.min.js"></script>
  <script>
          window.addEventListener('load', function() {
          const signedHashInput = document.getElementById('signedHash');
          const signatureInput = document.getElementById('signature');
          const storedSignedHash = localStorage.getItem('signedHash');
          const storedSignature = localStorage.getItem('signature');
          if (storedSignedHash && storedSignature) {
            signedHashInput.value = storedSignedHash;
            signatureInput.value = storedSignature;
      }
    });
    // Connect to MetaMask
    async function connect() {
      if (window.ethereum) {
        try {
          await window.ethereum.request({ method: 'eth_requestAccounts' });
          console.log('MetaMask connected.');
        } catch (error) {
          console.error(error);
        }
      } else {
        console.error('MetaMask not found.');
      }
    }

    // Submit transaction to contract
   async function submitTransaction() {
  const web3 = new Web3(window.ethereum);
  const contractAddress = '0x9d405a1d409f32867508fd3460f7d4708bf9ebba';
  const contractABI = [
  {
    "inputs": [ ],
    "name": "verifyOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function",
    "signature": "0x81c96a57"
  },
  {
    "inputs": [],
    "name": "getCurrentOwner",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  }
];

  const contract = new web3.eth.Contract(contractABI, contractAddress);
  const accounts = await web3.eth.getAccounts();
  const gasPrice = await web3.eth.getGasPrice();
  //const account = accounts[0].toLowerCase();
  const account = accounts[0]
  console.log("account = " + account);
  const currentOwner = await contract.methods.getCurrentOwner().call();
  console.log("currentOwner = " + currentOwner);

  const gasEstimate = await contract.methods.verifyOwnership().estimateGas();
  const transaction = {
    from: account,
    to: contractAddress,
    gas: gasEstimate,
    gasPrice: gasPrice,
    data: contract.methods.verifyOwnership().encodeABI()
  };
  const result = await web3.eth.sendTransaction(transaction);
  console.log(result);
 }



    // Handle form submission
    document.getElementById('form').addEventListener('submit', async function(event) {
      event.preventDefault();
      const signedHash = document.getElementById('signedHash').value;
      const signature = document.getElementById('signature').value;
      await submitTransaction();
    });

    // Connect to MetaMask when the page loads
    window.addEventListener('load', async function() {
      await connect();
    });
  </script>
</body>
</html>

here is the current modified contract with limit functions:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";

contract VidarCashCard is Ownable{
    address public currentOwner;
    bool public ownerVerfied;

    constructor() {
        currentOwner = msg.sender;
        ownerVerfied = false;
    }
    
    modifier onlyCurrentOwner {
        string memory errorMessage = string(abi.encodePacked("Only the current owner (", addToString(currentOwner), ") can call this function.", addToString(msg.sender)));
        require(msg.sender == currentOwner, errorMessage);
    _;
    }

    

    
function addToString(address _address) internal pure returns (string memory) {
    bytes memory result = new bytes(42);
    result[0] = '0';
    result[1] = 'x';
    for (uint i = 0; i < 20; i++) {
        uint8 value = uint8(uint160(address(_address)) / (2**(8*(19-i))));
        uint8 highNibble = uint8(value) / 16;
        uint8 lowNibble = uint8(value) - 16 * highNibble;
        result[2+2*i] = char(highNibble);
        result[3+2*i] = char(lowNibble);            
    }
    return string(result);
}

    function char(uint8 b) private pure returns (bytes1)  {
        if (b < 10) return bytes1(uint8(bytes('0')[0]) + b);
        else return bytes1(uint8(bytes('a')[0]) + b - 10);
    }

     receive() external payable {
            //All that is need to recive AVAX at the contracts address
    }
    
    function getCurrentOwner() public view returns (address) {
        return currentOwner;
    }


    function verifyOwnership() public onlyOwner {
        ownerVerfied =true;
    }
    

    

}

Like I said I have tried several hundred different ways to fix this and I never get any values set for msg.sender thus the account never matches the current owner even though the account I get in the html code and set to the from field matches the current owner in the contract and was the account used to deploy the contract.

Any help is greatly appreicated.

1
  • Can you add what gets printed in the console when you run it?
    – Julissa DC
    Commented Apr 9, 2023 at 2:03

1 Answer 1

0

You are not passing the correct sender address when calling the verifyOwnership() also you are not passing the from field correctly. You should pass the from field as the address of the current owner when using sendTransaction() to call the verifyOwnership() pass the from field as the address of the current owner. Also add the onlyOwner modifier in verifyOwnership() to ensure that only the owner of the contract can call this function.

This should work, here is your code:

async function submitTransaction() {
  const web3 = new Web3(window.ethereum);
  const contractAddress = '0x9d405a1d409f32867508fd3460f7d4708bf9ebba';
  const contractABI = [...];

  const contract = new web3.eth.Contract(contractABI, contractAddress);
  const accounts = await web3.eth.getAccounts();
  const gasPrice = await web3.eth.getGasPrice();
  const currentOwner = await contract.methods.getCurrentOwner().call();

  const gasEstimate = await contract.methods.verifyOwnership().estimateGas();
  const transaction = {
    from: currentOwner,
    to: contractAddress,
    gas: gasEstimate,
    gasPrice: gasPrice,
    data: contract.methods.verifyOwnership().encodeABI()
  };
  const result = await web3.eth.sendTransaction(transaction);
  console.log(result);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.