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 ...)

  • is foo defined as public? If is external it may not work – mirg Apr 12 '18 at 16:01
  • @mirg Yes, I simplified it for the example but all the functions I call externally are public. – Teleporting Goat Apr 12 '18 at 17:42
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();
  • 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: 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 8:32

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.