2

My question means for example that the primary contract stores names of secondary contracts, for example like this:

mapping (address => string) secondaryContractNames;

I know we can in the primary contract define the essence of secondary contract like this: secondaryContract contract = secondaryContract(_address); Is it possible to code something like this:

secondaryContractNames[_address] contract = secondaryContractNames[_address](_address); or:

contract(secondaryContractNames[_address]) contract = contract(secondaryContractNames[_address])(_address);

So if we store secondaryContractNames[_address] as for example secondaryContract the previous code will be transformed as secondaryContract contract = secondaryContract(_address);

I know that the code below doesn't work. It's just to explain my logic. And the question is it possible in solidity or not?

  • sounds like you are asking about abstract and interface smart contracts? That would allow you to implement a contract inside another, without deploying it first. Then deploying said contract later followed by linking it up via its address. – MSwezey Mar 15 at 19:51
  • The answer is almost certainly yes but I hesitate to scribble out a solution without understanding the question. Can you explain the end goal? Are you trying to create contracts with two participants? Are the contracts always the same, or different? What is the rationale for many small contracts? It sort of resembles a proxy pattern for upgradeable contracts. It sort of resembles an escrow arrangement. Maybe something else. – Rob Hitchens - B9lab Mar 16 at 17:34
  • @MSwezey how to implement contract(secondary) inside another contract(primary) before deploying I've already known. But you have to know the name of secondary contract so you have to create (I mean wrire the source code) of secondary contract. The question is about situation when you don't have the source code of secondary contract yet but you need to deploy the primary one. – Aleksandr Mar 18 at 6:42
  • @RobHitchens the end goal is to create an erc20 token, deploy it (this is important remark) and then create other contracts with own logic but that will use this erc20 token that has been already deployed. So when I'm deploying it, I don't know yet the number of secondary contracts, its' names and I don't have its' source codes yet. Hope I explained more clearly :) – Aleksandr Mar 18 at 6:47
2

From your previous comment:

how to implement contract(secondary) inside another contract(primary) before deploying I've already known. But you have to know the name of secondary contract so you have to create (I mean wrire the source code) of secondary contract. The question is about situation when you don't have the source code of secondary contract yet but you need to deploy the primary one.

You do not need to know the name of the contract. As long as the ABIs match up. The only thing you need is the deployed address. Then update the 1st contract deployed with said address. I can deploy these contracts below in any order, then call setContractInstance() passing in the address of the contract I want to take action on.

Knowing which methods beforehand helps one to create the proper interface/abstract contract(s) needed. But you do not care about the contract name, as it doesn't matter.

See the example I've created here: https://gist.github.com/mswezey23/b15085cc7339bf6d06f88b056a631326

pragma solidity 0.5.6;

interface DeployInterface {
    function foo() external returns (uint256);
}

contract DeploySecond is DeployInterface {
    function foo() external returns (uint256) {
        return 2;
    }
}

contract DeployThird is DeployInterface {
    function foo() external returns (uint256) {
        return 3;
    }
}


contract deployFirst {
    DeployInterface contractInstance;

    function setContractInstance(address _contractInstance) public {
        contractInstance = DeployInterface(_contractInstance);
    }

    function execDoThing() public returns (uint256) {
        return contractInstance.foo();
    }
}

Instructions:

  • Deploy in any order.
  • Pass either DeployThird or DeploySecond contract address to setContractInstance
  • call execDoThing
  • check result
  • Pass in the other contract address via setContractInstance
  • call execDoThing
  • check result

Example to call another contract function when not knowing the function name or parameters during compile time:

contract_address.call(bytes4(sha3("function_name(types)")),parameters_values)

This goes to show that the contract name does not matter.

Source

1

It is hard to understand the task, but here are some assumptions about it and posdible approaches:

  1. if you want to deploy token contract first, and then other contracts that will use this token contract, just pass address of the token contract to the constructors of other contracts, save it in storage and use;
  2. if you want your token contract to use other contracts deployed later, and you know signatures of methods token contract needs to call on other contracts (but not the implementations of these methods, that could be different in different contracts), than you need to define interface with these signatures, use it in token contract and implement it in other contracts, you will also need to implement special method(s) in token contract that you will use to tell token contract addresses of other contracts;
  3. if you need you token contract to actually deploy other contracts whose bytecode is not known at the time token contract is being deployed,but becomes known later, than this is also possible via assembly language.

Let me know what case better describes your task, and i will add more details to it.

  • Thanks for your answer. I think approach №2 is enough for this project and I've already understood how to do it, thanks to @MSwezey. But your assumptions are very useful, I think approach №3 will come useful in the future for me :) – Aleksandr Mar 19 at 7:37

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.