Skip to content

Instantly share code, notes, and snippets.

@a2468834
Last active April 28, 2023 03:19
Show Gist options
  • Save a2468834/96a78ffdff4803e500336f9a78a2108a to your computer and use it in GitHub Desktop.
Save a2468834/96a78ffdff4803e500336f9a78a2108a to your computer and use it in GitHub Desktop.
Calculate next slot prev_randao
import hashlib
import string
##### Helper function #####
ssz_byteorder = "little" # https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md
# https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#aliases
def isBytesN(input_):
# BytesN := Vector[uint8, N]
assert isinstance(input_, list)
assert all(isinstance(h, bytes) for h in input_)
assert all((int(h.hex(), 16) < 2**8) for h in input_)
return True
# https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#basic-types
def isUintNString(input_, N):
assert isinstance(input_, str)
assert all(c in string.hexdigits for c in input_)
assert len(input_) % (N // 4) == 0
return True
def hexToBytesN(input_):
assert isUintNString(input_, 8)
return [int(f"{a}{b}", 16).to_bytes(8 // 8, ssz_byteorder) for a, b in zip(input_[0::2], input_[1::2])]
def bytesNToHex(input_):
assert isBytesN(input_)
input_hex = [h.hex() for h in input_]
return f"0x{''.join(input_hex)}"
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#hash
def hashFunc(input_):
assert isBytesN(input_)
h = hashlib.new('sha256')
for byte in input_:
h.update(byte)
return hexToBytesN(h.hexdigest())
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#xor
def xor(bytes_1, bytes_2):
assert all([isBytesN(bytes_1), isBytesN(bytes_2)])
assert len(bytes_1) == len(bytes_2)
return [(int.from_bytes(a, ssz_byteorder) ^ int.from_bytes(b, ssz_byteorder)).to_bytes(8 // 8, ssz_byteorder) for a, b in zip(bytes_1, bytes_2)]
##### Main function #####
if __name__ == "__main__":
# (T-1)th slot := 4810145 (block_number := 15646555)
# (T)th slot := 4810146 (block_number := 15646556)
# Some information we've already known
prev_randao_4810145 = "0xab2dc18a256fd4dc62debeddf2d2d8ef3e9801bde1bf2e4b5cf57680e9de1982"
randao_reveal_4810145 = "0xa1510a1b094b716fbce31774c59ec33fe5d3d5d1da5f14c70a4db806aa3bddc80bd3bd3977d0f19bd622d0fa722557a4026ffca0c661c650bdc8e3d1d0128308d0cecdb7529b5e735d6763206fad9f19dba099dc3d0fb17941ab35d7b98fcd01"
prev_randao_4810146 = "0x7494e81527372a7d3305a32703e2e0bcfad7646436ab4521bcc02f1e0cbdd6be"
# [Step 0] Previous slot information
prev_randao_T_1 = prev_randao_4810145
randao_reveal_T_1 = randao_reveal_4810145
# [Step 1] Convert hex string to `bytes`
prev_randao_T_1_Bytes32 = hexToBytesN(prev_randao_T_1[2:])
randao_reveal_T_1_Bytes96 = hexToBytesN(randao_reveal_T_1[2:])
# [Step 2] Calculate SHA256 of `randao_reveal`
hash_of_randao_reveal_T_1_Bytes32 = hashFunc(randao_reveal_T_1_Bytes96)
# [Step 3] Calculate XOR of SHA256(`randao_reveal`) and `prev_randao`
prev_randao_T_Bytes32 = xor(prev_randao_T_1_Bytes32, hash_of_randao_reveal_T_1_Bytes32)
# [Step 4] Print the result
assert bytesNToHex(prev_randao_T_Bytes32) == prev_randao_4810146
print(f"prev_randao: {prev_randao_4810146}")
print(f"My result: {bytesNToHex(prev_randao_T_Bytes32)}")
@a2468834
Copy link
Author

a2468834 commented Sep 16, 2022

@a2468834
Copy link
Author

Revisions 2: re-write codes that follow the Ethereum consensus-specs

@a2468834
Copy link
Author

Revisions 3: update codes to calculate slot 4810145 and 4810146

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment