Skip to content

Instantly share code, notes, and snippets.

@Th0rgal
Last active June 12, 2022 10:35
Show Gist options
  • Save Th0rgal/49bb94f9528a8c0212305541d51535dd to your computer and use it in GitHub Desktop.
Save Th0rgal/49bb94f9528a8c0212305541d51535dd to your computer and use it in GitHub Desktop.
@storage_var
func my_var(id : felt) -> (content : felt):
end
@view
func test_my_var{syscall_ptr : felt*, range_check_ptr, pedersen_ptr : HashBuiltin*}():
alloc_locals
my_var.write(7, 'hello')
let (local keccak_ptr_start : felt*) = alloc()
let keccak_ptr = keccak_ptr_start
let (local bitwise_ptr_start : BitwiseBuiltin*) = alloc()
let bitwise_ptr = bitwise_ptr_start
# int.from_bytes(b'my_var', 'little') = 125762923362669
# 125762923362669 to binary = 011100100110000101110110010111110111100101101101
# len("011100100110000101110110010111110111100101101101")/8 = 6
let (name : felt*) = alloc()
assert name[0] = 125762923362669
let (inputs : felt*) = alloc()
assert inputs[0] = 7
let (addr) = find_storage_addr{bitwise_ptr=bitwise_ptr, keccak_ptr=keccak_ptr}(
name, 6, 1, inputs
)
# then we could try to use storage_read to ensure that the value is 'hello'
return ()
end
# requires to call unsafe_keccak_finalize after usage
func find_storage_addr{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr,
bitwise_ptr : BitwiseBuiltin*,
keccak_ptr : felt*,
}(name : felt*, name_bytes : felt, inputs_len : felt, inputs : felt*) -> (addr : felt):
if inputs_len == 0:
let (addr : felt) = starknet_keccak(name, name_bytes)
return (addr)
end
let (next : felt) = find_storage_addr(name, name_bytes, inputs_len - 1, inputs)
# this will be executed at the end so we need to start by the end of inputs
let input : felt = inputs[inputs_len - 1]
let (output) = hash2{hash_ptr=pedersen_ptr}(next, input)
return (output)
end
func starknet_keccak{
syscall_ptr : felt*,
pedersen_ptr : HashBuiltin*,
range_check_ptr,
bitwise_ptr : BitwiseBuiltin*,
keccak_ptr : felt*,
}(data : felt*, data_bytes : felt) -> (hash : felt):
# A variant of eth-keccak that computes a value that fits in a StarkNet field element.
#
# Parameters:
# data: The data to hash.
# data_bytes: The number of bytes in data.
#
# Returns:
# The hash of the data truncated to fit in a StarkNet field element.
let (res : Uint256) = keccak(data, data_bytes)
# we want to return res & 2^250-1
# low contains the 128 least significant bits of res
# high contains the 128 most significant bits of res
# 250-128 = 122, so we need to return low + 2^128*(high & MASK_122)
let suffix : felt = bitwise_and(res.high, 5316911983139663491615228241121378303)
return (res.low + suffix * 340282366920938463463374607431768211456)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment