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!

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);
| improve this answer | |
  • Thank you very much, I tried this at one point but did not format it correctly – doctor-gonzo Jan 22 at 19:05
  • @doctor-gonzo: You're welcome. – goodvibration Jan 22 at 19:26
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;
| improve this answer | |
  • 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 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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