-
Notifications
You must be signed in to change notification settings - Fork 110
/
Copy pathDataLocationsReferences.sol
75 lines (59 loc) · 2.94 KB
/
DataLocationsReferences.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// SPDX-License-Identifier: Apache-2
pragma solidity ^0.8.0;
contract DataLocationsReferences {
bytes someData;
function storageReferences() public {
bytes storage a = someData;
bytes memory b;
bytes calldata c;
// storage variables can reference storage variables as long as the storage reference they refer to is initialized.
bytes storage d = a;
// if the storage reference it refers to was not initiliazed, it will lead to an error
// "This variable (refering to a) is of storage pointer type and can be accessed without prior assignment,
// which would lead to undefined behaviour."
// basically you cannot create a storage reference that points to another storage reference that points to nothing
// f -> e -> (nothing) ???
/// bytes storage e;
/// bytes storage f = e;
// storage pointers cannot point to memory pointers (whether the memory pointer was initialized or not
/// bytes storage x = b;
/// bytes memory r = new bytes(3);
/// bytes storage s = r;
// storage pointer cannot point to a calldata pointer (whether the calldata pointer was initialized or not).
/// bytes storage y = c;
/// bytes calldata m = msg.data;
/// bytes storage n = m;
}
function memoryReferences() public {
bytes storage a = someData;
bytes memory b;
bytes calldata c;
// this is valid. It will copy from storage to memory
bytes memory d = a;
// this is invalid since the storage pointer x is not initialized and does not point to anywhere.
/// bytes storage x;
/// bytes memory y = x;
// this is valid too. `e` now points to same location in memory than `b`;
// if the variable `b` is edited, so will be `e`, as they point to the same location
// same the other way around. If the variable `e` is edited, so will be `b`
bytes memory e = b;
// this is invalid, as here c is a calldata pointer but is uninitialized, so pointing to nothing.
/// bytes memory f = c;
// a memory reference can point to a calldata reference as long as the calldata reference
// was initialized and is pointing to somewhere in the calldata.
// This simply result in copying the offset in the calldata pointed by the variable reference
// inside the memory
bytes calldata g = msg.data[10:];
bytes memory h = g;
// this is valid. It can copy the whole calldata (or a slice of the calldata) in memory
bytes memory i = msg.data;
bytes memory j = msg.data[4:16];
}
function calldataReferences() public {
bytes storage a = someData;
bytes memory b;
bytes calldata c;
// for calldata, the same rule than for storage applies.
// calldata pointers can only reference to the actual calldata or other calldata pointers.
}
}