Created
November 30, 2020 22:23
-
-
Save skozin/b3e1f38bb31387ce3b8d023ddb9f7e33 to your computer and use it in GitHub Desktop.
Unstructured storage demo (array of value types)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity 0.4.24; | |
contract ValueTypeArrayDemo { | |
bytes32 internal constant MEMBERS_ARRAY_POSITION = keccak256("org.test.storagedemo.members"); | |
function getMember(uint256 _index) public view returns (address) { | |
return _getMember(_index, MEMBERS_ARRAY_POSITION); | |
} | |
function setMember(uint256 _index, address _address) public { | |
_setMember(_index, _address, MEMBERS_ARRAY_POSITION); | |
} | |
function pushMember(address _address) public { | |
_pushMember(_address, MEMBERS_ARRAY_POSITION); | |
} | |
function popMember() public returns (address member) { | |
return _popMember(MEMBERS_ARRAY_POSITION); | |
} | |
function getTotalMembers() public view returns (uint256 total) { | |
return _getTotalMembers(MEMBERS_ARRAY_POSITION); | |
} | |
function _getTotalMembers(bytes32 _membersSlot) internal view returns (uint256 total) { | |
assembly { | |
total := sload(_membersSlot) | |
} | |
} | |
function _getMember(uint256 _index, bytes32 _membersSlot) internal view returns (address member) { | |
assembly { | |
let len := sload(_membersSlot) | |
switch lt(_index, len) | |
case 1 { | |
// using scratch space | |
mstore(0, _membersSlot) | |
let position := add(keccak256(0, 32), _index) | |
member := sload(position) | |
} | |
case 0 { | |
member := 0 | |
} | |
} | |
} | |
function _setMember(uint256 _index, address _address, bytes32 _membersSlot) internal { | |
assembly { | |
let len := sload(_membersSlot) | |
switch lt(_index, len) | |
case 1 { | |
// using scratch space | |
mstore(0, _membersSlot) | |
let position := add(keccak256(0, 32), _index) | |
sstore(position, _address) | |
} | |
case 0 { | |
revert(0, 0) | |
} | |
} | |
} | |
function _pushMember(address _address, bytes32 _membersSlot) internal { | |
uint256 newLen; | |
assembly { | |
newLen := add(sload(_membersSlot), 1) | |
sstore(_membersSlot, newLen) | |
} | |
_setMember(newLen - 1, _address, _membersSlot); | |
} | |
function _popMember(bytes32 _membersSlot) internal returns (address member) { | |
assembly { | |
let len := sload(_membersSlot) | |
switch lt(0, len) | |
case 1 { | |
let newLen := sub(len, 1) | |
sstore(_membersSlot, newLen) | |
// using scratch space | |
mstore(0, _membersSlot) | |
let position := add(keccak256(0, 32), newLen) | |
member := sload(position) | |
sstore(position, 0) | |
} | |
case 0 { | |
revert(0, 0) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment