我正在尝试解决“开罗如何运作”教程中的这个额外问题。我运行了以下函数,打开 Cairo 跟踪器,发现内存已满,且为 2 的幂。这是为什么呢?
func main():
[fp + 1] = 2; ap++
[fp] = 5201798304953761792; ap++
jmp rel -1
end
Run Code Online (Sandbox Code Playgroud)
据我了解,let定义了一个引用,可以将其视为别名,因此例如let x = y * y * y不计算y * y * y但出现的x将被替换y * y * y。局部变量与其他语言的局部变量类似。
如https://www.cairo-lang.org/docs/hello_cairo/dict.html中所示,写是什么意思let (local dict_start : DictAccess*) = alloc()?每个 的实例local dict_start : DictAccess*都会被替换为alloc()? 为什么不只是local (dict_start : DictAccess*) = alloc()或let (dict_start : DictAccess*) = alloc()?
如果在以太坊虚拟机中存储单个值需要花费 20000 Gas,那么在 StarkNet 端需要花费多少?同一插槽的后续更新是否更便宜?
我想确切的答案可能至少取决于以下几点:
如果没有确切的答案,一些粗略的指导方针会很好。
我们不深入研究链下存储(Validium)选项 - 这个问题集中在链上存储。
我经常可以使用不太优雅的代码来制作函数的终端递归版本。我应该这样做,因为它可以减少费用,还是应该保留未优化的版本?
例如,这是一个“未优化”的函数,它对数组的元素求和:
@view
func get_convoy_strength{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}(
convoy_id : felt
) -> (strength : felt):
alloc_locals
let (convoyables_len : felt, convoyables : felt*) = get_convoyables(convoy_id)
return _get_convoyables_strength(convoyables_len, convoyables)
end
Run Code Online (Sandbox Code Playgroud)
这是尾调用优化:
func _get_convoyables_strength_tc{
syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr
}(convoyables_len : felt, convoyables : felt*, sum : felt) -> (strength : felt):
if convoyables_len == 0:
return (sum)
else:
let convoyable_id = [convoyables]
alloc_locals
let (convoyable_strength) = _get_strength(convoyable_id)
return _get_convoyables_strength_tc(
convoyables_len - 1, convoyables + 1, …Run Code Online (Sandbox Code Playgroud)