17

I have a struct Purchase in which I'm putting an array of payments. However, when I try to add the new payments array in my makePayment method I get an error back from the solidity compiler: "Internal compiler error: Copying of type struct Payment memory[] memory to storage not yet supported." When I change the mayment array to be storage or memory, I get the same error. I've added the relevant code below.

Is it possible to do what I'm trying to do in solidity? I don't see anything explicitly saying it's not possible in the documentation but I also don't see any examples doing what I'm trying to do. :|

  struct Payment {
    address maker;
    uint amount;
  }

  struct Purchase {
    uint product_id;
    bool complete;
    Payment[] payments;
  }
  Purchase[] purchases;

  function makePayment(uint product_id, uint amt, uint purchase_id) returns (bool) {

      Payment[] payments;
      payments[0] = Payment(address, amt);
      purchases[purchase_id] = Purchase(product_id, false, payments);
  }
2
  • It's possible that this was happening because I wasn't using enough gas for the transaction. Commented Mar 2, 2016 at 12:58
  • Did you see there is an Ethereum SE beta? Commented Mar 3, 2016 at 21:04

2 Answers 2

12

You need to manually change the length of the payments array when setting it.

Either use:

  Payment[] payments;
  payments[payments.length++] = Payment(address, amt);

Or:

Payment[] payments;
payments.push(Payment(address, amt));

For setting the payments array in Purchase, instead of creating an array and trying to set it to the Purchase.payments you can do the following:

uint purchase_id = purchases.length++;
purchases[purchase_id].product_id = product_id;
purchases[purchase_id].complete   = false;
purchases[purchase_id].payments.push(Payment(msg.sender, amt));

Extending the purchases length will automatically create the new attributes. Then you can set them manually.

Sign up to request clarification or add additional context in comments.

2 Comments

Does payments need the memory keyword in this case?
In solidity 8 this solution won't work as length is read-only, but you can simply do Purchase p = purchases.push() instead, and instead of having index, you can do p.product_id = product_id and so on
0

I found this as best solution.

  event OnCreateRoom(address indexed _from, uint256 _value);

   struct Room {
      address[] players;       
      uint256 whosTurnId;
      uint256 roomState;
   }  

   Room[] rooms;

   function createRoom() public{
       address[] adr;
       adr.push(msg.sender);
       Room memory room = Room(adr, 0, 0);   
       rooms.push(room);
       OnCreateRoom(msg.sender, 0);
   }

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.