15

This code works:

contract C {
  function Get() constant returns(bytes8[]) {
    bytes8[] stuff;
    return stuff;
  }
  function Copy() {
    bytes8[] memory stuff = Get();
  }
}

But when I try to call Get() in another way...

contract A {
  A other;
  function Get() constant returns(bytes8[]) {
    bytes8[] stuff;
    return stuff;
  }
  function Copy() {
    bytes8[] stuff = other.Get();
  }
}

I get this error:

DynamicType.sol:8:5: Error: Type inaccessible dynamic type is not implicitly convertible to expected type bytes8[] memory.
    bytes8[] memory stuff = other.Get();
    ^---------------------------------^

I come from the Javascript world where we don't have to worry about storage vs memory types. I have read the section in the Solidity docs on Data Location but it would be helpful to get an explanation particular to this example so that I can better connect the concepts.

1
  • I don't think that you need to create "A other;". Use this or call the function normally.
    – Aniket
    Jul 27, 2016 at 13:27

1 Answer 1

7

To answer the main question that the OP is asking: the problem is that the EVM is unable to read variably-sized data from external function calls.

If you replace, in Get(), bytes8[] with uint you will see the error disappear.

Here (https://gist.github.com/raineorshine/ab40fa8c967e96dc94a1d34e2a79179b) is an example which shows, if you copy paste it in the solidity browser, that the error is not related to storage or memory issues.

9
  • Hi! Thank you for your explanation. The main message I'm getting is that you cannot dynamically allocate variables in storage. It does not answer my question specifically, but it is useful information nonetheless. (The error I get occurs when there is a reference to another instance, not the current instance. Naturally, removing the other instance as you did changes the problem. "The error you receive is because you don't initialize other" -> this is simply not true; the error occurs at compile-time, and occurs whether it is initialized or not.) Jul 30, 2016 at 19:20
  • how do you initialize it ? because if you try A other = new A() you get an error because you cannot create a contract of the same type inside a contract.
    – dragosb
    Jul 30, 2016 at 19:26
  • You can pass in the address from the outside before calling Copy(): gist.github.com/raineorshine/35305e0a35e7e1184a6d4d54cbc853d4 Jul 30, 2016 at 19:28
  • The question is more about what specifically is causing the error rather than whether the pattern makes sense architecturally for a specific problem. Jul 30, 2016 at 19:29
  • I did some tests and I think the problem is that the EVM is unable to read variably-sized data from external function calls. If you replace, in Get(), bytes8[] with uint you will see the error disappear.
    – dragosb
    Jul 30, 2016 at 19:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.