美文网首页
StarkNet最新进展报告

StarkNet最新进展报告

作者: 雪落无留痕 | 来源:发表于2023-09-10 16:38 被阅读0次

StarkNet 主网仍处于Alpha 阶段,核心的代码(Prover, StarkNet OS, L1 core Contract)尚未开源。

基本概念

区块结构

区块头的结构为:

交易结构

StarkNet 支持两种交易类型:

  • invoke 交易: 主要用来调用合约函数;
  • declare 交易: 主要用来引入新的classes;

deploy 交易目前从StarkNet移除,部署合约可以采用syscall 调用。

invoke 交易的结构为:

declare 交易的结构为:

合约

合约ABI

合约ABI 为JSON 格式:

starknet-compile contract.cairo \
    --output contract_compiled.json \
    --abi contract_abi.json

合约地址

采用pedersen hash计算:

contract_address := pedersen(
    “STARKNET_CONTRACT_ADDRESS”,
    caller_address,
    salt,
    pedersen(contract_code),
    pedersen(constructor_calldata))

合约类(Classes)

类似于面向对象编程,StarkNet 将合约的实现分为类(Class)和 实例(Instance).

合约类由Cairo 字节码定义,通过类hash识别; 合约实例对应着合约类,有相应的存储空间,能被交易和其它合约调用。

合约类并非特别需要部署合约实例;

合约类通过declare 交易添加; 合约实例通过deploy 系统调用实现。

可以使用library_call调用合约类代码,类似于以太坊的deletgatecall.

合约存储

合约有2^{251}个存储slots, 初始值为0;

存储值的读取:

let (value) = storage_read(key)

存储什的写入:

storage_write(key, value);

系统调用

合约调用的方法为:

func call_contract{syscall_ptr : felt*}(
    contract_address : felt, function_selector : felt, calldata_size : felt, calldata : felt*
) -> (retdata_size : felt, retdata : felt*)

合约部署的语法为:

func deploy{syscall_ptr : felt*}(
    class_hash : felt,   // 合约类的Hash
    contract_address_salt : felt,
    constructor_calldata_size : felt,
    constructor_calldata : felt*,
) -> (contract_address : felt)

抛出事件为:

func emit_event{syscall_ptr : felt*}(keys_len : felt, keys : felt*, data_len : felt, data : felt*)

获取区块号:

func get_block_number{syscall_ptr : felt*}() -> (block_number : felt)

获取区块的时间戳

func get_block_timestamp{syscall_ptr : felt*}() -> (block_timestamp : felt)

获取调用者的地址:

func get_caller_address{syscall_ptr : felt*}() -> (caller_address : felt)

获取合约的地址:

func get_contract_address{syscall_ptr : felt*}() -> (contract_address : felt)

获取sequencer的地址

func get_sequencer_address{syscall_ptr : felt*}() -> (sequencer_address : felt)

获取原始交易的信息

func get_tx_info{syscall_ptr : felt*}() -> (tx_info : TxInfo*)

调用合约类方法,类似于delegatecall 方法:

func library_call{syscall_ptr : felt*}(
    class_hash : felt, function_selector : felt, calldata_size : felt, calldata : felt*
) -> (retdata_size : felt, retdata : felt*)

调用L1 handler

func library_call_l1_handler{syscall_ptr : felt*}(
    class_hash : felt, function_selector : felt, calldata_size : felt, calldata : felt*
) -> (retdata_size : felt, retdata : felt*)

向L1 发送消息

func send_message_to_l1{syscall_ptr : felt*}(
    to_address : felt, payload_size : felt, payload : felt*
)

读取合约存储的值

func storage_read{syscall_ptr : felt*}(address : felt) -> (value : felt)

向合约存储写入值

func storage_write{syscall_ptr : felt*}(address : felt, value : felt)

Account abstraction

抽象账户可以实现:

  • signature abstract: 更改验证逻辑;
  • fee abstraction: 可以用不同的token 支付手续费;
  • Nonce abstraction: 支持并行广播交易。

