0

I have 2 smart contracts A and B that I have defined in the same file.

B is used to instantiate A using the new keyword.

However, when I try to interact on Remix with the newly instantiated contract using its returned address, I see the type of the newly instantiated contract is actually B and not A.

Why is this happening?

As, the two contracts are defined in the same file so B should have the byte code for A. Right?

Also, the constructor for A is public, so I don't understand why the new contract is of type B, when it should be of type A.

//patient is analogous to A

contract patient is entity{
    mapping (string => address) patientIDToSC;

    constructor (address adr, string memory idname) public {
        id = idname;
        ethAddress = adr;
        entityType = "patient";
        RCAddress = RC3(msg.sender);
    }
    //other relevant functions
}

//RC3 is analogous to B

contract RC3{
    address payable owner;
    constructor(){
        owner = payable(msg.sender);
    }
    mapping(string => address) public entityIDToEthAddress;
    mapping(address => address) public ethAddressToContractAddress;

    function insertEntity(string memory name, uint entityType) public payable{
        if(entityType == 0){
            patient newPatientSmartContract;
            newPatientSmartContract = new patient(msg.sender, name);
            ethAddressToContractAddress[msg.sender] = address(newPatientSmartContract);
        }
    }
    //other relevant code
}

The problem is whenever I try calling insertEntity in RC3, instead of creating a patient contract, it creates another contract of RC3 type, or at least that's what it shows on Remix. Please help.

1 Answer 1

1

If you're referring to this line:

newPatientSmartContract = new patient(msg.sender, name);

Then, indeed it's creating a new patient contract, not RC3.

The same can be confirmed by invoking the public variables of patient contract using the newPatientSmartContract instance and storing the values of the same in the corresponding variables of RC3 contract, inside the insertEntity() function call, like:

idInRC3 = newPatientSmartContract.id();
entityTypeInRC3 = newPatientSmartContract.entityType();

When you check the values of idInRC3 and entityTypeInRC3, then they'll be having the exact same values that are being assigned to id and entityType in the constructor of patient contract.

As, the value of idInRC3 will be whatever being passed in the name param of insertEntity() (that will be further passed as the idname param in the constructor of patient contract).

And, the value of entityTypeInRC3 will be assigned as "patient" string (i.e., the exact same as what's being assigned to entityType in the constructor of patient contract).

The minimal code to test the same is:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.24;

//patient is analogous to A

contract patient {
    mapping (string => address) patientIDToSC;
    string public id;
    address ethAddress;
    string public entityType;
    RC3 RCAddress;

    constructor (address adr, string memory idname) {
        id = idname;
        ethAddress = adr;
        entityType = "patient";
        RCAddress = RC3(msg.sender);
    }
    //other relevant functions
}

//RC3 is analogous to B

contract RC3{
    address payable owner;
    string public idInRC3;
    string public entityTypeInRC3;

    constructor(){
        owner = payable(msg.sender);
    }
    mapping(string => address) public entityIDToEthAddress;
    mapping(address => address) public ethAddressToContractAddress;

    function insertEntity(string memory name, uint entityType) public payable{
        if(entityType == 0){
            patient newPatientSmartContract;
            newPatientSmartContract = new patient(msg.sender, name);
            ethAddressToContractAddress[msg.sender] = address(newPatientSmartContract);
            idInRC3 = newPatientSmartContract.id();
            entityTypeInRC3 = newPatientSmartContract.entityType();
        }
    }
    //other relevant code
}

P.S., You don't need to add the public visibility to the constructor, as constructors are public by default.

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.