Starknet学习之了解Starknet基础知识了解Starknet基础知识主题为什么选择Cairo为什么选择Starknet智能钱包Starknet架构101TransactionsStarknet相关名称的了解与区分STARKWARE:是位于以
Starknet
基础知识Starknet
基础知识Cairo
Starknet
Starknet
架构 101Transactions
Starknet
相关名称的了解与区分STARKWARE
:是位于以色列的公司,开发了 Starknet
,包括 Starknet
相关的技术,目前负责构建和发展, Starknet
的核心团队是 Starkware
的员工。 Starkware
的创始人及现任的CEO 发明了 Starks ZK
的证明,这种证明推动了所有这些创新。 STARKWARE
做的第一个 ZKSTARKS
的实现被称为 STARKEx
,STARKEx
是一个需要授权的系统,所以你不能直接使用STARKEx
,你需要与 STARKWARE
签订合同协议才能使用它。STARKEx
有一些固定的功能,比如说你可以交易代币,做期货合约、资产交易等待。例如:DYDXVERSION3
实际就是运行在 STARKEx
上的。许多应用程序幕后都是使用的是STARKEx
。 这是 STARKWARE
开发的第一个产品。
实际上Cairo
就是为 STARKEx
开发的。最初是作为一种内部工具,以便更容易提高系统的能力,一段时间以后,它们希望创建一种系统,使用相同的技术、相同类型的零知识证明,使得人们可以自己使用 Cairo
创建智能合约,并随时部署它们,无须任何许可。这就是 STARKNET
。因此 STARKNET
是一个无需许可的系统。是一个二层汇总。使用以太坊作为安全层,你可以通过智能合约部署你的代码逻辑,无需得到 STARKWARE
的任何许可。
STARKNET Foundation
: STARKNET
基金会是成立大约一年的一个非营利组织。目标是帮助发展 STARKNET
生态系统,或者与一些开发者达成协议来创建一些应用,或者帮助分散系统的治理。
Cairo
为什么要开发另一个编程语言而不是直接使用以太坊,首先Cairo
是一种通用的编程语言,我们可以通过一个例子来解释 为什么选择 Cairo
:
这个例子是一个太空探索问题。
如何节省燃料
最佳发射窗口
最佳发射轨迹
工程师写算法
假设你是一个国家的航空航天探索机构的负责人,你的目标是将航天器送到火星,所以你需要尽可能的节省燃料,使火箭尽可能小,尽可能便宜找到这个火箭发射的最佳轨道。那你需要计算这些变量,这些变量的计算是非常复杂的,你的工程团队可能要选择一些高性能的语言,比如Rust来创建一个程序并找到这个变量的值,这个程序太复杂,你需要一台超级计算机来运行这个程序,在合理的时间内得到结果,否则在普通的电脑上可能需要很长时间。而问题是你的机构甚至你的国家都没有超级计算机,唯一的办法是让一个竞争的国家同意让你使用他们的超级计算机来运行你的程序。因为这是一个竞争国家,但是你又没有其它选择,所以你也只能选择合作。你把代码给他们,让他们运行,得到结果以后再给你,当你拿到结果以后,你会遇到一个问题,你怎么知道这个竞争国家的超级计算机,在运行你的程序时没有出现故障,你怎么知道竞争国家或机构没有篡改结果。即使是一个小的改变,都可能让整个航天探索技术脱轨。你不能信任这些结果,不知道它们是否被正确执行,唯一知道结果是否正确的方法是,请求另一拥有超级计算机的国家来运行这个程序,并比较结果,多次这样做以后,来避免串通。如果足够多的超级计算机给出相同的结果。你才能够信任它,但是这样非常低效,而且也非常昂贵。
与竞争国家合作
执行算法程序需要超级计算机
但是只有竞争国家有
如果你的工程是不是使用其他编程语言,而是是Cairo
。当你把你的程序交给竞争国家执行时,他们将不得不在Cairo
的虚拟机上运行代码。并且会像之前一样给到你执行的结果。现在他们还会给你一个执行后的加密证明。你可以在自己的电脑上去验证这个加密证明。如果证明有效,你几乎可以百分百确定没有人篡改过执行结果。系统也没有故障,因为如果有故障的话,证明将无效。竞争的国家无法伪造一个假的证明来欺骗你,接受错误的结果。换句话说,现在你又拥有了一种超能力,即你可以用普通电脑、笔记本甚至智能手机来验证超级计算机的同时性,如果它们作弊,你会立刻知道。只有像Cairo
这样的语言才能实现。这也是目前唯一具备这种特性的高级语言。
执行 竞争国家 结果 + 证明
Cairo
特征CairoVM
上运行Rust
的语法traits macros
ZK
STARKNET
创建智能合约// 这个 trait 只定义了两个方法, 方法只定义了签名 没有定义实现
// rust 当中不需要定义 self 的类型 这里使用 T 通用类型
// cairo 借用了很多 Rust 的东西,但它并不是完全一样的,所以有一些不同的点需要注意
pub trait ShapeGeometry<T> {
fn boundary(self: T) -> u64;
fn area(self: T) -> u64;
}
mod rectangle {
use super::ShapeGeometry;
#[derive(Copy, Drop)]
pub struct Rectangle {
pub heigth: u64,
pub width: u64,
}
// Rust 使用的是 for 而 cairo 使用的 of
impl RectangleGeometry of ShapeGeometry<Rectangle> {
fn boundary(self: Rectangle) -> u64 {
2 * (self.height + self.width)
}
fn area(self: Rectangle) -> u64 {
self.height * self.width
}
}
}
Cairo 就是一种高级语言、强类型、非常灵活、非常类似于 Rust,但是并不完全相同
Starknet
智能合约中怎么写?#[starknet::contract]
Storage
#[storage]
来注解#[starknet::interface]
trait ISimpleStorage<TContractState> {
// 当你有一个方法实际上想修改智能合约内部状态时,你需要传递智能合约的状态,self 参数作为引用 ref
fn set(ref self: TContractState, x: u128);
// 如果从状态中只读而不修改 可以请求状态作为快照作为传递 快照使用 @ 符号
fn get(self: @TContractState) -> u128;
}
#[starknet::contract]
mod SimpleStorage {
#[storage]
struct Storage {
stored_data: u128
}
// 以下实现将成为智能合约的 ABI ,所以这是任何人都可以调用的智能合约的公共接口
#[abi(embed_v0)]
impl SimpleStorage of super::ISimpleStorage<ContractState> {
fn set(ref self: ContractState, x: u128) {
self.stored_data.write(x);
}
fn get(self: @ContractState) -> u128 {
self.stored_data.read()
}
}
}
这是一个非常简单的示例,说明了如何从智能合约中读取和写入,并定义了智能合约的公共接口。
Cairo
使用 Cairo
可以在不重新执行的情况下,验证结果是否正确
Cairo
是一种强大且灵活的语言,部分原因是它是一种高级语言,抽象了所有ZK 的复杂性,并借用了许多Rust的语法,它防止了作弊,它通过ZK 证明保证超级计算机的结果不被篡改。这就是我们在 Starknet
上实现扩展的方式。
Starknet
L1 的扩展问题 当前以太坊的工作方式
在以太坊中有一台机器被随机选中,生成一个新块
生成块的所有者也被称为见证者
块生成者会收集交易创建这个块并告诉全世界,如果执行这个块中的所有交易,最终会得到以太坊网络新的全局状态。为了简单,假设这个新的块的状态的值是 42,块的生成者会告诉全世界这个新状态,当然在以太坊情况下,其他验证者是不会轻易相信块生成者的结果,其它验证者拿到块生成者创建的块,他们会执行其中的所有交易,并验证是否得到相同的最终状态。这是验证者保证生成者诚实的一种方式,也是系统保证状态的安全的一部分。因为所有机器都会独立的进行相同的工作,以验证结果是否一致。这是非常健壮的共识过程,确保只要至少一半的网络是诚实的,就能防止任何人作弊,缺点是效率非常低下。因为即使是一个包含少量交易的简单的块,也需要全球成千上万太机器独立重新执行,来比较结果。因此可以看到这种方式虽然健壮,但效率低下。
在 Starknet
中当提一个新块时,这个块不是为 L1 准备的,而是为 L2 准备的。它会创建块并执行交易,同时宣布新的状态为 42 ,但它会同时提供这个执行的加密证明。因为它的底层使用了 Cairo
。因此以太坊上的验证者不需要重新执行块中的所有交易,来验证这个 42 是最终状态。他们只需要验证 ZK 证明即可。如果证明有效,他们就能够确定新状态是 42 号。因此以太坊上的所有验证者只需要验证证明,这种验证只需要花费重新执行所有交易的一小部分算力。
可以看到,当你从整体系统来看,性能得到了很大的提升。当然这里有一个小小的代价,因为 Starknet
不仅要执行交易,而且还要创建相关的加密证明,这需要额外的算力。但是你只需要执行一次就可以在任何地方验证。而不是在每个地方都需要重新执行。
这就是我们能够依赖以太坊在相同的级别下处理更多交易的方式。
成本更低,因为大部分工作在 Starknet
上一台计算机就可以完成,而以太坊网络的成本只是其中的很小的一部分。
执行和验证
验证和执行我们进行比较一下,验证比执行更便宜。但到底有多便宜呢?
假设 x 是 Sequencer,也就是 Starknet
中的排序器。
Sequencer
执行一个交易或所有区块中的交易
x 是这些所有这些交易所需要的步骤的数量级
以太坊验证者确认这个新状态的步骤需要 log²(x)
x
是 Sequencer
的工作量
在以太坊上工作量只是一个对数级别
Sstarknet
上区块越大、执行的交易越多,log²(x)
的增长速度是远低于实际这个基数计算的。
所以差距会越来越大,性能收益会越来越多,同时保持相同的安全级别。
有效性证明对计算来说,类似于 zip 算法对文件大小的作用是一样的,同样都属于一种压缩类型。
有效性证明创建了计算的压缩
Zip 创建了文件大小的压缩
什么是 Starknet
使用的有效性证明
它是零知识证明的一个用例
你可以使用 ZK 证明来实现隐私保护或者用它来作为扩展
我只需要发送有效性证明,不需要发送在 L2 上发生的所有交易的细节和详细信息,来进行在 L1 上的验证。
因此我们发送到 L1 上的数据量要比乐观汇总小很多。
乐观汇总实际上需要发送所有 L2 上发生的交易细节,这就是为什么乐观汇总在性能上很难与 Starknet
这样的 ZK 汇总竞争。
因为从定义上讲,它们必须发送所有这些交易细节给外部实体以确保没有人作弊,并且允许大家提交其它证明,我们不需要分享 L2 上的交易细节,或者说它们不是验证加密证明所必须的。
这并不意味着STARKNET
上的交易是私密的
STARKNET
上现在并不是为了隐私而构建的,它只是为了扩展
所以一些细节实际上是会泄露,但并不需要介意,因为STARKNET
上不是为了隐私而是为了性能,并且这样做会使验证非常高效、非常简洁
因为我们在系统中使用有效性证明,我们更倾向于把它称为有效性汇总(ZK 汇总)
基于 STARKs
非 SNARKs
STARK | SNARK | |
---|---|---|
Verification | log²(n) |
constant |
Proof Size | ~ 400 KB | 288 bytes |
Proving Time | 1x | 10x |
Trusted Setup | No | Yes |
Quantum Secure | Yes | No |
基于 SNARKs
的系统是需要可信设置的(安全秘钥)
STARKs
是量子安全的
Compatibility Performance
Cairo
虚拟机
牺牲兼容性
获得最大的性能
你不能在 Starknet
上部署一个 solidity
智能合约
你必须重写代码逻辑
然后转换为 Cairo
并使用它
ZKEVM
为了实现兼容性,中间有很多转换和摩擦,最终会成为性能的瓶颈
https://vitalik.eth.limo/general/2022/08/29/zkevm_zhTW.html
EVM Changes | Compatibility | Performance | Projects | |
---|---|---|---|---|
Type 1 | Nothing | Full | Very Slow | - |
Type 2 | Storage data structure | High | Slow | - |
Type 3 | Storage hashes precompiles | Partial | Fast | Kakarot, zkSync, Scroll, Polygon, zkEVM |
Type 4 | Completely different VM | None | Very Fast | Starknet, Aztec*, Polygon Miden |
以太坊的最终确认大约是每6分钟实现一次
在乐观汇总中,从 L2 提取资金到 L1,大约需要一周的时间
在 Starknet
的情况下,这个等待时间只有2个小时
每2个小时就从 Starknet
发送有效性证明到 L1
一旦证明被验证,你就可以讲资金转移到 L1
L2 的最终确认也就是 Starknet
的最终确认非常短
目前大约三秒钟,因此确认交易的速度非常快
只有在你想要将资产取回到 L1 时,才需要等待两个小时
与乐观汇总相比,在这方面是一个很大的优势
关于 Starknet
的性能的统计
Starkscan.co
Starknet
的TPS 峰值是每秒大约52笔交易
看起来不算多,但在Starknet
上每笔交易实际上是多个交易捆绑在一起的
所以更好的比较是使用 PS,也就是每秒用户操作数
Starknet
https://docs.starknet.io/quick-start/deploy-interact-with-a-smart-contract-remix/
Argent
和 Braavos
Starknet
上的一个DeFi项目,你可以在一次点击 Swap,而无需逐步进行批准和交易,它在单笔交易中就完成了所有操作,你只需要签署一次交易就可以了。Starknet
上每个钱包都是智能钱包,这个是与以太坊完全不同的Starknet
上所有的钱包都是基于账户抽象,都是智能钱包,是没有EOA钱包的概念的DeFi 的 Swap
一次 Swap 要分别进行批准和交易,这是在以太坊上常见的交易方式
这两笔交易实际上只是一个单个过程的两个步骤
在以太坊上由于你签署了两笔交易,你可能会认为他们会安装你定义的顺序,会被包含在同一个区块中。但实际上并非如此,你无法控制这些交易被包含在区块中的顺序,可能会发生以下情况:
Starknet
上你可以在单笔交易中包含多个用户操作,我们称之为捆绑。这样就可以确保这些交易,首先会被包含在同一个区块中,并且按照你定义的顺序执行,不会有其他交易插入其中,因此你可以防止某些类型的攻击,例如三明治攻击。STARKWARE
控制的序列器。也就是排序器 Sequencer
。签名者
账户
账户抽象是智能钱包的基础
账户抽象实际上是将签署者与账户分离
签署者是签署交易的设备,可以是你的手机或者笔记本电脑
在 Starknet
上私钥通常可以存储在系统的安全区
账户是在Starknet
上的一个智能合约,它持有资产’、验证签名、负责执行多重调用
每个 Starknet
账户都有一个与之关联的智能合约,只是响应你的签署者
因此只有你的签署者可以发起交易,因为账户具有验证交易签名的逻辑,只允许你的设备发送交易
如果你在手机上安装了钱包,例如Argent
或 Braavos
,你的手机就是签署者
当你想在 Starknet
上执行交易时, 你的签署者会将交易发送到你的智能合约,账户合约将验证签名,如果有效,就会执行交易,调用目标合约,实际上是你的账户合约在调用目标合约,只是响应签署者的请求,签名验证是可以编程的,所以你可以进行更高级的操作。
允许多种签名逻辑
支持的 Elliptic Curves
STARK-friendly(native)
Secp256k1(Ethereum)
Secp256r1(standard)
例如你可以有一个单一的签署者,默认情况下是Argent
和 Braavos
钱包使用这种方式。
你也可以有多个签署者,类似于多重签名,但更像原生的多重签名,由所有应用程序支持。
相比之下,在以太坊上当你使用多重签名时,一些应用程序不支持通过多重签名钱包进行交易
账户合约或基于智能合约的钱包,在以太坊生态系统中是二等公民
而在 Starknet
上它们都是同类型的钱包,只是配置不同,所以它们都是一等公民
你可以做一些更高级的事情,比兔硬件签署,使用你的 Face ID 或者 Touch ID,利用手机或笔记本电脑的安全系统,你还可以进行一些恢复。
如果你丢失了钱包的访问权限,可以定义朋友或家人来帮助你恢复秘钥,通过某种离线的验证,你还可以有会话秘钥。
“会话密钥”是一个常见的术语,在加密和安全领域中广泛使用。它指的是在通信会话期间使用的临时密钥,用于加密和解密信息,以确保数据的保密性和完整性。会话密钥通常是在通信双方建立连接时生成的,并在会话结束后被丢弃。
在离线验证的上下文中,会话密钥可以用于对数据进行加密或签名,然后在不需要实时在线的情况下验证数据的真实性或完整性。这种方法可以提高安全性,因为即使攻击者获取了加密的数据,由于会话密钥是临时的,他们也无法解密数据或伪造消息。
会话秘钥就是session keys
,它对游戏是非常有用的。这样你就不必每次操作都需要去签署交易。只需要为游戏客户端提供一个具有有限权限的秘钥为你自动签署交易。
所谓有限权限指的是包括时间和资产都是有限的。
你还可以支持多种类型的椭圆曲线,可以让你在签名是有更多的灵活性
当你将账户抽象与手机安全结合使用时,它会将你的智能手机变成几乎像硬件钱包一样的东西。
如果你查看任何智能手机实际上是有两个系统,一个是所有应用程序共享的系统,我们称为 Shared System
,共享内存以及CPU;另一个是更小的系统称为安全区(Secure Enclave
),不同的供应商有不同的名称。
主要用于随机数生成、加密秘钥管理、硬件签名,这是Touch ID 或 Face ID 使用的系统。因此它有一个专门的处理器和内存,只用于这些高安全性的加密操作。
通过账户抽象,你实际上可以访问这个系统来进行交易签名。
在以太坊上,钱包只能使用共享系统。这主要是由于以太坊支持的椭圆曲线、签名的类型与硬件行业支持的标准不一致。
Secure Enclave
中 这种特定的曲线被称为 Secp256r1
对安全区的名称:
苹果称为 Secure Enclave
谷歌称为 Titan M
三星称为 Knox
Arm 称为 TrustZone
智能钱包的好处在于你获得了比普通钱包更好的用户体验,可以进行多次调用硬件签署来恢复会话秘钥。所有这些都是由账户抽象实现的。即将签署者与账户分离。
账户是一个具有特定接口的智能合约。
因此每次创建账户时,你都有签署者和 Starknet
上的账户合约。
它支持使用不同的椭圆曲线进行签名
在 Starknet
上每个钱包都是智能钱包,没有外部账户(EOA)
Starknet
架构 101Cairo
是一种可证明的编程语言,它的语法类似于Rust。Cairo
不直接编译为 Cairo AM
字节码
这个编译过程是由排序器 Sequencer
完成的
Sierra
确保即使交易失败,它也会以一种与可证明系统兼容的方式失败,如果不这样做会有一个拒绝服务的漏洞。
Sierra
允许 Cairo VM
和 字节码独立于 Cairo
语言本身的演变
因此我们可以对两端进行修改、而不必修改整个系统
证明者会输出有效性证明和计算结果
排序器作为 Starknet
中的一个节点
Cairo Program
Sierra
Sequencer
Sequencer
compile CASM
(Sierra
)Cairo VM
Prover
(SHARP
) RUN trace
validity proof
作为一个交易发送到 以太坊 Ethereum
进行 Verifier
result
在执行前必须:
用户用 txs 和 SN 交互
txs
必须签名
怎么知道排序器编译的版本真的就是你的程序编译后的版本呢?
也就是说,Sequencer
排序器可能会作弊
如何在没有证明的情况下检测到这种情况?
因为目前 Cairo
的编译器不是用 Cairo
编写的,是用 Rust写的。
编译不能被证明这个问题?解决方案:
长期方案是用 Cairo
编写一个 Cairo
编译器,这样编译就可以被证明
现在是当你声明一个智能合约时,你必须提供Cairo
汇编后的哈希值
声明和部署是Starknet
上两个不同的操作
声明智能合约只是在 Starknet
上注册代码
新的代码只需要声明一次
如果代码已经声明过,你不需要重新声明
声明的智能合约称为合约类
合约类是用来派生智能合约实例的蓝图
合约类由类哈希值标识,合约类是纯代码,没有内部存储,仅仅是蓝图,不用于直接调用或交易
要部署合约类的实例,你需要从合约类派生它并执行构造函数,然后得到一个智能合约实例,这就是我们通常指的智能合约。
智能合约有内部存储、这个合约实例由其地址标识,从同一个合约类或代码,可以通过调用构造函数部署多个实例。它们将拥有不同的地址。即使它们源自同一个合约类,但存储是不同的。
部署其他合约的智能合约
只有一个 selector
(智能合约中某个特定函数的唯一标识符):deployContract
内部使用 syscall : depoly
https://eips.ethereum.org/EIPS/eip-4337
通用部署者
智能合约部署
智能合约调用
Cairo
到 Sierra
Sierra
到 SafeCASM
Transactions
Starknet
上Starknet
节点称为 Sequencer
排序器Starknet
只有一个排序器,它具有类似内存池的功能Starknet
智能合约实际上时 Cairo
程序,因此必须在Cairo
虚拟机上执行Cairo
虚拟机,一旦执行完成,该执行的 trace 会发送到证明器,我们称其为 SHARP
SHARP
的原因是它不只是给 Starknet
使用,也给STARKEx
使用Starknet
就会接收它, 这时候它的状态就会变成 RECEIVED
IGNORED
Starknet
不会知道你的交易Sequencer
排序器会忽略该交易,不会解析其中的数据。CairoVM
虚拟机中运行。CairoVM
执行该交易,它的状态会变为ACCEPTEN_ON_L2
。也就是在L2 上被接受。这就是在L2 上最终被确认的状态。是在Starknet
上执行你的交易后网络的新状态。REVERTED
。ACCEPTED_ON_L1
,也就是说在 L1 上被接受。总结:你的交易首先被内存池接收并确认,如果结构正确,通过签名验证,它将进入CairoVM
虚拟机执行,如果执行失败,交易将被拒绝。如果执行成功,交易将获得在L2 上被接受的状态,即 ACCEPTED_ON_L2
。并在L2 上达到最终确认。有效性证明生成后发送给以太坊的验证器,如果被接受,交易状态将变为在L1上被接受,即 ACCEPTED_ON_L1
。这就是整个生命周期
声明 Declare
调用 Invoke
部署账户 deploy_account
没有账户合约的前提下如何部署账户合约
deploy_account tx
部署账户合约与常规的智能合约是不同的
要部署智能合约你需要先有智能钱包
Tx 类型
Tx 生命周期
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!