Last active
March 31, 2016 04:47
-
-
Save androlo/7307e4393ffe8227df1d3f4f65da48f1 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| contract AddressSet { | |
| // uint constant SIZE_ADDRESS = 0x10; | |
| // uint constant STORAGE_OFFSET = 0x11; | |
| function add(address addr) returns (bool added) { | |
| assembly { // [garbage, addr, added] | |
| swap1 | |
| dup1 | |
| sload // Load current index. | |
| not // Will be 1 if storage[addr] == 0, which means 'addr' should be added. | |
| dup1 | |
| tag_write | |
| jumpi | |
| tag_end: // [addr, added] | |
| 0x0 | |
| mstore | |
| 0x20 | |
| 0x0 | |
| return | |
| tag_write: // [addr, added] | |
| swap1 // put 'addr' on top. | |
| 0x10 // Load current set size | |
| sload | |
| dup1 // Add 1 to set size and store it | |
| 1 | |
| add | |
| 0x10 | |
| sstore | |
| 0x11 // Calculate new storageAddress (index + offset) | |
| add | |
| dup1 // storage[addr] = storageAddress | |
| dup3 | |
| sstore | |
| sstore // storage[storageAddress] = addr | |
| tag_end // done | |
| jump | |
| } | |
| } | |
| function remove(address addr) returns (bool removed) { | |
| assembly { // [garbage, addr, added] | |
| swap1 | |
| dup1 | |
| sload // [addr, offsetIndex] | |
| 0 | |
| dup2 | |
| gt // Will be 1 if offsetIndex > 0, which means 'addr' will be removed. | |
| dup1 | |
| tag_write | |
| jumpi | |
| tag_end: // 'removed' on the top | |
| 0x0 | |
| mstore | |
| 0x20 | |
| 0x0 | |
| return | |
| tag_write: // [addr, offsetIndex, removed] | |
| swap2 | |
| 0 // Clear storage[addr] | |
| swap1 | |
| sstore // Next [removed, offsetIndex] | |
| 0x10 // check if lastOffsetIndex == offsetIndex | |
| sload // current size | |
| dup1 // store for later | |
| 0x11 // address offset for the set | |
| add | |
| 1 | |
| swap1 | |
| sub // [removed, offsetIndex, size, lastOffsetIndex] | |
| dup3 | |
| dup2 | |
| eq // lastOffsetIndex == offsetIndex | |
| tag_clear | |
| jumpi | |
| tag_swap_addresses: // [removed, offsetIndex, size, lastOffsetIndex] | |
| dup1 | |
| sload // Next [removed, offsetIndex, size, lastOffsetIndex, addressAtLastOffsetIndex] | |
| dup1 // storage[offsetIndex] = addressAtLastOffsetIndex | |
| dup5 | |
| sstore | |
| dup4 // storage[addressAtLastOffsetIndex] = offsetIndex | |
| swap1 | |
| sstore // [removed, offsetIndex, size, lastOffsetIndex] | |
| 0 // storage[lastOffsetIndex] == 0 | |
| swap1 | |
| sstore | |
| pop | |
| tag_finalize | |
| jump | |
| tag_clear: // [removed, offsetIndex, size, lastOffsetIndex] | |
| pop | |
| swap1 | |
| 0 // storage[offsetIndex] = 0 | |
| swap1 // swap with 'offsetIndex' | |
| sstore // Next [removed] | |
| tag_finalize: // [removed, size] | |
| 1 // Sub 1 from current size and overwrite | |
| swap1 | |
| sub | |
| 0x10 | |
| sstore | |
| tag_end // done | |
| jump | |
| } | |
| } | |
| function has(address addr) constant returns (bool has) { | |
| assembly { // [garbage, addr, has] | |
| swap1 | |
| dup1 | |
| sload // Load the index at 'addr' | |
| not // turn it to 0 or 1 | |
| not | |
| 0x0 | |
| mstore | |
| 0x20 | |
| 0x0 | |
| return | |
| } | |
| } | |
| function size() constant returns (uint size) { | |
| assembly { | |
| 0x10 | |
| sload | |
| 0x0 | |
| mstore | |
| 0x20 | |
| 0x0 | |
| return | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment