Created
December 27, 2017 09:37
-
-
Save jannikluhn/373d5d0eb782feb8b551acf1c165c812 to your computer and use it in GitHub Desktop.
Bitcoin-style UTXO system on top of Ethereum with abstracted accounts
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
MEMORY_COUNTER = 0 | |
MEMORY_N_ITERATIONS = 32 | |
MEMORY_CALLDATA_INDEX = 64 | |
MEMORY_TOTAL_AMOUNT = 96 | |
MEMORY_KEY = 128 | |
MEMORY_SIGNATURE = 160 | |
MEMORY_ADDRESS = 160 | |
# CALLDATA: | |
# n inputs, | |
# [[input key, key signature], ...], | |
# n outputs, | |
# [[output amount, output address], ...] | |
# | |
# STORAGE: | |
# input key -> amount (0 if spent) | |
# input key + 1 -> address | |
# where key == sighash of output tx + index of output in tx | |
[ | |
'seq', | |
# remember number of inputs and assert that there aren't too many | |
['mstore', MEMORY_N_ITERATIONS, ['calldataload', 0]], | |
['assert', ['lt', ['mload', MEMORY_N_ITERATIONS], ['add', 1, MAX_ITERATIONS]]], | |
# initialize calldata pointer to first input | |
['mstore', MEMORY_CALLDATA_INDEX, 32], | |
# for each input key | |
['repeat', MEMORY_COUNTER, 0, MAX_ITERATIONS, [ | |
'seq', | |
['if', [ | |
'gt', | |
['add', 1, ['mload', MEMORY_COUNTER]], | |
['mload', MEMORY_N_ITERATIONS] | |
], 'break'], | |
# copy input key and signature to memory | |
['calldatacopy', MEMORY_KEY, ['mload', MEMORY_CALLDATA_INDEX], 128], | |
['with', 'amount', ['sload', ['mload', MEMORY_KEY]], [ | |
'with', 'total_amount', ['mload', MEMORY_TOTAL_AMOUNT], [ | |
'seq', | |
# assert that unspent | |
['assert', ['gt', 'amount', 0]], | |
# check for overflow | |
['assert', ['gt', ['add', 'amount', 'total_amount'], 'total_amount']], | |
# increase total amount | |
['mstore', MEMORY_TOTAL_AMOUNT, ['add', 'amount', 'total_amount']], | |
# mark as spent | |
['sstore', ['mload', MEMORY_KEY], 0] | |
] | |
]], | |
# verify signature | |
[ | |
'call', | |
3000, | |
1, | |
0, | |
MEMORY_KEY, | |
128, | |
MEMORY_ADDRESS, | |
32 | |
], | |
['assert', [ | |
'eq', | |
['mload', MEMORY_ADDRESS], | |
['sload', ['add', 1, ['mload', MEMORY_KEY]]] | |
]], | |
# point calldata index to next input | |
['mstore', MEMORY_CALLDATA_INDEX, [ | |
'add', 128, ['mload', MEMORY_CALLDATA_INDEX] | |
]] | |
]], | |
# point calldata index to first output | |
['mstore', MEMORY_CALLDATA_INDEX, ['add', 32, ['mload', MEMORY_CALLDATA_INDEX]]], | |
# use sighash as first output key | |
['mstore', MEMORY_KEY, ['sighash']], | |
# remember number of outputs and assert that there aren't too many | |
['mstore', MEMORY_N_ITERATIONS, [ | |
'calldataload', ['sub', ['mload', MEMORY_CALLDATA_INDEX], 32] | |
]], | |
['assert', ['lt', ['mload', MEMORY_N_ITERATIONS], ['add', 1, MAX_ITERATIONS]]], | |
# for each output | |
['repeat', MEMORY_COUNTER, 0, MAX_ITERATIONS, [ | |
'seq', | |
['if', [ | |
'gt', | |
['add', 1, ['mload', MEMORY_COUNTER]], | |
['mload', MEMORY_N_ITERATIONS] | |
], 'break'], | |
['with', 'amount', ['calldataload', ['mload', MEMORY_CALLDATA_INDEX]], [ | |
'seq', | |
# verify that total amount >= amount | |
['assert', ['gt', ['add', 1, ['mload', MEMORY_TOTAL_AMOUNT]], 'amount']], | |
['with', 'key', ['mload', MEMORY_KEY], [ | |
'seq', | |
# set amount | |
['sstore', 'key', 'amount'], | |
# set address (coinbase if 0) | |
['mstore', MEMORY_ADDRESS, [ | |
'calldataload', ['add', 32, ['mload', MEMORY_CALLDATA_INDEX]] | |
]], | |
['if', ['eq', ['mload', MEMORY_ADDRESS], 0], [ | |
'mstore', MEMORY_ADDRESS, ['coinbase'] | |
]], | |
['sstore', ['add', 1, 'key'], ['mload', MEMORY_ADDRESS]], | |
]], | |
# reduce total amount | |
['mstore', MEMORY_TOTAL_AMOUNT, [ | |
'sub', ['mload', MEMORY_TOTAL_AMOUNT], 'amount' | |
]] | |
]], | |
# point calldata index to next output | |
['mstore', MEMORY_CALLDATA_INDEX, ['add', 64, ['mload', MEMORY_CALLDATA_INDEX]]], | |
# increment key | |
['mstore', MEMORY_KEY, ['add', 1, ['mload', MEMORY_KEY]]] | |
]], | |
# assert that everything was spent | |
['assert', ['not', ['mload', MEMORY_TOTAL_AMOUNT]]] | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment