0

I am trying to make a parent contract which deploys a child-contract for each unique caller (which does not inherit from parent contract, but calls one of the parent's functions).

I have looked up other posts with this error, and they usually involve breaking changes in solidity 0.5 and the address payable keyword. I have tried converting the address using the code in this example, but I have not been able to get rid of the error.

I know this use-case (PGP) does not make sense as-is, I have changed the code for simplicity. The layout of the .sol file contains two contracts (Parent -> PGPAccounts and Child -> PGPMultisig) and is essentially:

pragma solidity ^0.5.2;

contract PGPAccounts {

  // One PGPAccount exists for every unique Ethereum EAO in the "accounts" mapping 
    struct PGPAccount {
        bytes pubkey;            
        bool isLinked;          // flag field, to check existence of a mapping in the accounts mapping
    }

    mapping (address => PGPAccount) accounts;

    //  checks if _address has an associated pubkey, by referencing the 
    //  "isLinked" bool field of the associated Account in accounts mapping
    function hasAccount(address _address) public returns(bool) {
        return accounts[_address].isLinked;
    }

    // deploys a new instance of the PGPMultisig contract, linked to both 
    // msg.sender and the provided pubkey
    function newAccount(bytes calldata _pubkey) external {
        require(hasAccount(msg.sender) == false);   // require that the caller does not already have an account in mapping

        // Build a new Account instance with supplied _pubkey
        PGPAccount storage newPGPAccount = accounts[msg.sender];
        newPGPAccount.pubkey = _pubkey; // TODO: to resolve error, use mload 
        newPGPAccount.isLinked = true;

        // Create a new instance of PGPMultisig 
        PGPMultisig newPGPMultisig = new PGPMultisig({
              _owner: msg.sender,
              _verifier: address(this)
            });
    }


    function getPubKey(address payable _accountHolder) public returns(bytes memory pubKey) {
        require(accounts[_accountHolder].isLinked == true);   // default value for .linked is false if no account exists

        return accounts[_accountHolder].pubkey;
    }

    function () external payable {} 
}



// a PGPSecureAddress will be deployed by .newAccount() 
// for every unique caller to Accounts contract
contract PGPMultisig {

    address owner;                              // the Ethereum EOA
    address PGPverifier;                        // the PGPAccounts registry contact

    constructor(address _owner, address _verifier) public {
    owner = _owner;
    // PGPverifier = _verifier;
    // PGPverifier = address(uint160(_verifier));       // casts _verifier to payable address
    PGPverifier = address(uint160(address(_verifier))); // casts _verifier to payable address
    }

    // Forwards a PGPsig sent by owner to the PGPAccounts contract, 
    // and if approved (sig determined to be valid), _tx is executed
    // from this PGPMultisig
    function checkTXValid(
        bytes calldata _PGPsig,
        bytes calldata _desiredTXHash,
        address _contractAddress,       // address of ERC-20 contract for token transfer, if applicable
        address payable _to,            // recipient of desiredTX
        uint256 _value                  
        ) external {

        require(msg.sender == owner);   // only the registered owner can initiate a transaction

        // Determine whether msg.sender has an account 
        require(PGPverifier.hasAccount(msg.sender) == true); // ERROR IS HERE!

        // require that PGPsig is correct before sending

        // If the desired transaction is simply an ETH transaction,
        if (_contractAddress == 0x0000000000000000000000000000000000000000) {  

            // process ETH transaction 
        }

        // If contract address coresponds to an ERC-20, process ERC-20 transaction
        else {
             // process ERC-20 transaction
        }

    }

    function () external payable {} 

}

The place where I get the error in Remix ('Member "hasAccount" not found or not visible after argument-dependent lookup in address.') is for the following line:

require(PGPverifier.hasAccount(msg.sender) == true); // ERROR IS HERE!

As far as I know, I have tried all iterations of converting addresses manually to payable etc.

I would appreciate any help with this!

2 Answers2

0

Since the type of PGPverifier is address, you need to change this:

require(PGPverifier.hasAccount(msg.sender) == true);

To this:

require(PGPAccounts(PGPverifier).hasAccount(msg.sender) == true);
goodvibration
  • 26,003
  • 5
  • 46
  • 86
0

You need to cast PGPverifier to PGPAccounts before calling functions on it:

PGPAccounts (PGPverifier).hasAccount(msg.sender)

Or even better, declare PGPverifier as PGPAccounts:

PGPAccounts PGPverifier;
Mikhail Vladimirov
  • 7,313
  • 1
  • 23
  • 38
  • Thank you very much for the help, I accepted the other one because it was 2 minutes earlier, but I really appreciate you taking the time – doctor-gonzo Jan 22 '20 at 19:03