StarkNet 的抽象账户必须包含以下两个函数:

  • __validate__: 保证Sequencer 只打包有效的交易。
  • __execute__: 主要执行交易。

关于账户Nonce, 目前顺序递增的模式,以后将升级到Nonce abstraction.

目前对于无效的交易,Sequencer 并不打包,以后将对失败交易也将打包,并扣手续费。

交易的手续费采用ETH 支付。

链上数据

目前StarkNet 仍然是ZK-Rollup模式,将state diff 以calldata 形式存储上链。

state diff 包含包更新 合约存储以及部署合约的信息,采用uint256[] 格式,包含以下数据:

  • 部署合约的个数:

  • 对于每个部署的合约,包含:

    • contract_address: 部署合约的地址;
    • contract_hash: 部署合约的hash;
  • 更新的合约的个数:

  • 对于每个更新合约:

    • contract_address: 合约的地址;
  • num_of_storage_updates: 存储更新新的个数;

    • nonce, num_of_storage_updates: 更新的nonce 和 存储更新的个数;
  • 对于每个存储更新:

    • key: 在合约存储的位置;
      • value: 新的值

Hash 函数

所有的Hash 输出映射到 \mathbb{F}_p, 其中 p = 2^{251}+17\cdot2^{192} + 1

StarkNet 主要使用两种Hash函数:

  • sn_keccak: \{0,1\}^* \rightarrow \mathbb{F}_p;
  • pedersen: \mathbb{F}_p \times \mathbb{F}_p \rightarrow \mathbb{F}_p

sn_keccak 根据 Keccak256 派生。

Pedersen hash 采用STARK 友好的椭圆曲线:
y^2 = x^3 + \alpha x + \beta
其中:

  • \alpha = 1 ;
  • \beta = 3141592653589793238462643383279502884197169399375105820974944592307816406665

对于 (a,b)\in\mathbb{F}_p^2 ,可以将其分解为 a_{low}, a_{high}, b_{low}, b_{high}, Pedersen hash 的定义为:
h(a,b) = \left[shift\_point + a_{low} \cdot P_0 + a_{high} \cdot P1 + b_{low} \cdot P2 + b_{high} \cdot P3\right]_x
其中 shift\_point, P_0, P_1, P_2, P_3 是常量。

事件

StarkNet 可以抛出事件,包含以下字段:

  • from_address: 发出事件的合约地址;
  • keys: 用来检索事件的keys;
  • data: 日志的值

日志的定义:

@event
func message_received(a : felt, b: felt):
end

日志的发出:

message_received.emit(1, 2);

手续费

手续费由ETH支付,主要有两部分:

  • 计算复杂度: 交易涉及计算越复杂,费用越高;
  • 链上数据: 主要是L1 calldata 和 L2->L1的消息。

手续费的计算公式为:
F = gas\_price \cdot\left(\max_k v_k w_k + c_w\left(2(n+m) + 3t + \sum\limits_{i=1}^t q_i + 2\ell\right)\right)

消息传递机制

L2上的合约可以和L1上的合约交互,通过 send_message_to_L1 系统调用。

当状态在L1上更新之后,消息存储在L1上的 StarkNet Core Contract 上,并发出 LogMessageToL1 事件。

随后,接收者通过 consumeMessageFromL2 消费传递的消息。

L2->L1的消息包含 FromAddress, EthereumAddress, Payload.

对于L1->L2消息,包含以下几个阶段:

  • 用户调用sendMessageToL2 发起L2合约的调用,L1合约记录支付的手续费;
  • 消息解码为StarkNet 交易,也称为L1 handler transactions.
    • Sequencer 在看到L1交易确认后,发起L2交易;
    • L2交易会调用l1_handler.
  • L1 Handler transaction 被提交到L1合约,并实现状态更新。

L1 -> L2 消息包含以下字段:

  • L1 发送者地址
  • 接收者合约地址
  • 函数 selector
  • Calldata
  • Message Nonce

对于L1->L2失败的交易,用户可以在L1调用 startL11ToL2MessageCancelldationcancelL1toL2Message进行取消.

