0

Here is the problem I am facing.

I am calling some function of already deployed contract using its contract address.

Below are the lines of code :-

function registerYourBrand(string memory brand, address contract_address)public onlyOwner returns(bool){
        require(! exists[contract_address][brand], "You have already register your brand");
        (bool success, bytes memory brand_Owner)=address(contract_address).call(abi.encodeWithSignature("getOwner()"));
        require(success);
        address brandOwner = address(bytesToAddress(brand_Owner));
        brandOwners[brand] = brandOwner;
        contractAddresses[brand] = contract_address;
        tokenValue[brand] = 1;
        exists[contract_address][brand] = true;
        emit Register(brand,contract_address);
        return true;
    }

contract_address should be the address of the already deployed contract.

But when I am passing any other address here even if it is not contract address then also these lines are executed. But I am wonder, how is that possible.

I am testing it in remix. I have one deployed contract named 'AirToken' . In that contract getOwner() is one function. When I am calling this function from other contract using its contact_address, this is working fine and I am getting the AirToken owner's address successfully. But when i pass some other address that is not Contract Address, this line is executed succesfully but the returned value is some dummy value like 0x0000000000000000000000000000000000000001 this.

How getOwner() function is found if contract_address is not any contract address ?

4
  • What do you mean "I am getting the AirToken owner's address successfully"? How exactly are you getting this address? Your function returns true, and it is not even a read-only function anyway. May 5 '20 at 13:27
  • ""I am getting the AirToken owner's address successfully" means the address on which AirToken Contract is deployed is the owner adderss for that contract and getOwner() returning this address. I have checked in the logs, my registerYourBrand() function is returning true in case of non-contract address also. May 5 '20 at 13:38
  • How do you know that getOwner() has returned that address when it was invoked dynamically from registerYourBrand? May 5 '20 at 13:45
  • because in the next line after require(success) i have stored the output of getOwner() in address ` brandOwner` and I have checked this address , This is the same adddress on which I have delployed my AirToken contract if I have passed 'contract_address` of AirToken as parameter in registerYourBrand May 5 '20 at 13:50
1

Off-chain - yes, for example, using web3.js:

async function isContract(address) {
    const bytecode = await web3.eth.getCode(address);
    return bytecode != "0x";
}

As to your question:

How getOwner() function is found if contract_address is not any contract address?

It is not found - call fails, and the value of the first output (bool success) is false.

7
  • can't i check in solidity because the lines of code I have mentioned here are from my contract ? May 5 '20 at 12:59
  • @PardeepThakur: See updated answer. May 5 '20 at 13:01
  • i have added the full function, if success is false then lines below these should not get executed and transaction should revert but that is not happening. With Any address, function is executed fully and I am getting true May 5 '20 at 13:07
  • @PardeepThakur: Please share in your question how exactly you are testing this function from the off-chain, what parameters you're passing, and how exactly you were able to determine your conclusion (that the getOwner function is called on any address). May 5 '20 at 13:13
  • I am testing it in remix. I have one deployed contract named 'AirToken' . In that contract getOwner() is one function. When I am calling this function from other contract using its contact_address, this is working fine and I am getting the AirToken owner's address successfully. But when i pass some other address that is not Contract Address, this line is executed succesfully but the returned value is some dummy value like 0x0000000000000000000000000000000000000001 like this. May 5 '20 at 13:20
1
  • It is very likely that making a call to a random contract will not fail.

    If a contract doesn't implement a function the fallback function will be invoked. Most fallback functions do nothing. So the call will succeed and the result will be an array on length 0. Some might return true/false that is encoded as a bytes32.

  • If you call an EOA the call will succeed and return an array of length 0.

To make sure a contract implements an interface you have to force them to use something like ERC-165 Standard Interface Detection .

2
  • Can I do interface detection with my own interface,,, Like suppose, i have implemented some interface say loyalty interface in my one contract and I have deployed that contract ,, can i check in my another contract using the previous contract's contract address whether that has implemented loyalty interface interface or not May 6 '20 at 5:48
  • @PardeepThakur If you implement something similar to EIP 165 you should be fine.
    – Ismael
    May 6 '20 at 15:29
1

As a general design heuristic, you should not be interacting with addresses that might be suitable contracts. You should be working with addresses you know are compatible contracts. You will avoid all sorts of issues.

The original post did not say why there should be any doubt. General question, so here's a general answer.

  1. There is no reliable on-chain way to determine if an address is a contract. Some answers say this can be done. No, not reliably. And, reliability is top priority.
  2. You can whitelist contract addresses in at least two general ways:
    • Whitelist contract addresses as your factory creates them, so your contract only interacts with known, trustworthy contracts.
    • Whitelist contract addresses as an admin function, e.g., adding a (supposed) token to a multitoken system that "expects" ERC20 is properly implemented.

You can, of course, get unexpected results during development if there are bugs in your system, and there are possibly unexpected results calling addresses that are not the expected contract. The suggestion is avoidance rather than detection and exception handling unless there is a very good reason to accept the complications.

Hope it helps.

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.