Search code examples
ethereumblockchainsolid-principles

Use of address function inside a contract constructor?


Wondering if anyone can explain this. I am following along in the "Solidity, Blockchain, and Smart Contract Course - Beginner to Expert Python Tutorial" by freeCodeCamp.org.

In lesson two we create a contract factory in which we store an array of contracts and then create a function to retrieve the contract by index and call a function on it.

Here is how he did it: SimpleStorage(address(simpleStorages[_simpleStorageIndex])).store(_simpleStorageNumber)

I do not understand the SimpleStorage(address(...)) part. I understand indexing into the array and getting the storage, but I tested it and this works the same: simpleStorages[_simpleStorageIndex].store(_simpleStorageNumber)

What is this address function? I assume it gets the address of the contract instance. Then why do we pass it to a constructor(?) of SimpleStorage? Why do all this when calling store on the instance itself without going through addresses works.

Thanks!!

EDIT: Entire contract:

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "./SimpleStorage.sol";

contract StorageFactory is SimpleStorage { // is SimpleStorgae = inheritance 

    SimpleStorage[] public simpleStorages;

    function createSimpleStorageContract() public {
        SimpleStorage simpleStorage = new SimpleStorage();
        simpleStorages.push(simpleStorage);
    }

    function sfStore(uint256 _simpleStorageIndex, uint256 _simpleStorageNumber) public {
        // Anytime you interact with a contract you need two things:
        // Address
        // ABI - Application Binary Interface
        return simpleStorages[_simpleStorageIndex].store(_simpleStorageNumber);
        //return SimpleStorage(address(simpleStorages[_simpleStorageIndex])).store(_simpleStorageNumber);
    }

    function sfGet(uint256 _simpleStorageIndex) public view returns(uint256) {
        return SimpleStorage(address(simpleStorages[_simpleStorageIndex])).retrieve();
    }
}

Solution

  • Your approach, calling the store() function right on the item, is in fact a more straightforward way to achieve the same result as the lecturer's code.

    So to answer your questions:

    What is this address function? I assume it gets the address of the contract instance.

    Correct. Even though the simpleStorages[_simpleStorageIndex] doesn't store the actual SimpleStorage instance. Within your contract, it only stores a helper object that contains a pointer to the external contract address, as well as interface definition of the SimpleStorage (but not the actual instance of the external contract).

    Typecasting the helper object to an address returns the address of the external contract.

    Then why do we pass it to a constructor(?) of SimpleStorage

    You're not passing it to the SimpleStorage constructor - that would be new SimpleStorage(<constructor_params>) with the new keyword (effectively deploying the SimpleStorage contract to a new address). You're instantiating the helper object described above, passing it the external contract address.

    Why do all this when calling store on the instance itself without going through addresses works.

    I don't know the lecturer's intentions behind this code. Maybe they use it later in the course to describe some optimization or as a bridge to show some other topic. But both ways work.