14

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.

  • I don't think that you need to create "A other;". Use this or call the function normally. – Aniket Jul 27 '16 at 13:27
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.

  • 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.) – Raine Revere Jul 30 '16 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 '16 at 19:26
  • You can pass in the address from the outside before calling Copy(): gist.github.com/raineorshine/35305e0a35e7e1184a6d4d54cbc853d4 – Raine Revere Jul 30 '16 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. – Raine Revere Jul 30 '16 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 '16 at 19:41

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.