Aaron Bloomfield (aaron@virginia.edu) @github | ↑ |
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0 <0.9.0; contract C { // The data location of x is storage; this is the // only place where the data location can be omitted uint[] x; // The data location of memoryArray is memory. function f(uint[] memory memoryArray) public { x = memoryArray; // works, copies the whole array to storage uint[] storage y = x; // works, assigns a pointer, y's location is storage y[7]; // fine, returns the 8th element y.pop(); // fine, modifies x through y delete x; // fine, clears the array, also modifies y // The following doesn't work; it would need to create a new temporary / // unnamed array in storage, but storage is "statically" allocated: // y = memoryArray; // This does not work either, since it would "reset" the pointer, // but there is no sensible location it could point to. // delete y; g(x); // calls g, handing over a reference to x h(x); // calls h and creates an independent, temporary copy in memory } function g(uint[] storage) internal pure {} function h(uint[] memory) public pure {} }
contract Modifiers { address public owner; constructor() { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; } modifier validAddress(address _addr) { require(_addr != address(0), "Not valid address"); _; } function changeOwner(address _newOwner) public onlyOwner validAddress(_newOwner) { owner = _newOwner; } }
.code PUSH 80 contract MyContract {\n uin... PUSH 40 contract MyContract {\n uin... MSTORE contract MyContract {\n uin... PUSH 3 1 + 2 * 3 - 4 PUSH 0 uint public i = 1 + 2 * 3 - 4 SSTORE uint public i = 1 + 2 * 3 - 4 CALLVALUE contract MyContract {\n uin... DUP1 contract MyContract {\n uin... ISZERO contract MyContract {\n uin... PUSH [tag] 1 contract MyContract {\n uin... JUMPI contract MyContract {\n uin... PUSH 0 contract MyContract {\n uin... DUP1 contract MyContract {\n uin... REVERT contract MyContract {\n uin... tag 1 contract MyContract {\n uin... JUMPDEST contract MyContract {\n uin... POP contract MyContract {\n uin... PUSH #[$] 0000000000000000000000000000000000000000000000000000000000000000 contract MyContract {\n uin... DUP1 contract MyContract {\n uin... PUSH [$] 0000000000000000000000000000000000000000000000000000000000000000 contract MyContract {\n uin... PUSH 0 contract MyContract {\n uin... CODECOPY contract MyContract {\n uin... PUSH 0 contract MyContract {\n uin... RETURN contract MyContract {\n uin... .data 0: .code PUSH 80 contract MyContract {\n uin... PUSH 40 contract MyContract {\n uin... MSTORE contract MyContract {\n uin... CALLVALUE contract MyContract {\n uin... DUP1 contract MyContract {\n uin... ISZERO contract MyContract {\n uin... PUSH [tag] 1 contract MyContract {\n uin... JUMPI contract MyContract {\n uin... PUSH 0 contract MyContract {\n uin... DUP1 contract MyContract {\n uin... REVERT contract MyContract {\n uin... tag 1 contract MyContract {\n uin... JUMPDEST contract MyContract {\n uin... POP contract MyContract {\n uin... PUSH 4 contract MyContract {\n uin... CALLDATASIZE contract MyContract {\n uin... LT contract MyContract {\n uin... PUSH [tag] 2 contract MyContract {\n uin... JUMPI contract MyContract {\n uin... PUSH 0 contract MyContract {\n uin... CALLDATALOAD contract MyContract {\n uin... PUSH E0 contract MyContract {\n uin... SHR contract MyContract {\n uin... DUP1 contract MyContract {\n uin... PUSH E5AA3D58 contract MyContract {\n uin... EQ contract MyContract {\n uin... PUSH [tag] 3 contract MyContract {\n uin... JUMPI contract MyContract {\n uin... tag 2 contract MyContract {\n uin... JUMPDEST contract MyContract {\n uin... PUSH 0 contract MyContract {\n uin... DUP1 contract MyContract {\n uin... REVERT contract MyContract {\n uin... tag 3 uint public i = 1 + 2 * 3 - 4 JUMPDEST uint public i = 1 + 2 * 3 - 4 PUSH [tag] 4 uint public i = 1 + 2 * 3 - 4 PUSH 0 uint public i = 1 + 2 * 3 - 4 SLOAD uint public i = 1 + 2 * 3 - 4 DUP2 uint public i = 1 + 2 * 3 - 4 JUMP uint public i = 1 + 2 * 3 - 4 tag 4 uint public i = 1 + 2 * 3 - 4 JUMPDEST uint public i = 1 + 2 * 3 - 4 PUSH 40 uint public i = 1 + 2 * 3 - 4 MLOAD uint public i = 1 + 2 * 3 - 4 SWAP1 DUP2 MSTORE PUSH 20 ADD PUSH 40 uint public i = 1 + 2 * 3 - 4 MLOAD uint public i = 1 + 2 * 3 - 4 DUP1 uint public i = 1 + 2 * 3 - 4 SWAP2 uint public i = 1 + 2 * 3 - 4 SUB uint public i = 1 + 2 * 3 - 4 SWAP1 uint public i = 1 + 2 * 3 - 4 RETURN uint public i = 1 + 2 * 3 - 4 .data
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; interface IPoll { struct Choice { uint id; string name; uint votes; } function purpose() external pure returns (string memory); function voted(address a) external view returns (bool); function choices(uint i) external view returns (Choice memory); function num_choices() external view returns (uint); function addChoice (string memory _name) external; function vote (uint _id) external; event votedEvent (uint indexed _id); event choiceAddedEvent (uint indexed _id); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.24; import "./IPoll.sol"; contract Poll is IPoll { mapping (address => bool) public override voted; mapping (uint => Choice) internal _choices; function choices(uint i) public view override returns (Choice memory) { return _choices[i]; } uint public override num_choices; string public override constant purpose = "Vote on your favorite color"; constructor() { addChoice("red"); addChoice("orange"); addChoice("yellow"); addChoice("green"); addChoice("blue"); addChoice("purple"); } function addChoice (string memory _name) public override { _choices[num_choices] = Choice(num_choices, _name, 0); emit choiceAddedEvent(num_choices); num_choices++; } function vote (uint _id) public override { require(!voted[msg.sender], "sender has already voted"); require(_id >= 0 && _id < num_choices, "invalid vote selection"); voted[msg.sender] = true; _choices[_id].votes++; emit votedEvent(_id); } function unnecessaryFunction() public view returns (string memory) { return _choices[0].name; } function supportsInterface(bytes4 interfaceId) external pure returns (bool) { return interfaceId == type(IPoll).interfaceId || interfaceId == 0x01ffc9a7; } }