pragma solidity ^0.4.24; /* The Ethereum Virtual Machine has 3 separate places to "store" data: 1. Stack: A last-in-first-out container to which values can be pushed and popped, resetting per computation 2. Memory: An infinitely expandable byte array, resetting per computation 3. Storage: The contract's long-term state, a key/value store, written onto the blockchain. In this level, we learn how the EVM stores primitive vs complex datatypes. We'll use some assembly opcodes to directly read from stack, memory or storage. But dont worry - you don't have to learn assembly programming just yet. Opcode definitions are provided for you inline and here: https://solidity.readthedocs.io/en/v0.4.24/assembly.html */ contract Test_Storage_7 is Koans { /* ----------------------Stack----------------------------- 1. Local, primitive variables are pushed and popped via the Stack, in LIFO order. 2. Remember: arrays, structs, mappings, are NOT saved to the Stack. Complex datatypes must be saved to Memory or Storage. */ function test_local_primitives_default_to_the_stack() public { uint actual; uint a = 1; uint b = 2; // Hint: swap1 is a stack-level command that swaps the most recent and second most recent datapoints on the stack assembly { swap1 } actual = a ** b; Assert.equal(actual, __, "should return the correct exponent, given stack ordering"); } /* ----------------------Memory----------------------------- 1. The EVM allocates infinite memory per computation. 2. Memory usage consumes more gas than stack usage. 3. Memory is a single byte array, where new data is appended at the end 4. As such, you cannot create mappings in memory. This is because mappings have a key, value data structure that only works in Storage */ function test_you_can_create_arrays_in_memory() public { uint256[2] memory array = [uint256(16), uint256(32)]; uint memory_at_c0; uint memory_at_e0; // Hint: mload(n) reads the data in Memory, at location n (in our case, this starts at 0xc0) assembly { memory_at_c0 := mload(0xc0) memory_at_e0 := mload(0xe0) } Assert.equal(memory_at_c0, array[uint(__)], "should be the correct value in memory slot 0xc0"); Assert.equal(memory_at_e0, array[uint(__)], "should be the correct value in memory slot 0xe0"); }
0.4.18