Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removes the source of the Vyper contract from the spec. #562

Merged
merged 3 commits into from
Feb 3, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 6 additions & 77 deletions specs/core/0_beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -1378,86 +1378,15 @@ 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
The source for the Vyper contract lives in a separate repository at [https://github.com/ethereum/deposit_contract](https://github.com/ethereum/deposit_contract).
ralexstokes marked this conversation as resolved.
Show resolved Hide resolved

new_deposit_root:bytes32 = self.get_deposit_root()
log.Deposit(new_deposit_root, deposit_data, merkle_tree_index, self.branch)
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.

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
```
For convenience, we provide the interface to the contract here:

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.
* `__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.
ralexstokes marked this conversation as resolved.
Show resolved Hide resolved

## On startup

Expand Down