-2

I have a marketplace contract which inherits from openzeppelins ownable.sol and i want to check access to the listNFT function to only be done by the owner of the contract. I tried the onlyOwner modifier which didn't work raising 'the caller not owner' error. Then i tried to understand the exact values of msg.sender and owner() and build my own event to track the values of msg.sender and owner. You can see the relevant code here.

    # Event to keep track of owner and caller
    event FunctionCall(
        address caller,
        address owner
    );

    // List the NFT on the marketplace
    function listNft( uint256 _tokenId, uint256 _price) public payable nonReentrant {

        # Emit event to inspect caller and owner
        emit FunctionCall(msg.sender ,owner());

        require(_price > 100, "Price must be at least 100 wei");

        # This line doesn't let me through and evaluates to false
        # require(msg.sender == owner(), "Must be owner");

      ...more code
    }

When i call the contract without the require owner statement I can inspect the events on polygonscan which gives the following

Polygonscan event

The event shows that msg.sender and owner are the same address, how can the require statement afterwards evaluate to false?

I tested casting msg.sender and owner() to address(msg.sender) and address(owner()) but it didn't work. What am I missing?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Fruot
  • 1
  • 1
  • what is `owner()` – Yilmaz Sep 17 '22 at 20:09
  • You should link to the actual contracts so we can verify all your assumptions. Because from what you described, an easy explanation is user error, e.g. you deployed the contract with the commented-out require using the same account you check with but the earlier contract was deployed using a different account, which is why it fails. – C S Sep 18 '22 at 04:35
  • owner() is the Getter methods from openzeppelin Ownable.sol – Fruot Sep 18 '22 at 08:13
  • Thats why i posted the polygonscan event to verify that owner and msg.sender are the same via the FunctionaCall event. – Fruot Sep 18 '22 at 08:15

1 Answers1

0

There was a problem with the signing methods. Earlier I signed transactions manually like this with Web3.py


  transaction = contract.functions.transferFrom(w3.toChecksumAddress(<PublicKey>),w3.toChecksumAddress(to),  token_id).buildTransaction({
        'from': acct.address,
        'nonce': w3.eth.get_transaction_count(acct.address),
    })
    gas = w3.eth.estimate_gas(transaction)
    transaction.update({'gas': int(gas*1.5)})
    signed_transaction = w3.eth.account.sign_transaction(transaction, private_key=<PRIVKEY>)
    tx_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction)
    tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)

After switching to the .transact() method and construct_sign_and_send_raw_middleware() from web3.py everything works. I am still stumped that the event gave out the correct msg.sender on polygonscan but as long as everything works I won't complain :)

TylerH
  • 20,799
  • 66
  • 75
  • 101
Fruot
  • 1
  • 1