.netethereumsoliditysmartcontractsnethereum

Fail to interact with smart contract as owner


I'm trying to interact with a smart contract (Solidity) as an owner. I tried first to do it through Nethereum in code, but I kept receiving the ownership error message I set in the owner modifier.

I tried then to interact with the contract through myetherwallet with the contract address and ABI, but I was still getting the same result.

I created four different functions to test it, and I will show it in code. The first uses the modifier, the second in function require code, the third is an if and else statement, and the fourth is open to all to see that the contract does react properly.

I also added a return ownerAddress() to see the contract owner is the same as my account. How can I fix this?

The results of the functions:

GetNumOne - return the error in the image.
GetNumTwo - return the error in the image.
GetNumThree - return 2.
GetNumFour - return 2 (working well).
GetAdmin - return the address of my account (the one i use to call the contract)

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.5.0  <0.9.0;

contract AdminIssue {
    address Owner;

    constructor()
    {
        Owner = msg.sender;
    }

    modifier OnlyAdmin {
        require(msg.sender == Owner, "Fail! only owner can access this function!");
        _;
    }

    function GetNumOne() public view OnlyAdmin returns(uint)
    {
        return 1;
    }

    function GetNumTwo() public view returns (uint)
    {
       require(msg.sender == Owner, "Fail! only owner can access this function!");
       return 1;
    }

    function GetNumThree() public view  returns (uint)
    {
        if(msg.sender == Owner)
            return 1;
        else
            return 2;
    }

    function GetNumFour() public pure returns(uint)
    {
        return 2;
    }

    function GetAdmin() public view returns (address)
    {
        return Owner;
    }
}

class Test
{
    private string contractAbi = "[{ \"inputs\": [], \"stateMutability\": \"nonpayable\",\"type\": \"constructor\" },{ \"inputs\": [], \"name\": \"GetAdmin\",\"outputs\": [ { \"internalType\": \"address\",\"name\": \"\",\"type\": \"address\" }],\"stateMutability\": \"view\",\"type\": \"function\" },{ \"inputs\": [], \"name\": \"GetNumFour\",\"outputs\": [ { \"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\" }],\"stateMutability\": \"pure\",\"type\": \"function\" },{ \"inputs\": [], \"name\": \"GetNumOne\",\"outputs\": [ { \"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\" }],\"stateMutability\": \"view\",\"type\": \"function\" },{ \"inputs\": [], \"name\": \"GetNumThree\",\"outputs\": [ { \"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\" }],\"stateMutability\": \"view\",\"type\": \"function\" },{ \"inputs\": [], \"name\": \"GetNumTwo\",\"outputs\": [ { \"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\" }],\"stateMutability\": \"view\",\"type\": \"function\" }]";
    private string contractAddress = "0x1cc5e67dab1c3844be03827433f3fa7129466853";

    public async Task<int> CallContract()
    {
        try
        {
            Account _account = new Account(AccountDetails._key, Chain.Rinkeby);
            Web3 _web3 = new Web3(_account, AccountDetails._url);
            Contract _contract = _web3.Eth.GetContract(contractAbi, contractAddress);
            Function _function = _contract.GetFunction("GetNumOne");

            var _result = await _function.CallAsync<int>();
            MessageBox.Show($"result: {_result}");
            return _result;
        }
        catch (Exception e)
        {
            MessageBox.Show($"fail to call contract: {e}");
            return -1;
        }
    }
}

Enter image description here


Solution

  • Add the "from" parameter in the function call. If you don't add it then the contract sees your address as "0x00000000000000". It seems like a wallet like myetherwallet cannot call owner-only functions.

    I'm adding the correct code.

    class Test
    {
        private string contractAbi = "[{ \"inputs\": [], \"stateMutability\": \"nonpayable\",\"type\": \"constructor\" },{ \"inputs\": [], \"name\": \"GetAdmin\",\"outputs\": [ { \"internalType\": \"address\",\"name\": \"\",\"type\": \"address\" }],\"stateMutability\": \"view\",\"type\": \"function\" },{ \"inputs\": [], \"name\": \"GetNumFour\",\"outputs\": [ { \"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\" }],\"stateMutability\": \"pure\",\"type\": \"function\" },{ \"inputs\": [], \"name\": \"GetNumOne\",\"outputs\": [ { \"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\" }],\"stateMutability\": \"view\",\"type\": \"function\" },{ \"inputs\": [], \"name\": \"GetNumThree\",\"outputs\": [ { \"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\" }],\"stateMutability\": \"view\",\"type\": \"function\" },{ \"inputs\": [], \"name\": \"GetNumTwo\",\"outputs\": [ { \"internalType\": \"uint256\",\"name\": \"\",\"type\": \"uint256\" }],\"stateMutability\": \"view\",\"type\": \"function\" }]";
        private string contractAddress = "0x1cc5e67dab1c3844be03827433f3fa7129466853";
    
        public async Task<int> CallContract()
        {
            try
            {
    
            Account _account = new Account(AccountDetails._key, Chain.Rinkeby);
            Web3 _web3 = new Web3(_account, AccountDetails._url);
            Contract _contract = _web3.Eth.GetContract(contractAbi, contractAddress);
            Function _function = _contract.GetFunction("GetNumOne");
    
            object[] _input = new object[0]; // function receive no parameters
            var _result = 
            await _function.CallAsync<int>("<publicAddress>", null, null, _input);
            
            MessageBox.Show($"result: {_result}");
                return _result;
    
            }
            catch (Exception e)
            {
                MessageBox.Show($"fail to call contract: {e}");
                return -1;
            }
        }