Created
February 5, 2019 08:52
-
-
Save chebykin/90beb47925053b3c167e5334a7782406 to your computer and use it in GitHub Desktop.
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.22 <0.6.0; | |
// Reference implementation at | |
// https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/ERC20.sol | |
contract ERC20HighAssembly { | |
// uint256 private _totalSupply; | |
// mapping(address => uint256) private _balances; | |
constructor() public { | |
assembly { | |
// _totalSupply = 42; | |
sstore(0x0, 42) | |
// _balances[msg.sender] = 42; | |
let x := mload(0x40) | |
mstore(0x40, add(x, 0x40)) | |
mstore(x, caller) | |
mstore(add(x, 0x20), 1) | |
let k := keccak256(x, 0x40) | |
sstore(k, 42) | |
} | |
} | |
function mint(address account, uint256 value) public { | |
assembly { | |
let x := mload(0x40) | |
mstore(0x40, add(x, 0x40)) | |
mstore(x, account) | |
mstore(add(x, 0x20), 1) | |
let k := keccak256(x, 0x40) | |
sstore(k, value) | |
} | |
} | |
function transfer(address to, uint256 value) public returns (bool) { | |
_transfer(msg.sender, to, value); | |
assembly { | |
mstore(0x0, 1) | |
return(0x0, 0x20) | |
} | |
} | |
function _transfer(address from, address to, uint256 value) internal { | |
// doesn't support 0 for value | |
assembly { | |
// require(to != address(0)); | |
if eq(to, 0) { revert(0, 0) } | |
// _balances[from] = _balances[from].sub(value); | |
let x := mload(0x40) | |
mstore(0x40, add(x, 0x40)) | |
mstore(x, from) | |
mstore(add(x, 0x20), 1) | |
let key := keccak256(x, 0x40) | |
let c := sload(key) | |
let r := sub(c, value) | |
if gt(r, c) { invalid() } | |
sstore(key, r) | |
// _balances[to] = _balances[to].add(value); | |
mstore(x, to) | |
mstore(add(x, 0x20), 1) | |
key := keccak256(x, 0x40) | |
c := sload(key) | |
r := add(c, value) | |
if lt(r, c) { invalid() } | |
sstore(key, r) | |
} | |
} | |
function balanceOf(address account) external view returns (uint256) { | |
assembly { | |
let x := mload(0x40) | |
mstore(0x40, add(x, 0x40)) | |
mstore(x, account) | |
mstore(add(x, 0x20), 1) | |
let k := keccak256(x, 0x40) | |
mstore(0x0, sload(k)) | |
return(0x0, 0x20) | |
} | |
} | |
function totalSupply() external view returns (uint256) { | |
assembly { | |
mstore(0x0, sload(0x0)) | |
return(0x0, 0x20) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment