Also is my assumption correct that when a 'memory' array is passed in as a parameter, it has a fixed size?
No. A dynamic array is preceded by a uint that specifies the length, e.g. the following array has 3 elements. The input would come in four chunks, one for the length (3) and three for the elements that follow.
I made this example to show that dynamic memory
work as both function inputs and outputs.
pragma solidity 0.5.2;
contract Memory {
function doSomething(uint[] memory array) public pure returns(uint[] memory y) {
return array;
}
}
What is happening when a parameter is declared as storage. Where is this storage written to?
As a developer, it may be sufficient to know that the values are written to a namespace with a "slot" for each index (as well as the length for a dynamic array).
If you are not familiar with mappings they are a more direct interface to the namespace that uses a hash function to compute the "slot". So ...
mapping(uint => bool) flags;
basically says "for every possible uint, compute a key and store a bool there (if set)." All keys exist but the default is zero/false and the majority of the values will never be set. It doesn't initialize the "empty" slots (that would take an enormous amount of space). If the empty slots are inspected, it returns 0, false, empty, null.
The reason I mention this is deep down, dynamic arrays use the same hash table namespace scheme, where the "rows" are used to generate keys ... there is a key for row 0, a key for row 1, a key for row 2, etc. as well as a length
(uint). Length puts a boundary on the indexes so it can detect "out of bounds" exceptions.
If you want to get into the guts of how storage actually works, have a look at this: ELI5 How does a Merkle-Patricia-trie tree work?
For completeness, I would add that the storage state is a logical construct. Clients are free to implement physical storage by any scheme they wish, so exploration of physical storage details will branch out on a case-by-case basis. In terms of writing contracts (and assembler), you would rummage around in the logical storage, so it's enough to understand the logical structure in most cases.
Hope it helps.