Removes the source of the Vyper contract from the spec.

This change allows for easier maintenance of the code and the spec by
uncoupling them. Before any edit to either document resulted in having to
synchronize the other. By adding a reference to the canonical repo for the code
we avoid having to maintain a duplicate copy here.
This commit is contained in:
Alex Stokes 2019-02-01 17:06:04 -08:00
parent 6a9c756191
commit 7e7e5e2795
No known key found for this signature in database
GPG Key ID: 51CE1721B245C086
1 changed files with 7 additions and 78 deletions

View File

@ -1378,87 +1378,16 @@ When sufficiently many full deposits have been made the deposit contract emits t
### Vyper code
```python
## compiled with v0.1.0-beta.6 ##
MIN_DEPOSIT_AMOUNT: constant(uint256) = 1000000000 # Gwei
MAX_DEPOSIT_AMOUNT: constant(uint256) = 32000000000 # Gwei
GWEI_PER_ETH: constant(uint256) = 1000000000 # 10**9
CHAIN_START_FULL_DEPOSIT_THRESHOLD: constant(uint256) = 16384 # 2**14
DEPOSIT_CONTRACT_TREE_DEPTH: constant(uint256) = 32
TWO_TO_POWER_OF_TREE_DEPTH: constant(uint256) = 4294967296 # 2**32
SECONDS_PER_DAY: constant(uint256) = 86400
Deposit: event({deposit_root: bytes32, data: bytes[528], merkle_tree_index: bytes[8], branch: bytes32[32]})
ChainStart: event({deposit_root: bytes32, time: bytes[8]})
zerohashes: bytes32[32]
branch: bytes32[32]
deposit_count: uint256
full_deposit_count: uint256
chainStarted: public(bool)
@public
def __init__():
for i in range(31):
self.zerohashes[i+1] = sha3(concat(self.zerohashes[i], self.zerohashes[i]))
self.branch[i+1] = self.zerohashes[i+1]
@public
@constant
def get_deposit_root() -> bytes32:
root:bytes32 = 0x0000000000000000000000000000000000000000000000000000000000000000
size:uint256 = self.deposit_count
for h in range(32):
if size % 2 == 1:
root = sha3(concat(self.branch[h], root))
else:
root = sha3(concat(root, self.zerohashes[h]))
size /= 2
return root
@payable
@public
def deposit(deposit_input: bytes[512]):
assert msg.value >= as_wei_value(MIN_DEPOSIT_AMOUNT, "gwei")
assert msg.value <= as_wei_value(MAX_DEPOSIT_AMOUNT, "gwei")
index: uint256 = self.deposit_count
deposit_amount: bytes[8] = slice(concat("", convert(msg.value / GWEI_PER_ETH, bytes32)), start=24, len=8)
deposit_timestamp: bytes[8] = slice(concat("", convert(block.timestamp, bytes32)), start=24, len=8)
deposit_data: bytes[528] = concat(deposit_amount, deposit_timestamp, deposit_input)
merkle_tree_index: bytes[8] = slice(concat("", convert(index, bytes32)), start=24, len=8)
# add deposit to merkle tree
i: int128 = 0
power_of_two: uint256 = 2
for _ in range(32):
if (index+1) % power_of_two != 0:
break
i += 1
power_of_two *= 2
value:bytes32 = sha3(deposit_data)
for j in range(32):
if j < i:
value = sha3(concat(self.branch[j], value))
self.branch[i] = value
self.deposit_count += 1
new_deposit_root:bytes32 = self.get_deposit_root()
log.Deposit(new_deposit_root, deposit_data, merkle_tree_index, self.branch)
if msg.value == as_wei_value(MAX_DEPOSIT_AMOUNT, "gwei"):
self.full_deposit_count += 1
if self.full_deposit_count == CHAIN_START_FULL_DEPOSIT_THRESHOLD:
timestamp_day_boundary: uint256 = as_unitless_number(block.timestamp) - as_unitless_number(block.timestamp) % SECONDS_PER_DAY + SECONDS_PER_DAY
chainstart_time: bytes[8] = slice(concat("", convert(timestamp_day_boundary, bytes32)), start=24, len=8)
log.ChainStart(new_deposit_root, chainstart_time)
self.chainStarted = True
```
The source for the Vyper contract lives in a separate repository at [https://github.com/ethereum/deposit_contract](https://github.com/ethereum/deposit_contract).
Note: to save ~10x on gas this contract uses a somewhat unintuitive progressive Merkle root calculation algo that requires only O(log(n)) storage. See https://github.com/ethereum/research/blob/master/beacon_chain_impl/progressive_merkle_tree.py for an implementation of the same algo in python tested for correctness.
For convenience, we provide the interface to the contract here:
* `__init__()`: initializes the contract
* `get_deposit_root() -> bytes32`: returns the current root of the deposit tree
* `deposit(bytes[512])`: adds a deposit instance to the deposit tree, incorporating the input argument and the value transferred in the given call.
## On startup
A valid block with slot `GENESIS_SLOT` (a "genesis block") has the following values. Other validity rules (e.g. requiring a signature) do not apply.