L1 handler transaction 包含的字段为:

  • Version
  • ContractAddress
  • Selector
  • Calldata
  • Nonce

StarkGate

StarkGate 主要实现ETH和ERC20在L1和L2之间发跨链。

**L1->L2 Transfer (Deposit) **

用户在L1发起 deposit 操作,发出deposit 事件,并向L2 发送一个消息。当交易在L1确认后,由Sequencer在L2 触发L1 handler handle_deposit 操作。当L1 handler 交易被打包进区块并提交到L1上时,完成整个操作。

L2 -> L1 Transfer (Withdraw)

用户首先在L2 发起initiate_withdraw 函数 ,并向L1 发送消息。当交易打包到区块并在L1 确认后,用户即可在L1 发起取款操作。

StarkNet State

StarkNet 的状态包含:

  • 合约实例: 为地址到合约状态的映射
  • 合约类: 为合约类Hash到合约 类定义的映射;

合约的状态由以下组成:

  • 类hash;
  • contract 存储;
  • contract nonce;

状态承诺为:

h(h(h(class_hash, storage_root), nonce),0)

整个状态采用MPT 树数据结构。

账户创建

通过StarkNet CLI 工具, 初始化一个账户:

starknet new_account

初始化完成之后,还需要部署账户:

starknet deploy_account

StarkNet 合约示例

// Declare this file as a StarkNet contract.
%lang starknet

from starkware.cairo.common.cairo_builtins import HashBuiltin

// Define a storage variable.
@storage_var
func balance() -> (res: felt) {
}

// Increases the balance by the given amount.
@external
func increase_balance{
    syscall_ptr: felt*,
    pedersen_ptr: HashBuiltin*,
    range_check_ptr,
}(amount: felt) {
    let (res) = balance.read();
    balance.write(res + amount);
    return ();
}

// Returns the current balance.
@view
func get_balance{
    syscall_ptr: felt*,
    pedersen_ptr: HashBuiltin*,
    range_check_ptr,
}() -> (res: felt) {
    let (res) = balance.read();
    return (res=res);
}

合约编译:

starknet-compile contract.cairo \
    --output contract_compiled.json \
    --abi contract_abi.json

合约声明:

starknet declare --contract contract_compiled.json


Declare transaction was sent.
Contract class hash: 0x1e2208b571b2cb68908f37a196ed5e391c8933a6db23bb3939acedee40d9b8a
Transaction hash: 0x762e166dd3326b2e263eb5bcfdccd225dc88e067fdf7c92cf8ce5e4ea01f9f1

合约部署:

starknet deploy --class_hash $CLASS_HASH

Invoke transaction for contract deployment was sent.
Contract address: 0x039564c4f6d9f45a963a6dc8cf32737f0d51a08e446304626173fd838bd70e1c
Transaction hash: 0x125e4bc5251af8ee2664ea0d1495b36c593f25f78f1a78f637a3f7aafa9e22

合约调用:

starknet invoke \
    --address ${CONTRACT_ADDRESS} \
    --abi contract_abi.json \
    --function increase_balance \
    --inputs 1234

合约查询:

starknet call \
    --address ${CONTRACT_ADDRESS} \
    --abi contract_abi.json \
    --function get_balance

参考

https://starkware.co/starknet/

https://docs.starknet.io/documentation/

https://medium.com/starkware/papyrus-an-open-source-starknet-full-node-396f7cd90202

https://starknet.io/

https://github.com/eqlabs/pathfinder

https://eprint.iacr.org/2021/1063.pdf

https://github.com/starkware-libs/cairo-lang

https://github.com/starkware-libs/papyrus

https://github.com/OpenZeppelin/cairo-contracts

https://github.com/starknet-io/starkgate-contracts

https://starknet.io/docs/hello_cairo/index.html#hello-cairo

https://starkscan.co/

https://github.com/NethermindEth/juno

https://github.com/starkware-libs/cairo

https://starknet.io/

相关文章

网友评论

      本文标题:StarkNet最新进展报告

      本文链接:https://www.haomeiwen.com/subject/awmsvdtx.html