0

I have two contracts, TokenContract and DynamicContract. The latter is created dynamically.

I want to call a function of DynamicContract from TokenContract (receiveApproval). According to this question, what I need to do is this:

function ApproveAndCall(address dynContAddress, uint value){
  DynamicContract dynamicContractInstance = DynamicContract(dynContAddress);
  dynamicContractInstance.foo();

  return true;
}

I have import "./DynamicContract.sol"; at the beginning of my TokenContract.

The thing is, I already have a constructor for DynamicContract and it takes a bunch of parameters. So I get a compilation error stating I don't have the right parameters.

I also tried using simply DynamicContract(dynContAddress).foo() but I get Member "foo" not found or not visible after argument-dependent lookup in address

EDIT: Maybe I should use function ApproveAndCall(DynamicContract dynContAddress, ...){} instead of function ApproveAndCall(address dynContAddress, ...) if I want to use dynContAddress.foo(){}? What's the difference?


I think the problem might come from the fact that both contract call functions of the other, so both have import "./OtherContract.sol". Since one has to compile before the other there might be a problem (Solidity isn't as flexible as some other languages).

Could it be the problem? Then how could I solve it? (I don't think the contract is over complicated, I just want to pay for functions in token and transfer them to the address they belong to).

EDIT 2: Actually I don't think that's the problem because when running truffle compile, I get Compiling .\contracts\DynamicContract.sol...and Compiling .\contracts\Factory.sol... before Compiling .\contracts\Token.sol... that gives the error. (member not found or not visible ...)

Teleporting Goat
  • 1,516
  • 1
  • 13
  • 33

1 Answers1

2

To create a new contract from within another contract:

a. If ether needs to be supplied upon construction:

DynamicContract dynamicContractInstance = 
     (new DynamicContract).value(<ether to send>)(<param1>, <param2>, ...);

b. If ether does not need to be supplied upon construction:

DynamicContract dynamicContractInstance = 
     new DynamicContract(<param1>, <param2>, ...);

Then, the function can be called:

dynamicContractInstance.foo();

If the address of the "dynamic" contract has already been obtained:

the function can be called:

dynContAddress.foo();
Drew
  • 218
  • 1
  • 3
  • I don't know if it's clear but the contract is already created, I only want to make an instance by using the address (that I already have) – Teleporting Goat Apr 12 '18 at 17:44
  • Is "the address (that I already have)" = dynContAddress? If so, there is no need to recreate or cast the contract, it's possible to use
    dynContAddress.foo(); 
    
    

    to call the function.

    – Drew Apr 12 '18 at 17:59
  • Yes it is, but as I said in the last part of my question, addressThatIAlreadyHave.foo() doesn't work, I get "member not found or not accessible" (even though it's public), I don't know why I, have I missed something? – Teleporting Goat Apr 12 '18 at 20:25
  • This gist contains the code that I used to validate the answer: https://gist.github.com/fidsteve/87fdd61996dfa04085161aecbc363690 – Drew Apr 12 '18 at 22:18
  • I think I know the problem. In my foo() function, there is tokenContract.transferFrom so dynContract has to import "./TokenContract.sol". But TokenContract also needs to import "./DynamicContract"to call dynContAddress.foo(). So maybe one has to compile first and it doesn't have the other one compiled already. Could that be it? How do I solve this? – Teleporting Goat Apr 13 '18 at 08:32
  • Maybe it's the token function definition? I used to have something like function approveAndCall (address dynContAddr, uint arg1){...}, I switched to function approveAndCall ( DynContract dynContAddr, uint arg1){...}. Is it better? Can I call that with an address? – Teleporting Goat Apr 13 '18 at 08:56