Sui : 一个新的智能合约平台
Login to comment
Login to comment
Sui是一个分布式、开放的智能合约平台,侧重于低延时的去管理资产。它使用Move编程语言来将资产定义为可能属于某个地址的对象。Move程序定义了对这些类型化了的对象的操作,包括自定义初始化规则、资产如何传递给新的拥有者、以及改变资产的操作。Sui是由一组无权限的验证者(authorities)维护,这些验证者的角色类似于其他区块链中的验证器或是矿工。它在授权机构之间使用拜占庭一致的广播协议,以确保对资产进行操作的安全性。与拜占庭协议相比,确保了更低的延迟和更好的可伸缩性。它仅依赖于拜占庭协议来保证共享对象的安全,以及在关键延迟路径之外执行的治理操作和检查点。在某些情况下,智能合约的执行也会自然地并行化。Sui支持轻客户端来验证读取,也支持完整的客户端来审核所有状态转换的完整性。这些设施允许与其他类型的区块链建设的信任最小化的桥梁。
链上原生资产SUI代币用来支付所有链上操作的gas费用。SUI代币也被它的所有者用来在不同周期(epoch)内委托质押给不同的验证者来管理Sui。这些验证者会定期的根据这些委托质押给他们的SUI来重置配置。被使用的gas会根据分配给这些验证者,还有根据质押SUI的比例分配给质押者们。
本白皮书氛围两部分,第二部分描述了基于Move语言的Sui编程模型,第四部分描述了确保Sui的安全性(safety)、可终止性(liveness)和性能的无许可去中心化分布式系统的操作。
Sui的智能合约是用Move[4]语言编写的。Move安全且富有表现力,其类型系统和数据模型天然支持并行协议/执行操作来使得Sui具有很强的可伸缩性。Move是一种用来构建智能合约的开源编程语言,最开始是在Facebook为了Diem区块链开发的。Move语言和平台无关,除了被Sui采用之外,它在其他平台(即OL,StarCoin)也越来越受欢迎。
在本节中,我们主要会讨论关于Move语言的一些重要特性,并且解释如何使用它在Sui上创建和管理资产。关于Move的更全面解释可以在《Move Programming Language》里找到,更对针对Sui的Move内容可以在《Sui开发者门户》里找到,关于Sui上下文中Move的更正式的描述可以在第3节中找到。
Sui的全局状态包括一个可编程的对象池,由Move包来创建和管理,这些可编程对象是包含Move函数和类型的Move模块的集合(详见2.1.1节)。Move包本身也是对象。因此,Sui中描述的对象可以分为以下两类:
对象可以对资产进行编码(比如同质化代币/非同质化代币),授予调用某些函数或创建其他对象的权限的功能,管理其他资产的“智能合约”等。这些全都由程序员们来决定。
声明自定义的Sui对象类型的Move代码如下所示:
struct Obj has key {
id:VersionedID,
f: u64
g: OtherObj
}
所有表示Sui对象的结构(但不是所有的Move结构值)必须具有id字段和值能力(key ability),表明值可以存储在Sui的全局对象池中。
Move程序被组织为一组模块,每个模块由结构声明和函数声明的列表组成。一个模块可以从其他模块导入结构类型,并调用由其他模块声明的函数。
在一个Move模块中声明的值可以流动(flow)到另一个模块中,比如上面举例的模块Obj可以定义在与定义Obj的模块不同的模块中。这与大多数智能合约语言不同,后者只允许非结构化的字节跨合约边界流动。但是,Move能够支持这一点,因为它提供了封装特性来帮助程序员编写健壮性强[14]的代码。具体来说,Move的类型系统确保了像上面的Obj这样的类型只能由声明该类型的模块中的函数创建、销毁、复制、读取和写入。这允许模块对其声明的类型强制强不变量,即使它们在流经智能合约信任边界时也会继续保持。
全局对象池可以通过创建、销毁、读写对象的事务进行更新。事务必须接受希望操作的每个现有对象作为输入。
此外,事务必须包括包对象的版本ID、包内模块、函数的名称以及函数的参数(包括输入对象)。
例如调用下面这个函数:
public fun entrypoint {
o1: Obj, o2: &mut Obj, o3: &Obj, x: u64, ctx: &mut TxContext
} { ... }
事务必须为三个类型为Obj的不同对象提供ID,并为绑定到x的整数提供ID。 TxContext是由运行时填充的特殊参数,其中包含创建新对象所需的发送方地址和信息。
入口点(更一般地说,是任何Move函数)的输入可以通过在类型中编码的不同的可变性权限来传递。可以读取、写入、传输或销毁Obj输入。一个&mut Obj输入只能读或写,而一个& Obj 只能读。事务发送方必须被授权使用具有指定的可变权限的每个输入对象 -- 详见4.4节。
程序员可以通过使用传入入口点的TxContext来创建对象,为对象生成一个新的ID:
public fun create_then_transfer (
f: u64 , g: OtherObj , o1: Obj , ctx: &mut TxContext
) {
let o2 = Obj { id: TxContext::fresh_id(ctx), f, g };
Transfer::transfer(o1, TxContext:sender());
Transfer::transfer(o2, TxContext:sender());
}
这段代码接受OtherObj和Obj类型的两个对象作为输入,使用第一个对象和生成的ID创建一个新的Obj,然后将两个obj对象传输给事务发送方。一旦传输了对象,它就会流到全局对象池中,并且在事务的其余部分中不能通过代码访问。Transfer模块是Sui标准库的一部分,它包含了将对象传输到用户地址和其他对象的函数。
我们注意到,如果程序员代码忽略了包含一个转移调用,那么Move的类型系统将会拒绝该代码。Move强制资源安全[5]保护,以确保在没有权限的情况下不能创建、复制或意外销毁对象。资源安全的另一个例子是试图两次传输相同的对象,这也会被Move类型系统拒绝。
在本节中,我们将通过详细的语义定义来扩展第2节中对Sui编程模型的非正式描述。上一节展示了Move源代码的示例,示例里定义了Move字节码的结构。开发人员在本地编写、测试并正式验证Move源码,然后将其编译为字节码,再将其发布到区块链。任何发布在链上的Move字节码必须通过字节码验证器,以确保它满足关键属性,如类型、内存和资源安全。
正如在第2节中提到的,Move是一种平台无关的语言,它可以适应不同系统的特定需求,而不需要创建核心语言。在下面的描述中,我们从核心的Move语言(用黑色表示)中定义了这两个概念以及扩展核心Move语言的Sui-specific特性 (Instr 后的值 )。
Module = ModuleName×
(StructName ⇀ StructDecl)×
(FunName ⇀ FunDecl) × FunDecl
GenericParam = [Ability]
StructDecl = (FieldName ⇀ StorableType)×
[Ability] × [GenericParam]
FunDecl = [Type] [Type] × [Instr] × [GenericParam]
Instr = TransferToAddr | TransferToObj | ShareMut | ShareImmut | . . .
Move代码被组织到模块中,其结构定义如上所示。一个模块由一组命名结构体声明和一组命名函数声明组成(这些声明的例子在第2.1节中提供)。 模块还包含一个特殊的函数声明,作为模块初始化器。这个函数在模块发布到链上时只调用一次。
结构声明是命名字段的集合,其中字段名映射到可存储类型。它的声明还包括一个可选的能力列表(参见第2节的可存储类型和能力的描述)。struct声明还可以包括具有能力约束的泛型参数列表,在这种情况下,我们称其为泛型struct声明,例如struct Wrapper<T: copy>{T: T}。
泛型参数表示在声明结构字段时要使用的类型——在声明结构时它是未知的,而在实例化结构时提供了具体类型(例如:创建结构值时)。
函数声明包括形参类型列表、返回类型列表和组成函数体的指令列表。函数声明还可以包括具有能力约束的泛型参数列表,在这种情况下,我们称其为泛型函数声明,例如fun unwrap<T: copy>(p: Wrapper){}。与struct声明类似,泛型形参表示在函数声明时未知的类型,但在声明函数形参、返回值和函数体时使用(在调用函数时提供具体类型)。 可以出现在函数体中的指令包括所有普通的Move指令,但全局存储指令除外(例如,move_to, move_from, borrow_global)。请参阅[14]的Move指令集以获得核心Move指令及其语义的完整列表。在Sui中,持久存储是通过Sui的全局对象池来支持的,而不是核心Move中基于账户的全局存储。 有四个特定于sui的对象操作。这些操作都会改变对象的所有权元数据(参见3.3节),并将其返回给全局对象池。 最简单的是,一个Sui对象可以被转移到一个Sui最终用户的地址。对象还可以被转移到另一个父对象—此操作要求调用方提供对中父对象的可变引用添加到子对象。对象可以被可变地共享,因此它可以被Sui系统中的任何人读/写。最后,一个对象可以不可更改地共享,这样它就可以被Sui系统中的任何人读取,但不能被任何人编写。 区分不同类型所有权的能力是Sui的一个独特特征。在我们知道的其他区块链平台中,每个合约和对象都是可变地共享的。正如我们将在第4节中解释的,Sui利用该信息进行并行事务执行(针对所有事务)和并行协议(针对涉及没有共享可变性的对象的事务)。 3.2 类型与能力 PrimType = {address, id, bool, u8, u64, . . .}
StructType = ModuleName × StructName× [StorableType]
StorableType = PrimType ⊎ StructType⊎
GenericType ⊎ VectorType
VectorType = StorableType
GenericType = N
MutabilityQual = {mut, immut}
ReferenceType = StorableType × MutabilityQual
Type = ReferenceType ⊎ StorableType
Ability = {key, store, copy, drop}
Move程序操作存储在Sui全局对象池中的数据和在Move程序运行时创建的瞬时数据。对象和瞬时数据在语言层面上都是表示值。然而,并不是所有的值都是相同的 -- 他们可能具有不同的属性和不同的结构。 Move中使用的类型定义在上表中展示。Move支持其他编程语言支持的许多相同的基本类型,比如布尔类型或者其他各种大小的无符号整数类型。此外,Move有一个表示系统中最终用户(end-user)的地址类型,也用来表示交易的发送者和(Sui)对象的所有者。最后Sui定义了一个表示Sui对象标识的id类型 -- 详细信息请参见3.3节。 结构类型描述了一个实例(比如一个值)在给定的模块中声明的结构体(参见3.1节了解结构体声明的信息)。表示泛型结构声明的结构类型(比如泛型结构类型)包含一个可存储类型列表 -- 这个列表与结构声明中的泛型参数列表对应。可存储类型可以是具体类型(一个基础类型或者结构),也可以是泛型。我们称此类类型为可存储的,因为它们可以作为结构体的字段或持久化存储在链上的对象中,而引用类型则不能。 例如, Wrapper<u64> 是一个泛型结构类型,参数化了一个具体的(原始的)可存储类型u64 -- 这种类型可以用来创建一个结构实例(比如值)。另一方面,相同的泛型结构类型可以通过泛型类型(比如 struct Parent<T> { w: Wrapper<T> } )进行参数化外部结构或函数声明的泛型参数 - 这种类型可用于声明结构字段、函数参数等。在结构上,泛型类型是封闭结构或函数声明中泛型参数列表的整数索引。 Move中的vector类型描述为同一种类型值的一个可变长度集合。Move的vector只能包含可存储类型,而且它本身也是一个可存储类型。 Move程序可以直接操作值或者通过引用间接访问他们。引用类型包括引用的可存储类型和用于确定(和强制)给定类型的值是可读可写(mut)还是只读(imut)的可变性限定符。因此,Move值类型的一般形式可以是可存储类型或者引用类型。 最后,Move中的能力控制给定类型的值允许哪些操作,例如给定类型的值是否可以复制。能力约束结构声明和泛型类型参数。Move字节码验证器负责确保像拷贝这样的敏感操作只能在具有相应能力的类型上执行。 3.3 对象和所有权 TxDigest = 𝐶𝑜𝑚(Tx)
ObjID = 𝐶𝑜𝑚(TxDigest × N)
SingleOwner = Addr ⊎ ObjID
Shared = {shared_mut, shared_immut}
Ownership = SingleOwner ⊎ Shared
StructObj = StructType × Struct
ObjContents = StructObj ⊎ Package
Obj = ObjContents × ObjID × Ownership × Version
每个Sui对象都有一个全局唯一的标识符(ObjID)。作为对象的持久标识符,它在所有者之间流动并在其他对象中进出。这个ID是由创建它的事务分配给对象的。对象ID是通过将一个抗碰撞哈嘻函数应用到当前事务的内容和一个记录事务已经创建了多少个对象的计数器来创建的。由于事务的输入对象受到限制,事务(及其摘要)保证是唯一的,我们将在后面解释这一点。 除了ID之外,每个对象都携带关于其所有权的元数据。对象要么由一个地址或者另一个对象唯一拥有,要么共享读写权限,要么共享只读权限。对象的所有权决定事务是否以及如何将其用作输入。一般来说,唯一拥有的对象只能用于由其所有者发起的事务中,或将其父对象作为输入,而共享对象可以用于任何事务,但必须具有指定的可变性权限。详细解释请看4.4节。 有两种类型的对象:包代码对象和结构数据对象。包对象包含一个模块列表。一个结构对象包含一个Move值和该值的Move类型。 对象的内容可能会改变,但是它的ID、对象类型(package vs struct)和Move结构类型是不可变的。这确保了对象是强类型的,并且具有持久的标识。 最后,对象包含一个版本。新创建的对象的版本为0,每次事务接受对象作为输入时,对象的版本就会递增。 3.4 地址和验证者 Authenticator = Ed25519PubKey ⊎ ECDSAPubKey ⊎ . . .
Addr = 𝐶𝑜𝑚(Authenticator)
地址是Sui最终用户的持久标识(尽管注意单个用户可以有任意数量的地址)。若要将对象传输给另一个用户,发送方必须知道接收方的地址。 正如我们稍后将讨论的,Sui事务必须包含用户发送的地址(比如初始化)事务和摘要与地址匹配的验证器。地址和身份验证器之间的分离使得加密的灵活性得以实现。 验证者可以是来自任何签名方案的公钥,即使这些方案使用不同的密钥长度(例如,支持后量子签名(postquantum signatures))。 此外,验证者不必是单一的公钥——它也可以是(例如)K-of-N多重sig密钥。 3.5 交易 ObjRef = ObjID × Version × 𝐶𝑜𝑚(Obj)
CallTarget = ObjRef × ModuleName × FunName
CallArg = ObjRef ⊎ ObjID ⊎ PrimType
Package = [Module]
Publish = Package × [ObjRef]
Call = CallTarget × [StorableType] × [CallArg]
GasInfo = ObjRef × MaxGas × BaseFee × Tip
Tx = (Call ⊎ Publish) × GasInfo × Addr × Authenticator
Sui有两种不同的事务类型:发布一个新的Move包,以及调用一个之前发布的Move包。 发布事务包含一个包——一组将作为单个对象一起发布的模块,以及这个包中所有模块的依赖关系(编码为必须引用已经发布的包对象的对象引用列表)。 要执行发布事务,Sui运行时将在每个包上运行Move字节码验证器,将包与它的依赖项链接起来,并运行每个模块的模块初始化器。模块初始化器对于引导由包实现的应用程序的初始状态非常有用。 调用事务最重要的参数是对象输入。对象参数可以通过对象引用(对于单一所有者和共享的不可变对象)或对象ID(对于共享的可变对象)指定。 对象引用由对象组成ID、对象版本和对象值的哈希值。Sui运行时将对象ID和对象引用解析为存储在全局对象池中的对象值。对于对象引用,运行时将根据池中对象的版本检查引用的版本,并检查引用的散列是否与池对象匹配。这确保了对象的运行时视图与事务发送方的对象视图相匹配。 此外,调用事务接受类型参数和纯值参数。类型参数实例化要调用的入口点函数的泛型类型参数(例如,如果入口点函数
Sui是一个分布式、开放的智能合约平台,侧重于低延时的去管理资产。它使用Move编程语言来将资产定义为可能属于某个地址的对象。Move程序定义了对这些类型化了的对象的操作,包括自定义初始化规则、资产如何传递给新的拥有者、以及改变资产的操作。Sui是由一组无权限的验证者(authorities)维护,这些验证者的角色类似于其他区块链中的验证器或是矿工。它在授权机构之间使用拜占庭一致的广播协议,以确保对资产进行操作的安全性。与拜占庭协议相比,确保了更低的延迟和更好的可伸缩性。它仅依赖于拜占庭协议来保证共享对象的安全,以及在关键延迟路径之外执行的治理操作和检查点。在某些情况下,智能合约的执行也会自然地并行化。Sui支持轻客户端来验证读取,也支持完整的客户端来审核所有状态转换的完整性。这些设施允许与其他类型的区块链建设的信任最小化的桥梁。
链上原生资产SUI代币用来支付所有链上操作的gas费用。SUI代币也被它的所有者用来在不同周期(epoch)内委托质押给不同的验证者来管理Sui。这些验证者会定期的根据这些委托质押给他们的SUI来重置配置。被使用的gas会根据分配给这些验证者,还有根据质押SUI的比例分配给质押者们。
本白皮书氛围两部分,第二部分描述了基于Move语言的Sui编程模型,第四部分描述了确保Sui的安全性(safety)、可终止性(liveness)和性能的无许可去中心化分布式系统的操作。
Sui的智能合约是用Move[4]语言编写的。Move安全且富有表现力,其类型系统和数据模型天然支持并行协议/执行操作来使得Sui具有很强的可伸缩性。Move是一种用来构建智能合约的开源编程语言,最开始是在Facebook为了Diem区块链开发的。Move语言和平台无关,除了被Sui采用之外,它在其他平台(即OL,StarCoin)也越来越受欢迎。
在本节中,我们主要会讨论关于Move语言的一些重要特性,并且解释如何使用它在Sui上创建和管理资产。关于Move的更全面解释可以在《Move Programming Language》里找到,更对针对Sui的Move内容可以在《Sui开发者门户》里找到,关于Sui上下文中Move的更正式的描述可以在第3节中找到。
Sui的全局状态包括一个可编程的对象池,由Move包来创建和管理,这些可编程对象是包含Move函数和类型的Move模块的集合(详见2.1.1节)。Move包本身也是对象。因此,Sui中描述的对象可以分为以下两类:
对象可以对资产进行编码(比如同质化代币/非同质化代币),授予调用某些函数或创建其他对象的权限的功能,管理其他资产的“智能合约”等。这些全都由程序员们来决定。
声明自定义的Sui对象类型的Move代码如下所示:
struct Obj has key {
id:VersionedID,
f: u64
g: OtherObj
}
所有表示Sui对象的结构(但不是所有的Move结构值)必须具有id字段和值能力(key ability),表明值可以存储在Sui的全局对象池中。
Move程序被组织为一组模块,每个模块由结构声明和函数声明的列表组成。一个模块可以从其他模块导入结构类型,并调用由其他模块声明的函数。
在一个Move模块中声明的值可以流动(flow)到另一个模块中,比如上面举例的模块Obj可以定义在与定义Obj的模块不同的模块中。这与大多数智能合约语言不同,后者只允许非结构化的字节跨合约边界流动。但是,Move能够支持这一点,因为它提供了封装特性来帮助程序员编写健壮性强[14]的代码。具体来说,Move的类型系统确保了像上面的Obj这样的类型只能由声明该类型的模块中的函数创建、销毁、复制、读取和写入。这允许模块对其声明的类型强制强不变量,即使它们在流经智能合约信任边界时也会继续保持。
全局对象池可以通过创建、销毁、读写对象的事务进行更新。事务必须接受希望操作的每个现有对象作为输入。
此外,事务必须包括包对象的版本ID、包内模块、函数的名称以及函数的参数(包括输入对象)。
例如调用下面这个函数:
public fun entrypoint {
o1: Obj, o2: &mut Obj, o3: &Obj, x: u64, ctx: &mut TxContext
} { ... }
事务必须为三个类型为Obj的不同对象提供ID,并为绑定到x的整数提供ID。 TxContext是由运行时填充的特殊参数,其中包含创建新对象所需的发送方地址和信息。
入口点(更一般地说,是任何Move函数)的输入可以通过在类型中编码的不同的可变性权限来传递。可以读取、写入、传输或销毁Obj输入。一个&mut Obj输入只能读或写,而一个& Obj 只能读。事务发送方必须被授权使用具有指定的可变权限的每个输入对象 -- 详见4.4节。
程序员可以通过使用传入入口点的TxContext来创建对象,为对象生成一个新的ID:
public fun create_then_transfer (
f: u64 , g: OtherObj , o1: Obj , ctx: &mut TxContext
) {
let o2 = Obj { id: TxContext::fresh_id(ctx), f, g };
Transfer::transfer(o1, TxContext:sender());
Transfer::transfer(o2, TxContext:sender());
}
这段代码接受OtherObj和Obj类型的两个对象作为输入,使用第一个对象和生成的ID创建一个新的Obj,然后将两个obj对象传输给事务发送方。一旦传输了对象,它就会流到全局对象池中,并且在事务的其余部分中不能通过代码访问。Transfer模块是Sui标准库的一部分,它包含了将对象传输到用户地址和其他对象的函数。
我们注意到,如果程序员代码忽略了包含一个转移调用,那么Move的类型系统将会拒绝该代码。Move强制资源安全[5]保护,以确保在没有权限的情况下不能创建、复制或意外销毁对象。资源安全的另一个例子是试图两次传输相同的对象,这也会被Move类型系统拒绝。
在本节中,我们将通过详细的语义定义来扩展第2节中对Sui编程模型的非正式描述。上一节展示了Move源代码的示例,示例里定义了Move字节码的结构。开发人员在本地编写、测试并正式验证Move源码,然后将其编译为字节码,再将其发布到区块链。任何发布在链上的Move字节码必须通过字节码验证器,以确保它满足关键属性,如类型、内存和资源安全。
正如在第2节中提到的,Move是一种平台无关的语言,它可以适应不同系统的特定需求,而不需要创建核心语言。在下面的描述中,我们从核心的Move语言(用黑色表示)中定义了这两个概念以及扩展核心Move语言的Sui-specific特性 (Instr 后的值 )。
Module = ModuleName×
(StructName ⇀ StructDecl)×
(FunName ⇀ FunDecl) × FunDecl
GenericParam = [Ability]
StructDecl = (FieldName ⇀ StorableType)×
[Ability] × [GenericParam]
FunDecl = [Type] [Type] × [Instr] × [GenericParam]
Instr = TransferToAddr | TransferToObj | ShareMut | ShareImmut | . . .
Move代码被组织到模块中,其结构定义如上所示。一个模块由一组命名结构体声明和一组命名函数声明组成(这些声明的例子在第2.1节中提供)。 模块还包含一个特殊的函数声明,作为模块初始化器。这个函数在模块发布到链上时只调用一次。
结构声明是命名字段的集合,其中字段名映射到可存储类型。它的声明还包括一个可选的能力列表(参见第2节的可存储类型和能力的描述)。struct声明还可以包括具有能力约束的泛型参数列表,在这种情况下,我们称其为泛型struct声明,例如struct Wrapper<T: copy>{T: T}。
泛型参数表示在声明结构字段时要使用的类型——在声明结构时它是未知的,而在实例化结构时提供了具体类型(例如:创建结构值时)。
函数声明包括形参类型列表、返回类型列表和组成函数体的指令列表。函数声明还可以包括具有能力约束的泛型参数列表,在这种情况下,我们称其为泛型函数声明,例如fun unwrap<T: copy>(p: Wrapper){}。与struct声明类似,泛型形参表示在函数声明时未知的类型,但在声明函数形参、返回值和函数体时使用(在调用函数时提供具体类型)。 可以出现在函数体中的指令包括所有普通的Move指令,但全局存储指令除外(例如,move_to, move_from, borrow_global)。请参阅[14]的Move指令集以获得核心Move指令及其语义的完整列表。在Sui中,持久存储是通过Sui的全局对象池来支持的,而不是核心Move中基于账户的全局存储。 有四个特定于sui的对象操作。这些操作都会改变对象的所有权元数据(参见3.3节),并将其返回给全局对象池。 最简单的是,一个Sui对象可以被转移到一个Sui最终用户的地址。对象还可以被转移到另一个父对象—此操作要求调用方提供对中父对象的可变引用添加到子对象。对象可以被可变地共享,因此它可以被Sui系统中的任何人读/写。最后,一个对象可以不可更改地共享,这样它就可以被Sui系统中的任何人读取,但不能被任何人编写。 区分不同类型所有权的能力是Sui的一个独特特征。在我们知道的其他区块链平台中,每个合约和对象都是可变地共享的。正如我们将在第4节中解释的,Sui利用该信息进行并行事务执行(针对所有事务)和并行协议(针对涉及没有共享可变性的对象的事务)。 3.2 类型与能力 PrimType = {address, id, bool, u8, u64, . . .}
StructType = ModuleName × StructName× [StorableType]
StorableType = PrimType ⊎ StructType⊎
GenericType ⊎ VectorType
VectorType = StorableType
GenericType = N
MutabilityQual = {mut, immut}
ReferenceType = StorableType × MutabilityQual
Type = ReferenceType ⊎ StorableType
Ability = {key, store, copy, drop}
Move程序操作存储在Sui全局对象池中的数据和在Move程序运行时创建的瞬时数据。对象和瞬时数据在语言层面上都是表示值。然而,并不是所有的值都是相同的 -- 他们可能具有不同的属性和不同的结构。 Move中使用的类型定义在上表中展示。Move支持其他编程语言支持的许多相同的基本类型,比如布尔类型或者其他各种大小的无符号整数类型。此外,Move有一个表示系统中最终用户(end-user)的地址类型,也用来表示交易的发送者和(Sui)对象的所有者。最后Sui定义了一个表示Sui对象标识的id类型 -- 详细信息请参见3.3节。 结构类型描述了一个实例(比如一个值)在给定的模块中声明的结构体(参见3.1节了解结构体声明的信息)。表示泛型结构声明的结构类型(比如泛型结构类型)包含一个可存储类型列表 -- 这个列表与结构声明中的泛型参数列表对应。可存储类型可以是具体类型(一个基础类型或者结构),也可以是泛型。我们称此类类型为可存储的,因为它们可以作为结构体的字段或持久化存储在链上的对象中,而引用类型则不能。 例如, Wrapper<u64> 是一个泛型结构类型,参数化了一个具体的(原始的)可存储类型u64 -- 这种类型可以用来创建一个结构实例(比如值)。另一方面,相同的泛型结构类型可以通过泛型类型(比如 struct Parent<T> { w: Wrapper<T> } )进行参数化外部结构或函数声明的泛型参数 - 这种类型可用于声明结构字段、函数参数等。在结构上,泛型类型是封闭结构或函数声明中泛型参数列表的整数索引。 Move中的vector类型描述为同一种类型值的一个可变长度集合。Move的vector只能包含可存储类型,而且它本身也是一个可存储类型。 Move程序可以直接操作值或者通过引用间接访问他们。引用类型包括引用的可存储类型和用于确定(和强制)给定类型的值是可读可写(mut)还是只读(imut)的可变性限定符。因此,Move值类型的一般形式可以是可存储类型或者引用类型。 最后,Move中的能力控制给定类型的值允许哪些操作,例如给定类型的值是否可以复制。能力约束结构声明和泛型类型参数。Move字节码验证器负责确保像拷贝这样的敏感操作只能在具有相应能力的类型上执行。 3.3 对象和所有权 TxDigest = 𝐶𝑜𝑚(Tx)
ObjID = 𝐶𝑜𝑚(TxDigest × N)
SingleOwner = Addr ⊎ ObjID
Shared = {shared_mut, shared_immut}
Ownership = SingleOwner ⊎ Shared
StructObj = StructType × Struct
ObjContents = StructObj ⊎ Package
Obj = ObjContents × ObjID × Ownership × Version
每个Sui对象都有一个全局唯一的标识符(ObjID)。作为对象的持久标识符,它在所有者之间流动并在其他对象中进出。这个ID是由创建它的事务分配给对象的。对象ID是通过将一个抗碰撞哈嘻函数应用到当前事务的内容和一个记录事务已经创建了多少个对象的计数器来创建的。由于事务的输入对象受到限制,事务(及其摘要)保证是唯一的,我们将在后面解释这一点。 除了ID之外,每个对象都携带关于其所有权的元数据。对象要么由一个地址或者另一个对象唯一拥有,要么共享读写权限,要么共享只读权限。对象的所有权决定事务是否以及如何将其用作输入。一般来说,唯一拥有的对象只能用于由其所有者发起的事务中,或将其父对象作为输入,而共享对象可以用于任何事务,但必须具有指定的可变性权限。详细解释请看4.4节。 有两种类型的对象:包代码对象和结构数据对象。包对象包含一个模块列表。一个结构对象包含一个Move值和该值的Move类型。 对象的内容可能会改变,但是它的ID、对象类型(package vs struct)和Move结构类型是不可变的。这确保了对象是强类型的,并且具有持久的标识。 最后,对象包含一个版本。新创建的对象的版本为0,每次事务接受对象作为输入时,对象的版本就会递增。 3.4 地址和验证者 Authenticator = Ed25519PubKey ⊎ ECDSAPubKey ⊎ . . .
Addr = 𝐶𝑜𝑚(Authenticator)
地址是Sui最终用户的持久标识(尽管注意单个用户可以有任意数量的地址)。若要将对象传输给另一个用户,发送方必须知道接收方的地址。 正如我们稍后将讨论的,Sui事务必须包含用户发送的地址(比如初始化)事务和摘要与地址匹配的验证器。地址和身份验证器之间的分离使得加密的灵活性得以实现。 验证者可以是来自任何签名方案的公钥,即使这些方案使用不同的密钥长度(例如,支持后量子签名(postquantum signatures))。 此外,验证者不必是单一的公钥——它也可以是(例如)K-of-N多重sig密钥。 3.5 交易 ObjRef = ObjID × Version × 𝐶𝑜𝑚(Obj)
CallTarget = ObjRef × ModuleName × FunName
CallArg = ObjRef ⊎ ObjID ⊎ PrimType
Package = [Module]
Publish = Package × [ObjRef]
Call = CallTarget × [StorableType] × [CallArg]
GasInfo = ObjRef × MaxGas × BaseFee × Tip
Tx = (Call ⊎ Publish) × GasInfo × Addr × Authenticator
Sui有两种不同的事务类型:发布一个新的Move包,以及调用一个之前发布的Move包。 发布事务包含一个包——一组将作为单个对象一起发布的模块,以及这个包中所有模块的依赖关系(编码为必须引用已经发布的包对象的对象引用列表)。 要执行发布事务,Sui运行时将在每个包上运行Move字节码验证器,将包与它的依赖项链接起来,并运行每个模块的模块初始化器。模块初始化器对于引导由包实现的应用程序的初始状态非常有用。 调用事务最重要的参数是对象输入。对象参数可以通过对象引用(对于单一所有者和共享的不可变对象)或对象ID(对于共享的可变对象)指定。 对象引用由对象组成ID、对象版本和对象值的哈希值。Sui运行时将对象ID和对象引用解析为存储在全局对象池中的对象值。对于对象引用,运行时将根据池中对象的版本检查引用的版本,并检查引用的散列是否与池对象匹配。这确保了对象的运行时视图与事务发送方的对象视图相匹配。 此外,调用事务接受类型参数和纯值参数。类型参数实例化要调用的入口点函数的泛型类型参数(例如,如果入口点函数
send_coin<T>(c: Coin<T>,…)
,泛型类型参数T可以用类型参数SUI实例化,以发送SUI原生token)。纯值可以包括基元类型和基元类型的向量,但不包括结构类型。 调用要调用的函数是通过对象引用(必须指向一个包对象)、包中的模块名和包中的函数名指定的。要执行调用事务,Sui运行时将解析函数,将类型、对象和值参数绑定到函数参数,并使用Move VM执行函数。 调用和发布交易都受gas计量和gas费用的影响。计量限制用最大gas预算表示。运行时将执行事务,直到达到预算为止,如果预算耗尽,则将中止而不产生任何影响(除了扣除费用并报告中止代码)。 费用从指定为对象参考的气体对象中扣除。该对象必须是Sui的本地令牌(即类型必须为Coin)。Sui使用eip1559风格的费用:该协议定义了一个基本费用(以每个Sui代币的天然气单位计算),在纪元边界进行算法调整,交易发送者也可以包括一个可选的小费(以Sui代币计算)。在正常的系统负载下,即使没有提示,事务也会被及时处理。但是,如果系统拥塞,则小费较多的事务将被优先处理。气体对象的总费用是(GasUsed * BaseFee) + Tip。 3.6 交易的影响 Event = StructType × Struct
Create = Obj
Update = Obj
Wrap = ObjID × Version
Delete = ObjID × Version
ObjEffect = Create ⊎ Update ⊎ Wrap ⊎ Delete
AbortCode = N × ModuleName
SuccessEffects = [ObjEffect] × [Event]
AbortEffects = AbortCode
TxEffects = SuccessEffects ⊎ AbortEffects
事务执行产生的事务效果在事务成功执行(上面的SuccessEffects)和不成功执行(上面的AbortEffects)时是不同的。 事务成功执行后,事务效果包括对Sui的全局对象池所做的更改(包括对现有对象和新创建对象的更新)和事务执行期间生成的事件的信息。 事务执行成功的另一个影响可能是对象从全局对象池里删除(比如deletion)并且包装一个对象(比如embedding)到另一个对象里,这与移除有类似的效果——被包装的对象从全局池中消失,只作为包装它的对象的一部分存在。由于已删除和封装的对象在全局池中不再可访问,因此这些效果由对象的ID和版本表示。 事件编码成功执行事务的连锁反应,而不仅仅是更新全局对象池。 在结构上,一个事件由一个Move结构体及其类型组成。事件旨在由区块链之外的参与者使用,但Move程序不能读取事件。 交易有一个原子性的语义,如果执行事务中止在某种情况下(例如,由于一个意想不到的失败),即使发生了一些改变对象(或一些事件生成的)这一点之前,这些影响坚持一个失败的事务。相反,中止的事务效果包括一个数字中止代码和发生事务中止的模块的名称。中止交易仍需收取gas费。 4.Sui系统 在本节中,我们从系统的角度来描述Sui,包括确保安全的机制和在出现了拜占庭式容错的情况下各验证者的有效性。我们还解释了客户端的操作,包括轻量级客户端,它们需要在不验证完整状态的情况下对系统状态进行一些保证。
简短的背景介绍。
在系统层面上,Sui发展自FastPay[3]的低延迟结算系统,扩展到通过用户定义的智能合约操作任意对象,并由具有无权限的质押委托股权证明[2]。对象所有者的基本资产管理基于拜占庭一致性广播[6]的变种,与传统的拜占庭共识[8,11,12]实现相比,它具有更低的延迟,也更容易跨多台机器伸缩。当需要完全的协议时,我们使用高吞吐量的基于DAG的共识,例如[9]用来管理锁,当在不同的共享对象上并行执行操作的时候。
协议大纲
图1 提交事务的交互概述 上图展示了客户端与Sui验证者之间提交事务的高级交互。我们在此简单的介绍: 一个拥有私有签名密钥的用户创建并签署了一个用户事务,以改变他们在Sui内部拥有或者共享的对象。随后,不再需要用户的签名密钥,流程的剩余部分可能由用户的客户端执行,或者由代表用户的网管执行(在图中表示为无密钥操作)。 用户的交易被发送至Sui验证者,验证者们检查其有效性,并在成功签署后返回发送给客户端的已签名事务。客户端收集到足够多验证者的响应(达到法定人数)之后形成一个事务证书。 事务证书被发送给所有的验证者,如果交易涉及到共享对象,它也被发送到一个由Sui验证者们共同操作的拜占庭协议。验证者们回检查这个证书,如果涉及到共享对象,会将对应的共享对象和其他共享对象事务进行排序,然后执行交易并将其效果汇总成一个签名的效果响应。 一旦足够数量的验证者执行了证书,就代表着事务最终生效了(即图中的finality)。客户端可以收集验证者响应的仲裁,并创建一个效果证书,并将其用作事务效果的最终证明。 本节详细描述这些操作,以及跨权限重新配置和管理状态的操作。 4.1 系统模型 Sui的操作在一系列周期中以
𝑒 ∈ {0, . . .}
表示。每个周期都由一个委员会
𝐶𝑒 = (𝑉𝑒, 𝑆𝑒 (·))
来进行管理,
𝑉𝑒
是一组具有已知公共验证key和网络终端的验证者集合。函数
𝑆𝑒 (𝑣)
映射了每个验证者
𝑣 ∈ 𝑉𝑒
对应被委托质押的数量。我们假设
𝐶𝑒
对于每个周期,都是由法定人数(见下文)在第e-1周期签署的(第4.7节讨论委员会的组成和管理)。在一个周期内,有些验证者是正确的(他们忠实地遵循协议,并且是实时的),而有一些验证者则是拜占庭式的(他们任意的偏离协议)。安全的假设是,诚实验证者节点的集合
𝐻𝑒 ⊆ 𝑉𝑒
是否在指定周期内分配到了法定的份额,比如Σ h ∈ H e S e ( h ) > 2 / 3 Σ v ∈ V e S e ( v ) \Sigma _h\in H_e S_e (_h) > 2/3 \Sigma _v\in V_e S_e(_v) Σ h ∈ H e S e ( h ) > 2/3 Σ v ∈ V e S e ( v ) (这里指拥有超过三分之二的质押验证者作为法定人数) 至少存在一个活跃的、存在着的当事者作为每个证书(详见4.3节)在诚实的验证者中间作为中继器(relay)。这确保了可终止性,并为拜占庭广播提供了一个最终交付属性(参考[6]中的可靠广播的整体性)。每个验证者都单独或通过集体传播协议运行这样的中继器。外部实体,包括Sui的轻客户端,副本和服务都可能扮演这个角色。有限授权的核心和内部或者外部的活跃中继器区别,确保了可靠计算基础[15]的清晰划分和最小化,而Sui的安全性和可终止性依赖于此。 4.2 验证者 & 副本数据结构 Sui的验证者依靠大量的数据结构来表示状态。我们根据它们支持的操作定义这些结构。它们都有一个确定的字节表示方式。 对象(Obj)在Sui中存储智能合约和数据。它们是第2节中介绍的Sui系统级别的Move对象编码。它们支持以下操作集: ref(Obj)
返回对象的引用(ObjRef),即一个三元组(ObjID, Version, ObjDigest)。ObjID几乎是对于所有新创建的对象来说是唯一的,Version是一个递增的正整数,表示对象发生变化时的版本。
owner(Obj)
返回该对象所有者的认证者Auth。在最简单的情况下,Auth是一个地址,表示可能使用该对象的公钥。也可以使用更复杂的验证器(参见4.4节)。
read-only(Obj)
如果对象是只读的,返回true。只读对象永远不能被修改、包装或删除。它们也可能被任何人使用,而不仅仅是它们的拥有者。
parent(Obj)
返回最近一次修改或创建对象的事务摘要(TxDigest)。
contents(Obj)
返回对象类型
type
和data
data
,可以用来检查事务的有效性,并携带对象的特定应用程序信息。 对象引用(ObjRef)用于索引对象。它还用于验证对象,因为ObjDigest是对对象全部内容的承诺(commitment)。 事务(Tx)是表示一个或多个对象的状态转换的结构。它们支持以下操作集:
digest(Tx)
返回TxDigest,它是对事务的绑定密码承诺。
epoch(Tx)
返回事务执行期间的EpochID。
input (Tx)
返回一个事务需要执行的对象[ObjRef]序列。
payment(Tx)
返回一个ObjRef的引用,用于支付gas,以及gas的最大限额,以及gas单位和gas支付对象的价值单位之间的转化率。
valid(Tx, [Obj])
如果事务有效则返回true。有效性在第4.4节中讨论,它涉及被授权对输入对象起作用的交易,以及有足够的gas可用来支付执行的成本。
exec(Tx, [Obj])
执行事务并返回一个表示其效果的结构效果。一个有效的事务执行是绝对正确的,它的输出是确定的。 事务由其TxDigest建立索引,该TxDigest也可用于验证事务的全部内容。所有有效的事务(除了特殊的硬编码生成事务)至少有一个拥有的输入,即用于支付gas的对象。 事务效果(effects)结构总结了事务执行的结果。支持以下操作:
digest(Effects)
是EffDigest对Effects结构的承诺,可以用来索引或验证它。
transaction(Effects)
返回产生效果的执行事务的TxDigest。
dependencies(Effects)
返回一个依赖序列[TxDigest],应该在事务执行之前执行。
contents(Effects)
返回执行的摘要。Status报告智能合约执行的结果。列表Created、Mutated、Wrapped、Unwrapped和Deleted列出了经历了各自操作的对象引用。而Events则列出由执行发射(emit)的事件。 事务上的事务证书TxCert包含事务本身以及来自仲裁机构的标识符和签名。请注意,证书可能不是唯一的,因为相同的逻辑证书可能由组成仲裁的不同的权威集表示。此外,证书可能不会严格地由2/3的法定人数签名,但如果有更多的授权机构响应,可能会更多。但是,同一事务上的两个不同的有效证书应该被视为在语义上表示相同的证书。部分证书(TxSign)包含相同的信息,但来自一组授权机构的签名,这些授权机构代表的风险低于所需的法定人数,通常是单个授权机构。签名者的标识符包含在证书中(即负责任的签名[?])以识别验证者准备处理证书,或可用于下载处理证书所需的过去信息(参见4.8节)。 类似地,效应结构上的效应证书
EffCert
包含效应结构本身,以及来自验证者的签名,这些验证者代表了交易有效时期的法定人数。关于非惟一性和身份的注意事项同样适用于事务证书。一个部分效果证书,通常包含一个验证签名和效果结构,称为
EffSign
。
持久存储
每个验证者和副本维护一组持久存储。存储实现了持久的映射语义,可以表示为一组键-值对(表示为𝑚𝑎𝑝[𝑘𝑒𝑦]→𝑣𝑎𝑙𝑢𝑒),这样只有一个键对具有给定的键。在插入pair之前,contains(𝑘𝑒𝑦)调用返回false, get(𝑘𝑒𝑦)调用返回错误。插入一对后,contains(𝑘𝑒𝑦)调用返回true, get(𝑘𝑒𝑦)返回值。中心维护以下持久存储: order lock map
lock𝑣 [ObjRef]→TxSignOption
记录一个拥有对象版本ObjRef的授权下第一个被Tx看到并签名的有效事务,或者如果对象版本存在但没有被用作输入的有效事务被看到,则为None。它还可以记录与该对象一起出现的第一个证书作为输入。这个表和它的更新规则代表了整个Sui权限范围内对象上的分布式锁的状态,并确保了事务并发处理下的安全性。 certificate map
Ct𝑣 [TxDigest]→(TxCert, EffSign)
记录所有完整的证书TxCert(也包括Tx),在其有效期内由验证者处理,以及其签名的效果EffSign。它们通过事务摘要TxDigest进行索引。 The object map
Obj𝑣 [objj]→Obj
记录了所有Obj创建的对象,这些对象包含在Ct的证书中𝑣 由ObjRef索引。这个存储可以通过重新执行Ct中的所有证书来完全派生𝑣 .维护一个二级索引,将ObjID映射到具有该ID的最新对象。这是处理新事务所需的惟一信息,而维护旧版本只是为了方便读取和审计。 -The synchronization map
Sync𝑣 [ObjRef]→TxDigest
索引Ct内的所有证书𝑣 通过他们创建,变异或删除的对象作为元组ObjRef。该结构可以通过处理Ct中的所有证书完全重新创建𝑣 ,用于帮助客户端同步影响它们所关心的对象的事务。 验证者维护所有四个结构,并提供对其证书映射的本地检查点的访问,以允许其他验证者和副本下载其完整的已处理证书集。副本不处理事务,只处理证书,并像权威机构那样重新执行它们以更新其他表。它还维护了一个订单锁映射,以审计非模糊性。 一个中心可以被设计成一个完整的副本,维护所有四个存储区(和检查点),以促进读取和同步,并结合一个最小的中心,只维护用于处理新事务和证书的对象的最新版本的对象锁和对象。这最大限度地减少了安全所依赖的可信计算基础。 只有顺序锁映射需要强键自一致性,也就是说,对某个键的读取应该始终返回某个已存在键的值是否存在或是否存在None,并且这种检查应该是原子性的,并将锁设置为非None值。与跨键的强一致性相比,这是一个较弱的属性,并允许对存储进行有效的分片以进行伸缩。其他存储可能最终会在不影响安全的情况下保持一致。 4.3 验证者基础操作
处理事务:
在接收到Tx交易后,验证者执行一系列检查: 1.确保epoch(Tx)是当前的epoch 2.确保所有对象引用输入(Tx)和支付中的gas对象引用(Tx)都存在于Obj中𝑣 并加载到[Obj]。对于拥有的对象,应该提供准确的引用;对于只读或共享对象,对象ID应该存在。 3.确保gas对象中有足够的gas来支付执行交易的成本 4.检查valid(Tx, [Obj])是true。这个步骤确保事务中的身份验证信息允许访问拥有的对象。它检查锁𝑣 [ObjRef]为所有拥有的输入(Tx)对象存在,它要么为None,要么设置为相同的Tx,并自动设置为TxSign。(我们称之为“锁检查”)。 如果任何检查失败,处理结束,并返回一个错误。但是,对Lock的部分更新是安全的𝑣 持久(尽管我们当前的实现不进行部分更新,而是对所有锁进行原子更新)。 如果所有的检查都成功,那么验证者就会返回一个对事务的签名。部分证书TxSign。成功后,处理订单是幂等的,并返回部分证书(TxSign),或完整证书(TxCert)(如果有的话)。 任何一个验证者都可以整理一个epoch内的交易和签名(TxSign)𝑒,以形成一个交易证书TxCert。
过程证明:
在收到证书后,验证者检查事务的所有有效性条件,除了与锁相关的(所谓的“锁检查”)。相反,它执行以下检查:对于输入(Tx)中的每个拥有的输入对象,它检查锁是否存在,并且它要么为None,要么设置为任何TxSign,要么设置为与当前证书相同的事务的证书。如果修改后的锁检查失败,则中心检测到不可恢复的拜占庭故障,停止正常操作,并启动灾难恢复进程。对于共享对象(见4.4节),验证者检查锁是否已经通过被排序的证书在一个共识中设置,以确定要使用的共享对象版本。如果是这样,交易可以执行;否则就需要等待这样的排序。 如果检查成功,验证者将证书添加到它的证书映射中,以及它的执行所产生的效果,例如:Ct𝑣 [TxDigest]→(TxCert, EffSign);它更新锁映射以记录证书Lock𝑣 [ObjRef]→TxCert用于所有拥有的没有设置为证书的锁的输入对象。只要Input(Tx)中的所有对象都插入到Obj中𝑣 ,那么EffSign中的所有效果也通过将它们的ObjRef和内容添加到Obj来具体化𝑣 .最后,所有在EffSign中创建或修改的同步映射都被更新为映射到Tx。
结论:
处理事务和证书的逻辑导致了许多重要的属性:
因果关系和并行性
。事务和证书的处理条件都确保了因果执行:一个验证者只有在处理了所有创建该事务所依赖的对象的证书(包括所有的、共享的和只读的)之后,才会通过签署一项交易来“投票”。类似地,只有当中心所依赖的所有输入对象都存在于其本地对象映射中时,中心才会处理证书。这就强加了一个因果执行顺序,但也允许不相互依赖的事务在不同的核心或机器上并行执行。
一次签名,确保安全
。所有拥有的输入对象在Lock中锁定𝑣 [·]设置为使用它们通过检查的第一个事务Tx,然后设置为使用该对象作为输入的第一个证书。我们称此操作为将对象锁定到该事务,并且在一个时期内不存在解锁操作。因此,验证者在每个锁上只签署一个事务,这是一致广播[6]基本组成部分,因此也保证了Sui的安全性。
灾难恢复
。一个权威机构检测到同一个锁的两个相互矛盾的证书,它有无法恢复的拜占庭行为的证据——即quorum诚实权威假设不成立的证据。这两个相互矛盾的证书是一个欺诈证明[1],可以与所有权威机构和副本共享,以触发灾难恢复过程。权威机构还可能得到不可恢复的拜占庭行为的其他形式的证明,比如代表证书执行错误的效果上的>1/3签名(EffSign)。或者,一个证书的输入对象不能代表以前处理过的证书的正确输出。这些也可以打包为欺诈证据,并与所有当局和副本共享。请注意,这些不同于那些可以容忍的少数权威(按股份≤1/3)或对象所有者(任何数字)是拜占庭或模棱两可的证据,它们可以在没有任何服务中断的情况下被容忍。
终局性
。于Lock中索引的任何读请求,验证者都会返回一个证书(TxCert)和签名效果(EffSign)𝑣 , Ct𝑣 和Obj𝑣 、Sync𝑣。一笔交易如果超过法定人数的验证者报告Tx包括在他们的Ct𝑣存储里,那么这笔交易就是最终的交易。这意味着效果证书(EffCert)是终局性的可转移证明。然而,使用对象的证书也证明了所有的依赖关系其因果路径中的证书也是最终的。向任何一方提供证书,然后将其提交给绝大多数验证者进行处理,也确保了证书效果的终局性。注意,finality比fastpay[3]要晚,以确保重新配置时的安全性。然而,中心可以在看到证书时应用事务的效果,而不是等待提交。 4.4 所有者、授权和共享对象 事务有效性(见4.3节)确保一个事务被授权在一个事务中包含所有指定的输入对象。这种检查取决于对象的性质以及所有者字段。 只读对象不能被修改或删除,并且可以被所有用户并发地在事务中使用。例如,Move模块是只读的。这样的对象确实有一个可能被用作智能合约一部分的所有者,但这并不影响使用它们的授权。它们可以包含在任何交易中。 拥有的对象有一个所有者字段。所有者可以设置为表示公钥的地址。在这种情况下,如果事务是由该地址签名的,那么它就被授权使用该对象并对其进行修改。事务由单个地址签名,因此可以使用该地址拥有的一个或多个对象。但是,一个事务不能使用多个地址拥有的对象。一个对象(称为子对象)的所有者可以被设置为另一个对象(称为父对象)的ObjID。在这种情况下,只有当父对象包含在事务中时,才可以使用子对象,并且事务被授权使用该对象。契约可以使用这个功能来构造有效的集合和其他复杂的数据结构。 共享对象是可变的,但没有特定的所有者。它们可以被不同的方包括在交易中,不需要任何授权。相反,它们执行自己的授权逻辑。这样的对象,由于必须支持多个写入器,同时确保安全性和活动性,确实需要一个完整的协议协议才能安全地使用。因此,它们在执行之前需要额外的逻辑。授权机构处理章节4.3中规定的事务,用于管理拥有对象和只读对象的锁。然而,验证者并不依赖于一致的广播来管理共享对象的锁。相反,涉及共享对象的事务的创建者将事务上的证书插入到高吞吐量的共识系统中,例如[9]。所有权威机构都遵循这样的证书的一致顺序,并根据这个顺序分配每个交易使用的共享对象的版本。然后执行可以继续进行,并保证在所有权限之间保持一致。在effect证书中包含事务执行中使用的共享对象的版本。 上述规则确保,对于涉及只读对象和拥有对象的事务,只需要一致的广播和一个证书就可以执行;拜占庭协议只适用于涉及共享对象的事务。因此,智能合约作者可以设计他们的类型和操作,以优化单个用户对象上的传输和其他操作,以降低延迟,同时享受使用共享的灵活性对象来实现需要由多个用户访问的逻辑。 4.5 客户端
副本:
有时也称为完整的客户端,不验证新的事务,但维护系统有效状态的一致副本,以进行审计,以及构建事务或操作服务,包括用于轻客户端查询的读取基础设施。
轻客户端:
对象引用和事务都包含允许对导致其创建或执行的事务的完整因果链进行身份验证的信息。具体来说,对象引用(ObjRef)包含一个ObjDigest,它是对象完整状态的验证器,包括获取父对象(Obj)的工具,即创建对象的TxDigest。类似地,TxDigest对事务进行身份验证,包括通过输入(Tx)提取输入对象的对象引用的工具。因此,对象和证书的集合形成了一个自认证的二分图。此外,效果结构也被签名,并且可以整理成直接证明事务执行结果的效果证书。 这些设施可以用于支持轻客户端,这些客户端可以执行对Sui状态的高完整性读取,而无需维护一个完整的复制节点。具体地说,一个机构或完整节点可以提供一个简洁的证据束,包括一个交易Tx上的证书TxCert和对应于输入(Tx)的输入对象[Obj],以使轻客户端相信一个转换可以在Sui内发生。然后,轻客户端可以提交此证书,或检查是否已被法定人数或验证者的样本看到,以确保最终结果。或者,它可以使用执行产生的对象来设计一个事务,并观察它是否成功。 更直接地说,服务可以向客户端提供一个效果证书,以说服他们在Sui中存在一个过渡,并且这个过渡是最终的,而系统中没有进一步的操作或交互。如果最终证书的检查点可用,在时代边界或其他地方,包括输入对象和证书的证据束,以及证书包含在检查点中的证明,也是最终的证明。 验证者可以使用定期检查的机制来创建最终交易的集体检查点,以及Sui的状态随时间的推移。轻客户端可以使用具有检查点上的仲裁权益的证书有效地验证对象的最近状态和发出的事件。一个检查点机制是必要的委员会重组之间的epoch。更频繁的检查点对于轻客户端很有用,验证者也可以使用它来压缩内部数据结构,以及更有效地与其他验证者同步状态。 4.6 桥 对轻客户端和通过拜占庭协议管理的共享对象的原生支持,允许Sui支持与其他区块链[13]的双向桥。这类桥梁的信任假设反映了Sui和其他区块链的信任假设,如果其他的区块链也支持轻客户端,则不需要依赖与受信任的预言机或者是硬件[7]。 桥用于导入发布在另一个区块链上的资产,并将其表示为一个封装在Sui系统中的资产。最终,可以解锁被包装的资产,并将其传输回本机区块链上的用户。桥还允许在Sui上发行的资产被锁定,并作为包装资产在其他区块链上使用。最终,在另一个系统上被包装的对象可以被销毁,而Sui上的对象更新以反映任何状态或所有权的变化,并解锁。 桥接资产的语义对于确保封装资产是有用的,具有一定的重要性。跨区块链桥接的可替代资产可以提供更丰富的包装表示,允许它们在包装时可分割和转移。不可替代资产不能分割,只能转让。它们还可能支持在包装时以受控方式改变其状态的其他操作,这可能需要在它们被桥接回来并取消包装时执行自定义智能合约逻辑。Sui很灵活,允许智能合约作者定义这些体验,因为桥梁只是在Move中实现的智能合约,而不是原生的Sui概念——因此可以使用Move提供的可组合性和安全保证进行扩展。 4.7 委员会重置 重置发生在epoch之间,委员会
𝐶𝑒
会被
𝐶𝑒‘
取代,此时
𝑒‘ = 𝑒 + 1
。重置的安全性确保如果事务Tx是在𝑒或之前提交的,则在𝑒之后不会提交冲突的事务。可终止性确保如果Tx是在𝑒或之前提交的,那么它也必须在𝑒之后提交。 我们利用Sui智能合约系统来执行大量必要的重新配置工作。在Sui内部,一个系统智能合约允许用户锁定并将对应的代币委托给候选验证者。在某个epoch,币的所有者可以通过锁定代币进行委托,通过解锁代币取消委托,或将其委托更改为一个或多个授权。 一旦投票选择结束epoch
e
的人数达到法定人数,验证者们会交换信息来达到同一个检查点,确定下一个委员会,并改变epoch。在协议[9]的帮助下,来商定一个认证的检查点以结束epoch
e
。检查点包含已由验证者处理的所有事务和可能产生的对象的集合。因此,如果一个事务已被验证者处理,那么至少有一个处理该事务的诚实验证者将其处理过的事务包括在epoch结束检查点中,从而确保事务及其影响是跨epoch持久的。此外,这样一个认证的检查点保证了所有的事务对纪元𝑒的诚实的验证者都是可用的。 然后,在epoch结束的检查点的委托代币质押被用来确定新的epoch
e+1
的验证者集合。这两个epoch的验证者的签署都达到法定人数时,就开启新的epoch。一旦这两组签名都可用了之后,新的验证者集合就开始处理新epoch的交易了。而旧epoch的验证者则可以删除他们的epoch签名key了。
恢复:
由于客户端错误或客户端模棱两可,所拥有的对象可能会在一个时期内被“锁定”,从而阻止与之相关的任何事务被认证(或最终完成)。例如,一个客户端使用同一个拥有的对象版本签署两个不同的事务,每一个事务都有一半的验证者进行签名,那么就无法形成一个需要对这两个证书中的任何一个进行仲裁签名的证书。恢复确保一旦epoch发生更改,这些对象将再次处于允许它们在事务中使用的状态。因为不能生成证书,所以在要操作的下一个epoch开始时,原始对象是可用的。由于事务包含一个纪元号,旧的模棱两可的事务将不会再次锁定对象,从而给对象的所有者一个使用它的机会。
奖励和代币经济学:
Sui有一种原生的令牌Sui,具有固定的供给。SUI是用来支付gas费用的,也可以作为一个epoch的委托质押。在这个epoch,验证者的投票权就是这种委托利益的功能。在epoch结束时,通过所有交易收取的费用将根据他们对Sui的经营贡献分配给验证者,反过来,他们将一部分费用作为对委托给他们的地址的奖励。我们将Sui代币经济学的完整描述推迟到一篇专门的论文中。 4.8 验证者和副本更新
为客户创造价值。
由于客户端故障或非拜占庭验证者故障,一些验证者可能没有处理所有证书。因此,依赖于这些证书生成的缺失对象的因果相关事务将被拒绝。然而,客户总是可以更新一个可靠的验证者,使其能够处理正确的事务。它可以使用自己的过去证书存储,或者使用一个或多个其他诚实的验证者作为过去证书的来源。 给定一个证书
c
和一个存储
Ct𝑣
,其中包括 c 和它的因果历史,客户端可以更新一个c也能被接受的诚实验证者v'。这涉及到寻找到证书c不在v'内的最小集,这样以便在应用时,c要求的输入对象v‘中都拥有。更新一个滞后的,使用包含证书TxCert的存储Ct𝑣的验证者B牵涉到: 客户端维护一个要同步的证书列表,最初设置为只包含TxCert。 客户端认为最后一个TxCert需要同步。它在TxCert中提取Tx并派生其所有输入对象(使用input (Tx))。 对于每一个输入对象,它都会检查最后生成或变异的Tx(使用𝐶𝑡𝑣上的Sync𝑣索引)是否有一个B内的证书,否则就从𝐶𝑡𝑣上读取证书并添加到要同步的证书列表里。 如果没有更多的证书可以添加到列表中(因为没有更多的输入从𝐵丢失),证书列表按因果顺序排序,并提交到𝐵。 上面的算法也适用于将对象更新到特定版本以启用新事务。在本例中,生成对象版本的Tx的证书,在Sync中找到𝑣 [ObjRef]被提交给了滞后验证者。一旦在𝐵上执行,就可以使用正确版本的对象。 执行此操作的客户端称为中继器。可以有多个中继器独立和并发操作。他们在诚信方面是不可信的,他们的操作是无key的。除了客户端,中心还可以运行中继逻辑来更新彼此,副本操作服务也可以作为中继来更新滞后的中心。
bulk。
验证者为追随者(follower)提供设施,以便他们在处理证书时接收更新。这允许副本维护验证者状态的最新视图。此外,验证者可以使用推拉式gossip网络在短期内互相更新最新处理的交易,以减少中继者执行这一功能的需要。在较长的时期内,滞后的验证者可以使用周期性的状态承诺,在时期边界或更频繁地,以确保他们已经处理了一套完整的证书,直到某些检查点。 5. 缩放和延迟 Sui系统允许通过将更多资源(即一台机器内或多台机器上的cpu、内存、网络和存储)分配给事务处理的权限进行伸缩。更多的资源会增加处理交易的能力,从而增加为这些资源提供资金的费用收入。更多的资源还会导致更低的延迟,因为操作无需等待必要的资源变得可用就可以执行。
吞吐量。
为了确保更多的资源导致准线性容量的增加,Sui设计积极地减少了瓶颈和需要在权限内全局锁的同步点。事务处理被清晰地划分为两个阶段,即 (1)确保事务对特定版本的所有或共享对象具有独占访问权 (2)随后执行事务并提交其效果。 阶段(1)需要一个事务来获取对象粒度上的分布式锁。对于拥有的对象,这是通过可靠的广播原语执行的,不需要在权限内进行全局同步,因此可以通过ObjID跨多台机器分片锁管理来扩展。对于涉及共享对象的事务,需要使用共识协议来排序,这对这些事务施加了全局顺序,并有可能成为瓶颈。然而,最近关于工程高吞吐量共识协议[9]的进展表明,顺序执行是状态机复制的瓶颈,而不是排序。在Sui中,排序只用于确定输入共享对象的版本,即增加对象版本号并将其与事务摘要相关联,而不是执行顺序执行。 阶段(2)发生在所有输入对象的版本为验证者所知的时候(并且在验证者之间安全地达成一致),并且涉及到Move事务的执行及其效果的承诺。一旦知道了输入对象的版本,就可以执行完全平行地发生。将虚拟机移动到多个核心或物理机器上,读取版本控制的输入对象、执行并将结果对象从存储中写入存储中。对象和事务(除了订单锁映射)的存储一致性要求非常宽松,允许每个验证者在内部使用可伸缩的分布式键值存储。执行是幂等的,这使得处理执行的组件的崩溃或硬件故障也很容易恢复。 因此,相互之间没有因果关系的事务可以并行执行。因此,智能合约设计者可以在其合约内设计对象和操作的数据模型,以利用这种并行性。 检查点和状态承诺是在关键事务处理路径上计算出来的,以避免阻塞新事务的处理。这涉及到对已提交数据的读操作,而不是在事务到达终结之前要求进行计算和协商。因此,它们不会影响处理新事务的延迟或吞吐量,并且本身可以跨可用资源分布。 读取可以受益于非常主动的、可伸缩的缓存。验证者签署并提供轻客户端读取所需的所有数据,这些数据可以由分布式存储作为静态数据提供。证书作为其交易和对象的完整因果历史的信任根(roots of trust)。状态承诺进一步允许整个系统对所有处理的状态和事务具有定期的全局信任根,至少每个epoch,或者更频繁。
延迟
。智能合约设计者可以灵活地控制他们定义的操作的延迟,这取决于它们涉及的是拥有的对象还是共享的对象。拥有的对象在执行和提交之前依赖于可靠的广播,这需要两次往返于法定验证者以达到最终结果。另一方面,涉及共享对象的操作需要一个一致的广播来创建证书,然后在一个共识协议中处理,这导致延迟增加(从[9] 到仲裁的4到8次往返)。 [1].Mustafa Al-Bassam, Alberto Sonnino, Vitalik Buterin, and Ismail Khoffi. 2021. Fraud and Data Availability Proofs: Detecting Invalid Blocks in Light Clients. In Financial Cryptography and Data Security - 25th International Conference, FC 2021, Virtual Event, March 1-5, 2021, Revised Selected Papers, Part II (Lecture Notes in Computer Science, Vol. 12675), Nikita Borisov and Claudia Diaz (Eds.). Springer, 279–298 [2] Shehar Bano, Alberto Sonnino, Mustafa Al-Bassam, Sarah Azouvi, Patrick McCorry, Sarah Meiklejohn, and George Danezis. 2019. SoK: Consensus in the Age of Blockchains. In Proceedings of the 1st ACM Conference on Advances in Financial Technologies, AFT 2019, Zurich, Switzerland, October 21-23, 2019. ACM, 183–198. [3] Mathieu Baudet, George Danezis, and Alberto Sonnino. 2020. FastPay: HighPerformance Byzantine Fault Tolerant Settlement. In AFT ’20: 2nd ACM Conference on Advances in Financial Technologies, New York, NY, USA, October 21-23, 2020. ACM, 163–177. 2021. [4] Sam Blackshear, Evan Cheng, David L. Dill, Victor Gao, Ben Maurer, Todd Nowacki, Alistair Pott, Shaz Qadeer, Ra in, Dario Russi, Stephane Sezer, Tim Zakian, and Runtian Zhou. 2019. Move: A Language With Programmable Resources.
[5] Sam Blackshear, David L. Dill, Shaz Qadeer, Clark W. Barrett, John C. Mitchell, Oded Padon, and Yoni Zohar. 2020. Resources: A Safe Language Abstraction for Money. CoRR abs/2004.05106 (2020). arXiv:2004.05106
2004.05106 [6] Christian Cachin, Rachid Guerraoui, and Luís Rodrigues. 2011. Introduction to reliable and secure distributed programming. Springer Science & Business Media [7] Panagiotis Chatzigiannis, Foteini Baldimtsi, and Konstantinos Chalkias. 2021. SoK: Blockchain Light Clients. IACR Cryptol. ePrint Arch. (2021), 1657. [8] Daniel Collins, Rachid Guerraoui, Jovan Komatovic, Petr Kuznetsov, Matteo Monti, Matej Pavlovic, Yvonne-Anne Pignolet, Dragos-Adrian Seredinschi, Andrei Tonkikh, and Athanasios Xygkis. 2020. Online Payments by Merely Broadcasting Messages. In 50th Annual IEEE/IFIP International Conference on Dependable Systems and Networks, DSN 2020, Valencia, Spain, June 29 - July 2, 2020. IEEE, 26–38. [9] George Danezis, Eleftherios Kokoris-Kogias, Alberto Sonnino, and Alexander Spiegelman. 2021. Narwhal and Tusk: A DAG-based Mempool and Efficient BFT Consensus. CoRR abs/2105.11827 (2021). [10] David L. Dill, Wolfgang Grieskamp, Junkil Park, Shaz Qadeer, Meng Xu, and Jingyi Emma Zhong. 2021. Fast and Reliable Formal Verification of Smart Contracts with the Move Prover. CoRR abs/2110.08362 (2021). arXiv:2110.08362
[11] Rachid Guerraoui, Petr Kuznetsov, Matteo Monti, Matej Pavlovic, and DragosAdrian Seredinschi. 2018. AT2: Asynchronous Trustworthy Transfers. CoRR abs/1812.10844 (2018). [12] Rachid Guerraoui, Petr Kuznetsov, Matteo Monti, Matej Pavlovic, and DragosAdrian Seredinschi. 2019. The Consensus Number of a Cryptocurrency. In Proceedings of the 2019 ACM Symposium on Principles of Distributed Computing, PODC 2019, Toronto, ON, Canada, July 29 - August 2, 2019, Peter Robinson and Faith Ellen (Eds.). ACM, 307–316. [13] Patrick McCorry, Chris Buckland, Bennet Yee, and Dawn Song. 2021. SoK: Validating Bridges as a Scaling Solution for Blockchains. IACR Cryptol. ePrint Arch. (2021), 1589. [14] Marco Patrignani and Sam Blackshear. 2021. Robust Safety for Move. CoRR abs/2110.05043 (2021). arXiv:2110.05043
[15] Jerome H Saltzer and Michael D Schroeder. 1975. The protection of information in computer systems. Proc. IEEE 63, 9 (1975), 1278–1308. [16] Jingyi Emma Zhong, Kevin Cheang, Shaz Qadeer, Wolfgang Grieskamp, Sam Blackshear, Junkil Park, Yoni Zohar, Clark W. Barrett, and David L. Dill. 2020. The Move Prover. In Computer Aided Verification - 32nd International Conference, CAV 2020, Los Angeles, CA, USA, July 21-24, 2020, Proceedings, Part I (Lecture Notes in Computer Science, Vol. 12224), Shuvendu K. Lahiri and Chao Wang (Eds.). Springer, 137–150.
send_coin<T>(c: Coin<T>,…)
,泛型类型参数T可以用类型参数SUI实例化,以发送SUI原生token)。纯值可以包括基元类型和基元类型的向量,但不包括结构类型。 调用要调用的函数是通过对象引用(必须指向一个包对象)、包中的模块名和包中的函数名指定的。要执行调用事务,Sui运行时将解析函数,将类型、对象和值参数绑定到函数参数,并使用Move VM执行函数。 调用和发布交易都受gas计量和gas费用的影响。计量限制用最大gas预算表示。运行时将执行事务,直到达到预算为止,如果预算耗尽,则将中止而不产生任何影响(除了扣除费用并报告中止代码)。 费用从指定为对象参考的气体对象中扣除。该对象必须是Sui的本地令牌(即类型必须为Coin)。Sui使用eip1559风格的费用:该协议定义了一个基本费用(以每个Sui代币的天然气单位计算),在纪元边界进行算法调整,交易发送者也可以包括一个可选的小费(以Sui代币计算)。在正常的系统负载下,即使没有提示,事务也会被及时处理。但是,如果系统拥塞,则小费较多的事务将被优先处理。气体对象的总费用是(GasUsed * BaseFee) + Tip。 3.6 交易的影响 Event = StructType × Struct
Create = Obj
Update = Obj
Wrap = ObjID × Version
Delete = ObjID × Version
ObjEffect = Create ⊎ Update ⊎ Wrap ⊎ Delete
AbortCode = N × ModuleName
SuccessEffects = [ObjEffect] × [Event]
AbortEffects = AbortCode
TxEffects = SuccessEffects ⊎ AbortEffects
事务执行产生的事务效果在事务成功执行(上面的SuccessEffects)和不成功执行(上面的AbortEffects)时是不同的。 事务成功执行后,事务效果包括对Sui的全局对象池所做的更改(包括对现有对象和新创建对象的更新)和事务执行期间生成的事件的信息。 事务执行成功的另一个影响可能是对象从全局对象池里删除(比如deletion)并且包装一个对象(比如embedding)到另一个对象里,这与移除有类似的效果——被包装的对象从全局池中消失,只作为包装它的对象的一部分存在。由于已删除和封装的对象在全局池中不再可访问,因此这些效果由对象的ID和版本表示。 事件编码成功执行事务的连锁反应,而不仅仅是更新全局对象池。 在结构上,一个事件由一个Move结构体及其类型组成。事件旨在由区块链之外的参与者使用,但Move程序不能读取事件。 交易有一个原子性的语义,如果执行事务中止在某种情况下(例如,由于一个意想不到的失败),即使发生了一些改变对象(或一些事件生成的)这一点之前,这些影响坚持一个失败的事务。相反,中止的事务效果包括一个数字中止代码和发生事务中止的模块的名称。中止交易仍需收取gas费。 4.Sui系统 在本节中,我们从系统的角度来描述Sui,包括确保安全的机制和在出现了拜占庭式容错的情况下各验证者的有效性。我们还解释了客户端的操作,包括轻量级客户端,它们需要在不验证完整状态的情况下对系统状态进行一些保证。
简短的背景介绍。
在系统层面上,Sui发展自FastPay[3]的低延迟结算系统,扩展到通过用户定义的智能合约操作任意对象,并由具有无权限的质押委托股权证明[2]。对象所有者的基本资产管理基于拜占庭一致性广播[6]的变种,与传统的拜占庭共识[8,11,12]实现相比,它具有更低的延迟,也更容易跨多台机器伸缩。当需要完全的协议时,我们使用高吞吐量的基于DAG的共识,例如[9]用来管理锁,当在不同的共享对象上并行执行操作的时候。
协议大纲
图1 提交事务的交互概述 上图展示了客户端与Sui验证者之间提交事务的高级交互。我们在此简单的介绍: 一个拥有私有签名密钥的用户创建并签署了一个用户事务,以改变他们在Sui内部拥有或者共享的对象。随后,不再需要用户的签名密钥,流程的剩余部分可能由用户的客户端执行,或者由代表用户的网管执行(在图中表示为无密钥操作)。 用户的交易被发送至Sui验证者,验证者们检查其有效性,并在成功签署后返回发送给客户端的已签名事务。客户端收集到足够多验证者的响应(达到法定人数)之后形成一个事务证书。 事务证书被发送给所有的验证者,如果交易涉及到共享对象,它也被发送到一个由Sui验证者们共同操作的拜占庭协议。验证者们回检查这个证书,如果涉及到共享对象,会将对应的共享对象和其他共享对象事务进行排序,然后执行交易并将其效果汇总成一个签名的效果响应。 一旦足够数量的验证者执行了证书,就代表着事务最终生效了(即图中的finality)。客户端可以收集验证者响应的仲裁,并创建一个效果证书,并将其用作事务效果的最终证明。 本节详细描述这些操作,以及跨权限重新配置和管理状态的操作。 4.1 系统模型 Sui的操作在一系列周期中以
𝑒 ∈ {0, . . .}
表示。每个周期都由一个委员会
𝐶𝑒 = (𝑉𝑒, 𝑆𝑒 (·))
来进行管理,
𝑉𝑒
是一组具有已知公共验证key和网络终端的验证者集合。函数
𝑆𝑒 (𝑣)
映射了每个验证者
𝑣 ∈ 𝑉𝑒
对应被委托质押的数量。我们假设
𝐶𝑒
对于每个周期,都是由法定人数(见下文)在第e-1周期签署的(第4.7节讨论委员会的组成和管理)。在一个周期内,有些验证者是正确的(他们忠实地遵循协议,并且是实时的),而有一些验证者则是拜占庭式的(他们任意的偏离协议)。安全的假设是,诚实验证者节点的集合
𝐻𝑒 ⊆ 𝑉𝑒
是否在指定周期内分配到了法定的份额,比如Σ h ∈ H e S e ( h ) > 2 / 3 Σ v ∈ V e S e ( v ) \Sigma _h\in H_e S_e (_h) > 2/3 \Sigma _v\in V_e S_e(_v) Σ h ∈ H e S e ( h ) > 2/3 Σ v ∈ V e S e ( v ) (这里指拥有超过三分之二的质押验证者作为法定人数) 至少存在一个活跃的、存在着的当事者作为每个证书(详见4.3节)在诚实的验证者中间作为中继器(relay)。这确保了可终止性,并为拜占庭广播提供了一个最终交付属性(参考[6]中的可靠广播的整体性)。每个验证者都单独或通过集体传播协议运行这样的中继器。外部实体,包括Sui的轻客户端,副本和服务都可能扮演这个角色。有限授权的核心和内部或者外部的活跃中继器区别,确保了可靠计算基础[15]的清晰划分和最小化,而Sui的安全性和可终止性依赖于此。 4.2 验证者 & 副本数据结构 Sui的验证者依靠大量的数据结构来表示状态。我们根据它们支持的操作定义这些结构。它们都有一个确定的字节表示方式。 对象(Obj)在Sui中存储智能合约和数据。它们是第2节中介绍的Sui系统级别的Move对象编码。它们支持以下操作集: ref(Obj)
返回对象的引用(ObjRef),即一个三元组(ObjID, Version, ObjDigest)。ObjID几乎是对于所有新创建的对象来说是唯一的,Version是一个递增的正整数,表示对象发生变化时的版本。
owner(Obj)
返回该对象所有者的认证者Auth。在最简单的情况下,Auth是一个地址,表示可能使用该对象的公钥。也可以使用更复杂的验证器(参见4.4节)。
read-only(Obj)
如果对象是只读的,返回true。只读对象永远不能被修改、包装或删除。它们也可能被任何人使用,而不仅仅是它们的拥有者。
parent(Obj)
返回最近一次修改或创建对象的事务摘要(TxDigest)。
contents(Obj)
返回对象类型
type
和data
data
,可以用来检查事务的有效性,并携带对象的特定应用程序信息。 对象引用(ObjRef)用于索引对象。它还用于验证对象,因为ObjDigest是对对象全部内容的承诺(commitment)。 事务(Tx)是表示一个或多个对象的状态转换的结构。它们支持以下操作集:
digest(Tx)
返回TxDigest,它是对事务的绑定密码承诺。
epoch(Tx)
返回事务执行期间的EpochID。
input (Tx)
返回一个事务需要执行的对象[ObjRef]序列。
payment(Tx)
返回一个ObjRef的引用,用于支付gas,以及gas的最大限额,以及gas单位和gas支付对象的价值单位之间的转化率。
valid(Tx, [Obj])
如果事务有效则返回true。有效性在第4.4节中讨论,它涉及被授权对输入对象起作用的交易,以及有足够的gas可用来支付执行的成本。
exec(Tx, [Obj])
执行事务并返回一个表示其效果的结构效果。一个有效的事务执行是绝对正确的,它的输出是确定的。 事务由其TxDigest建立索引,该TxDigest也可用于验证事务的全部内容。所有有效的事务(除了特殊的硬编码生成事务)至少有一个拥有的输入,即用于支付gas的对象。 事务效果(effects)结构总结了事务执行的结果。支持以下操作:
digest(Effects)
是EffDigest对Effects结构的承诺,可以用来索引或验证它。
transaction(Effects)
返回产生效果的执行事务的TxDigest。
dependencies(Effects)
返回一个依赖序列[TxDigest],应该在事务执行之前执行。
contents(Effects)
返回执行的摘要。Status报告智能合约执行的结果。列表Created、Mutated、Wrapped、Unwrapped和Deleted列出了经历了各自操作的对象引用。而Events则列出由执行发射(emit)的事件。 事务上的事务证书TxCert包含事务本身以及来自仲裁机构的标识符和签名。请注意,证书可能不是唯一的,因为相同的逻辑证书可能由组成仲裁的不同的权威集表示。此外,证书可能不会严格地由2/3的法定人数签名,但如果有更多的授权机构响应,可能会更多。但是,同一事务上的两个不同的有效证书应该被视为在语义上表示相同的证书。部分证书(TxSign)包含相同的信息,但来自一组授权机构的签名,这些授权机构代表的风险低于所需的法定人数,通常是单个授权机构。签名者的标识符包含在证书中(即负责任的签名[?])以识别验证者准备处理证书,或可用于下载处理证书所需的过去信息(参见4.8节)。 类似地,效应结构上的效应证书
EffCert
包含效应结构本身,以及来自验证者的签名,这些验证者代表了交易有效时期的法定人数。关于非惟一性和身份的注意事项同样适用于事务证书。一个部分效果证书,通常包含一个验证签名和效果结构,称为
EffSign
。
持久存储
每个验证者和副本维护一组持久存储。存储实现了持久的映射语义,可以表示为一组键-值对(表示为𝑚𝑎𝑝[𝑘𝑒𝑦]→𝑣𝑎𝑙𝑢𝑒),这样只有一个键对具有给定的键。在插入pair之前,contains(𝑘𝑒𝑦)调用返回false, get(𝑘𝑒𝑦)调用返回错误。插入一对后,contains(𝑘𝑒𝑦)调用返回true, get(𝑘𝑒𝑦)返回值。中心维护以下持久存储: order lock map
lock𝑣 [ObjRef]→TxSignOption
记录一个拥有对象版本ObjRef的授权下第一个被Tx看到并签名的有效事务,或者如果对象版本存在但没有被用作输入的有效事务被看到,则为None。它还可以记录与该对象一起出现的第一个证书作为输入。这个表和它的更新规则代表了整个Sui权限范围内对象上的分布式锁的状态,并确保了事务并发处理下的安全性。 certificate map
Ct𝑣 [TxDigest]→(TxCert, EffSign)
记录所有完整的证书TxCert(也包括Tx),在其有效期内由验证者处理,以及其签名的效果EffSign。它们通过事务摘要TxDigest进行索引。 The object map
Obj𝑣 [objj]→Obj
记录了所有Obj创建的对象,这些对象包含在Ct的证书中𝑣 由ObjRef索引。这个存储可以通过重新执行Ct中的所有证书来完全派生𝑣 .维护一个二级索引,将ObjID映射到具有该ID的最新对象。这是处理新事务所需的惟一信息,而维护旧版本只是为了方便读取和审计。 -The synchronization map
Sync𝑣 [ObjRef]→TxDigest
索引Ct内的所有证书𝑣 通过他们创建,变异或删除的对象作为元组ObjRef。该结构可以通过处理Ct中的所有证书完全重新创建𝑣 ,用于帮助客户端同步影响它们所关心的对象的事务。 验证者维护所有四个结构,并提供对其证书映射的本地检查点的访问,以允许其他验证者和副本下载其完整的已处理证书集。副本不处理事务,只处理证书,并像权威机构那样重新执行它们以更新其他表。它还维护了一个订单锁映射,以审计非模糊性。 一个中心可以被设计成一个完整的副本,维护所有四个存储区(和检查点),以促进读取和同步,并结合一个最小的中心,只维护用于处理新事务和证书的对象的最新版本的对象锁和对象。这最大限度地减少了安全所依赖的可信计算基础。 只有顺序锁映射需要强键自一致性,也就是说,对某个键的读取应该始终返回某个已存在键的值是否存在或是否存在None,并且这种检查应该是原子性的,并将锁设置为非None值。与跨键的强一致性相比,这是一个较弱的属性,并允许对存储进行有效的分片以进行伸缩。其他存储可能最终会在不影响安全的情况下保持一致。 4.3 验证者基础操作
处理事务:
在接收到Tx交易后,验证者执行一系列检查: 1.确保epoch(Tx)是当前的epoch 2.确保所有对象引用输入(Tx)和支付中的gas对象引用(Tx)都存在于Obj中𝑣 并加载到[Obj]。对于拥有的对象,应该提供准确的引用;对于只读或共享对象,对象ID应该存在。 3.确保gas对象中有足够的gas来支付执行交易的成本 4.检查valid(Tx, [Obj])是true。这个步骤确保事务中的身份验证信息允许访问拥有的对象。它检查锁𝑣 [ObjRef]为所有拥有的输入(Tx)对象存在,它要么为None,要么设置为相同的Tx,并自动设置为TxSign。(我们称之为“锁检查”)。 如果任何检查失败,处理结束,并返回一个错误。但是,对Lock的部分更新是安全的𝑣 持久(尽管我们当前的实现不进行部分更新,而是对所有锁进行原子更新)。 如果所有的检查都成功,那么验证者就会返回一个对事务的签名。部分证书TxSign。成功后,处理订单是幂等的,并返回部分证书(TxSign),或完整证书(TxCert)(如果有的话)。 任何一个验证者都可以整理一个epoch内的交易和签名(TxSign)𝑒,以形成一个交易证书TxCert。
过程证明:
在收到证书后,验证者检查事务的所有有效性条件,除了与锁相关的(所谓的“锁检查”)。相反,它执行以下检查:对于输入(Tx)中的每个拥有的输入对象,它检查锁是否存在,并且它要么为None,要么设置为任何TxSign,要么设置为与当前证书相同的事务的证书。如果修改后的锁检查失败,则中心检测到不可恢复的拜占庭故障,停止正常操作,并启动灾难恢复进程。对于共享对象(见4.4节),验证者检查锁是否已经通过被排序的证书在一个共识中设置,以确定要使用的共享对象版本。如果是这样,交易可以执行;否则就需要等待这样的排序。 如果检查成功,验证者将证书添加到它的证书映射中,以及它的执行所产生的效果,例如:Ct𝑣 [TxDigest]→(TxCert, EffSign);它更新锁映射以记录证书Lock𝑣 [ObjRef]→TxCert用于所有拥有的没有设置为证书的锁的输入对象。只要Input(Tx)中的所有对象都插入到Obj中𝑣 ,那么EffSign中的所有效果也通过将它们的ObjRef和内容添加到Obj来具体化𝑣 .最后,所有在EffSign中创建或修改的同步映射都被更新为映射到Tx。
结论:
处理事务和证书的逻辑导致了许多重要的属性:
因果关系和并行性
。事务和证书的处理条件都确保了因果执行:一个验证者只有在处理了所有创建该事务所依赖的对象的证书(包括所有的、共享的和只读的)之后,才会通过签署一项交易来“投票”。类似地,只有当中心所依赖的所有输入对象都存在于其本地对象映射中时,中心才会处理证书。这就强加了一个因果执行顺序,但也允许不相互依赖的事务在不同的核心或机器上并行执行。
一次签名,确保安全
。所有拥有的输入对象在Lock中锁定𝑣 [·]设置为使用它们通过检查的第一个事务Tx,然后设置为使用该对象作为输入的第一个证书。我们称此操作为将对象锁定到该事务,并且在一个时期内不存在解锁操作。因此,验证者在每个锁上只签署一个事务,这是一致广播[6]基本组成部分,因此也保证了Sui的安全性。
灾难恢复
。一个权威机构检测到同一个锁的两个相互矛盾的证书,它有无法恢复的拜占庭行为的证据——即quorum诚实权威假设不成立的证据。这两个相互矛盾的证书是一个欺诈证明[1],可以与所有权威机构和副本共享,以触发灾难恢复过程。权威机构还可能得到不可恢复的拜占庭行为的其他形式的证明,比如代表证书执行错误的效果上的>1/3签名(EffSign)。或者,一个证书的输入对象不能代表以前处理过的证书的正确输出。这些也可以打包为欺诈证据,并与所有当局和副本共享。请注意,这些不同于那些可以容忍的少数权威(按股份≤1/3)或对象所有者(任何数字)是拜占庭或模棱两可的证据,它们可以在没有任何服务中断的情况下被容忍。
终局性
。于Lock中索引的任何读请求,验证者都会返回一个证书(TxCert)和签名效果(EffSign)𝑣 , Ct𝑣 和Obj𝑣 、Sync𝑣。一笔交易如果超过法定人数的验证者报告Tx包括在他们的Ct𝑣存储里,那么这笔交易就是最终的交易。这意味着效果证书(EffCert)是终局性的可转移证明。然而,使用对象的证书也证明了所有的依赖关系其因果路径中的证书也是最终的。向任何一方提供证书,然后将其提交给绝大多数验证者进行处理,也确保了证书效果的终局性。注意,finality比fastpay[3]要晚,以确保重新配置时的安全性。然而,中心可以在看到证书时应用事务的效果,而不是等待提交。 4.4 所有者、授权和共享对象 事务有效性(见4.3节)确保一个事务被授权在一个事务中包含所有指定的输入对象。这种检查取决于对象的性质以及所有者字段。 只读对象不能被修改或删除,并且可以被所有用户并发地在事务中使用。例如,Move模块是只读的。这样的对象确实有一个可能被用作智能合约一部分的所有者,但这并不影响使用它们的授权。它们可以包含在任何交易中。 拥有的对象有一个所有者字段。所有者可以设置为表示公钥的地址。在这种情况下,如果事务是由该地址签名的,那么它就被授权使用该对象并对其进行修改。事务由单个地址签名,因此可以使用该地址拥有的一个或多个对象。但是,一个事务不能使用多个地址拥有的对象。一个对象(称为子对象)的所有者可以被设置为另一个对象(称为父对象)的ObjID。在这种情况下,只有当父对象包含在事务中时,才可以使用子对象,并且事务被授权使用该对象。契约可以使用这个功能来构造有效的集合和其他复杂的数据结构。 共享对象是可变的,但没有特定的所有者。它们可以被不同的方包括在交易中,不需要任何授权。相反,它们执行自己的授权逻辑。这样的对象,由于必须支持多个写入器,同时确保安全性和活动性,确实需要一个完整的协议协议才能安全地使用。因此,它们在执行之前需要额外的逻辑。授权机构处理章节4.3中规定的事务,用于管理拥有对象和只读对象的锁。然而,验证者并不依赖于一致的广播来管理共享对象的锁。相反,涉及共享对象的事务的创建者将事务上的证书插入到高吞吐量的共识系统中,例如[9]。所有权威机构都遵循这样的证书的一致顺序,并根据这个顺序分配每个交易使用的共享对象的版本。然后执行可以继续进行,并保证在所有权限之间保持一致。在effect证书中包含事务执行中使用的共享对象的版本。 上述规则确保,对于涉及只读对象和拥有对象的事务,只需要一致的广播和一个证书就可以执行;拜占庭协议只适用于涉及共享对象的事务。因此,智能合约作者可以设计他们的类型和操作,以优化单个用户对象上的传输和其他操作,以降低延迟,同时享受使用共享的灵活性对象来实现需要由多个用户访问的逻辑。 4.5 客户端
副本:
有时也称为完整的客户端,不验证新的事务,但维护系统有效状态的一致副本,以进行审计,以及构建事务或操作服务,包括用于轻客户端查询的读取基础设施。
轻客户端:
对象引用和事务都包含允许对导致其创建或执行的事务的完整因果链进行身份验证的信息。具体来说,对象引用(ObjRef)包含一个ObjDigest,它是对象完整状态的验证器,包括获取父对象(Obj)的工具,即创建对象的TxDigest。类似地,TxDigest对事务进行身份验证,包括通过输入(Tx)提取输入对象的对象引用的工具。因此,对象和证书的集合形成了一个自认证的二分图。此外,效果结构也被签名,并且可以整理成直接证明事务执行结果的效果证书。 这些设施可以用于支持轻客户端,这些客户端可以执行对Sui状态的高完整性读取,而无需维护一个完整的复制节点。具体地说,一个机构或完整节点可以提供一个简洁的证据束,包括一个交易Tx上的证书TxCert和对应于输入(Tx)的输入对象[Obj],以使轻客户端相信一个转换可以在Sui内发生。然后,轻客户端可以提交此证书,或检查是否已被法定人数或验证者的样本看到,以确保最终结果。或者,它可以使用执行产生的对象来设计一个事务,并观察它是否成功。 更直接地说,服务可以向客户端提供一个效果证书,以说服他们在Sui中存在一个过渡,并且这个过渡是最终的,而系统中没有进一步的操作或交互。如果最终证书的检查点可用,在时代边界或其他地方,包括输入对象和证书的证据束,以及证书包含在检查点中的证明,也是最终的证明。 验证者可以使用定期检查的机制来创建最终交易的集体检查点,以及Sui的状态随时间的推移。轻客户端可以使用具有检查点上的仲裁权益的证书有效地验证对象的最近状态和发出的事件。一个检查点机制是必要的委员会重组之间的epoch。更频繁的检查点对于轻客户端很有用,验证者也可以使用它来压缩内部数据结构,以及更有效地与其他验证者同步状态。 4.6 桥 对轻客户端和通过拜占庭协议管理的共享对象的原生支持,允许Sui支持与其他区块链[13]的双向桥。这类桥梁的信任假设反映了Sui和其他区块链的信任假设,如果其他的区块链也支持轻客户端,则不需要依赖与受信任的预言机或者是硬件[7]。 桥用于导入发布在另一个区块链上的资产,并将其表示为一个封装在Sui系统中的资产。最终,可以解锁被包装的资产,并将其传输回本机区块链上的用户。桥还允许在Sui上发行的资产被锁定,并作为包装资产在其他区块链上使用。最终,在另一个系统上被包装的对象可以被销毁,而Sui上的对象更新以反映任何状态或所有权的变化,并解锁。 桥接资产的语义对于确保封装资产是有用的,具有一定的重要性。跨区块链桥接的可替代资产可以提供更丰富的包装表示,允许它们在包装时可分割和转移。不可替代资产不能分割,只能转让。它们还可能支持在包装时以受控方式改变其状态的其他操作,这可能需要在它们被桥接回来并取消包装时执行自定义智能合约逻辑。Sui很灵活,允许智能合约作者定义这些体验,因为桥梁只是在Move中实现的智能合约,而不是原生的Sui概念——因此可以使用Move提供的可组合性和安全保证进行扩展。 4.7 委员会重置 重置发生在epoch之间,委员会
𝐶𝑒
会被
𝐶𝑒‘
取代,此时
𝑒‘ = 𝑒 + 1
。重置的安全性确保如果事务Tx是在𝑒或之前提交的,则在𝑒之后不会提交冲突的事务。可终止性确保如果Tx是在𝑒或之前提交的,那么它也必须在𝑒之后提交。 我们利用Sui智能合约系统来执行大量必要的重新配置工作。在Sui内部,一个系统智能合约允许用户锁定并将对应的代币委托给候选验证者。在某个epoch,币的所有者可以通过锁定代币进行委托,通过解锁代币取消委托,或将其委托更改为一个或多个授权。 一旦投票选择结束epoch
e
的人数达到法定人数,验证者们会交换信息来达到同一个检查点,确定下一个委员会,并改变epoch。在协议[9]的帮助下,来商定一个认证的检查点以结束epoch
e
。检查点包含已由验证者处理的所有事务和可能产生的对象的集合。因此,如果一个事务已被验证者处理,那么至少有一个处理该事务的诚实验证者将其处理过的事务包括在epoch结束检查点中,从而确保事务及其影响是跨epoch持久的。此外,这样一个认证的检查点保证了所有的事务对纪元𝑒的诚实的验证者都是可用的。 然后,在epoch结束的检查点的委托代币质押被用来确定新的epoch
e+1
的验证者集合。这两个epoch的验证者的签署都达到法定人数时,就开启新的epoch。一旦这两组签名都可用了之后,新的验证者集合就开始处理新epoch的交易了。而旧epoch的验证者则可以删除他们的epoch签名key了。
恢复:
由于客户端错误或客户端模棱两可,所拥有的对象可能会在一个时期内被“锁定”,从而阻止与之相关的任何事务被认证(或最终完成)。例如,一个客户端使用同一个拥有的对象版本签署两个不同的事务,每一个事务都有一半的验证者进行签名,那么就无法形成一个需要对这两个证书中的任何一个进行仲裁签名的证书。恢复确保一旦epoch发生更改,这些对象将再次处于允许它们在事务中使用的状态。因为不能生成证书,所以在要操作的下一个epoch开始时,原始对象是可用的。由于事务包含一个纪元号,旧的模棱两可的事务将不会再次锁定对象,从而给对象的所有者一个使用它的机会。
奖励和代币经济学:
Sui有一种原生的令牌Sui,具有固定的供给。SUI是用来支付gas费用的,也可以作为一个epoch的委托质押。在这个epoch,验证者的投票权就是这种委托利益的功能。在epoch结束时,通过所有交易收取的费用将根据他们对Sui的经营贡献分配给验证者,反过来,他们将一部分费用作为对委托给他们的地址的奖励。我们将Sui代币经济学的完整描述推迟到一篇专门的论文中。 4.8 验证者和副本更新
为客户创造价值。
由于客户端故障或非拜占庭验证者故障,一些验证者可能没有处理所有证书。因此,依赖于这些证书生成的缺失对象的因果相关事务将被拒绝。然而,客户总是可以更新一个可靠的验证者,使其能够处理正确的事务。它可以使用自己的过去证书存储,或者使用一个或多个其他诚实的验证者作为过去证书的来源。 给定一个证书
c
和一个存储
Ct𝑣
,其中包括 c 和它的因果历史,客户端可以更新一个c也能被接受的诚实验证者v'。这涉及到寻找到证书c不在v'内的最小集,这样以便在应用时,c要求的输入对象v‘中都拥有。更新一个滞后的,使用包含证书TxCert的存储Ct𝑣的验证者B牵涉到: 客户端维护一个要同步的证书列表,最初设置为只包含TxCert。 客户端认为最后一个TxCert需要同步。它在TxCert中提取Tx并派生其所有输入对象(使用input (Tx))。 对于每一个输入对象,它都会检查最后生成或变异的Tx(使用𝐶𝑡𝑣上的Sync𝑣索引)是否有一个B内的证书,否则就从𝐶𝑡𝑣上读取证书并添加到要同步的证书列表里。 如果没有更多的证书可以添加到列表中(因为没有更多的输入从𝐵丢失),证书列表按因果顺序排序,并提交到𝐵。 上面的算法也适用于将对象更新到特定版本以启用新事务。在本例中,生成对象版本的Tx的证书,在Sync中找到𝑣 [ObjRef]被提交给了滞后验证者。一旦在𝐵上执行,就可以使用正确版本的对象。 执行此操作的客户端称为中继器。可以有多个中继器独立和并发操作。他们在诚信方面是不可信的,他们的操作是无key的。除了客户端,中心还可以运行中继逻辑来更新彼此,副本操作服务也可以作为中继来更新滞后的中心。
bulk。
验证者为追随者(follower)提供设施,以便他们在处理证书时接收更新。这允许副本维护验证者状态的最新视图。此外,验证者可以使用推拉式gossip网络在短期内互相更新最新处理的交易,以减少中继者执行这一功能的需要。在较长的时期内,滞后的验证者可以使用周期性的状态承诺,在时期边界或更频繁地,以确保他们已经处理了一套完整的证书,直到某些检查点。 5. 缩放和延迟 Sui系统允许通过将更多资源(即一台机器内或多台机器上的cpu、内存、网络和存储)分配给事务处理的权限进行伸缩。更多的资源会增加处理交易的能力,从而增加为这些资源提供资金的费用收入。更多的资源还会导致更低的延迟,因为操作无需等待必要的资源变得可用就可以执行。
吞吐量。
为了确保更多的资源导致准线性容量的增加,Sui设计积极地减少了瓶颈和需要在权限内全局锁的同步点。事务处理被清晰地划分为两个阶段,即 (1)确保事务对特定版本的所有或共享对象具有独占访问权 (2)随后执行事务并提交其效果。 阶段(1)需要一个事务来获取对象粒度上的分布式锁。对于拥有的对象,这是通过可靠的广播原语执行的,不需要在权限内进行全局同步,因此可以通过ObjID跨多台机器分片锁管理来扩展。对于涉及共享对象的事务,需要使用共识协议来排序,这对这些事务施加了全局顺序,并有可能成为瓶颈。然而,最近关于工程高吞吐量共识协议[9]的进展表明,顺序执行是状态机复制的瓶颈,而不是排序。在Sui中,排序只用于确定输入共享对象的版本,即增加对象版本号并将其与事务摘要相关联,而不是执行顺序执行。 阶段(2)发生在所有输入对象的版本为验证者所知的时候(并且在验证者之间安全地达成一致),并且涉及到Move事务的执行及其效果的承诺。一旦知道了输入对象的版本,就可以执行完全平行地发生。将虚拟机移动到多个核心或物理机器上,读取版本控制的输入对象、执行并将结果对象从存储中写入存储中。对象和事务(除了订单锁映射)的存储一致性要求非常宽松,允许每个验证者在内部使用可伸缩的分布式键值存储。执行是幂等的,这使得处理执行的组件的崩溃或硬件故障也很容易恢复。 因此,相互之间没有因果关系的事务可以并行执行。因此,智能合约设计者可以在其合约内设计对象和操作的数据模型,以利用这种并行性。 检查点和状态承诺是在关键事务处理路径上计算出来的,以避免阻塞新事务的处理。这涉及到对已提交数据的读操作,而不是在事务到达终结之前要求进行计算和协商。因此,它们不会影响处理新事务的延迟或吞吐量,并且本身可以跨可用资源分布。 读取可以受益于非常主动的、可伸缩的缓存。验证者签署并提供轻客户端读取所需的所有数据,这些数据可以由分布式存储作为静态数据提供。证书作为其交易和对象的完整因果历史的信任根(roots of trust)。状态承诺进一步允许整个系统对所有处理的状态和事务具有定期的全局信任根,至少每个epoch,或者更频繁。
延迟
。智能合约设计者可以灵活地控制他们定义的操作的延迟,这取决于它们涉及的是拥有的对象还是共享的对象。拥有的对象在执行和提交之前依赖于可靠的广播,这需要两次往返于法定验证者以达到最终结果。另一方面,涉及共享对象的操作需要一个一致的广播来创建证书,然后在一个共识协议中处理,这导致延迟增加(从[9] 到仲裁的4到8次往返)。 [1].Mustafa Al-Bassam, Alberto Sonnino, Vitalik Buterin, and Ismail Khoffi. 2021. Fraud and Data Availability Proofs: Detecting Invalid Blocks in Light Clients. In Financial Cryptography and Data Security - 25th International Conference, FC 2021, Virtual Event, March 1-5, 2021, Revised Selected Papers, Part II (Lecture Notes in Computer Science, Vol. 12675), Nikita Borisov and Claudia Diaz (Eds.). Springer, 279–298 [2] Shehar Bano, Alberto Sonnino, Mustafa Al-Bassam, Sarah Azouvi, Patrick McCorry, Sarah Meiklejohn, and George Danezis. 2019. SoK: Consensus in the Age of Blockchains. In Proceedings of the 1st ACM Conference on Advances in Financial Technologies, AFT 2019, Zurich, Switzerland, October 21-23, 2019. ACM, 183–198. [3] Mathieu Baudet, George Danezis, and Alberto Sonnino. 2020. FastPay: HighPerformance Byzantine Fault Tolerant Settlement. In AFT ’20: 2nd ACM Conference on Advances in Financial Technologies, New York, NY, USA, October 21-23, 2020. ACM, 163–177. 2021. [4] Sam Blackshear, Evan Cheng, David L. Dill, Victor Gao, Ben Maurer, Todd Nowacki, Alistair Pott, Shaz Qadeer, Ra in, Dario Russi, Stephane Sezer, Tim Zakian, and Runtian Zhou. 2019. Move: A Language With Programmable Resources.
[5] Sam Blackshear, David L. Dill, Shaz Qadeer, Clark W. Barrett, John C. Mitchell, Oded Padon, and Yoni Zohar. 2020. Resources: A Safe Language Abstraction for Money. CoRR abs/2004.05106 (2020). arXiv:2004.05106
2004.05106 [6] Christian Cachin, Rachid Guerraoui, and Luís Rodrigues. 2011. Introduction to reliable and secure distributed programming. Springer Science & Business Media [7] Panagiotis Chatzigiannis, Foteini Baldimtsi, and Konstantinos Chalkias. 2021. SoK: Blockchain Light Clients. IACR Cryptol. ePrint Arch. (2021), 1657. [8] Daniel Collins, Rachid Guerraoui, Jovan Komatovic, Petr Kuznetsov, Matteo Monti, Matej Pavlovic, Yvonne-Anne Pignolet, Dragos-Adrian Seredinschi, Andrei Tonkikh, and Athanasios Xygkis. 2020. Online Payments by Merely Broadcasting Messages. In 50th Annual IEEE/IFIP International Conference on Dependable Systems and Networks, DSN 2020, Valencia, Spain, June 29 - July 2, 2020. IEEE, 26–38. [9] George Danezis, Eleftherios Kokoris-Kogias, Alberto Sonnino, and Alexander Spiegelman. 2021. Narwhal and Tusk: A DAG-based Mempool and Efficient BFT Consensus. CoRR abs/2105.11827 (2021). [10] David L. Dill, Wolfgang Grieskamp, Junkil Park, Shaz Qadeer, Meng Xu, and Jingyi Emma Zhong. 2021. Fast and Reliable Formal Verification of Smart Contracts with the Move Prover. CoRR abs/2110.08362 (2021). arXiv:2110.08362
[11] Rachid Guerraoui, Petr Kuznetsov, Matteo Monti, Matej Pavlovic, and DragosAdrian Seredinschi. 2018. AT2: Asynchronous Trustworthy Transfers. CoRR abs/1812.10844 (2018). [12] Rachid Guerraoui, Petr Kuznetsov, Matteo Monti, Matej Pavlovic, and DragosAdrian Seredinschi. 2019. The Consensus Number of a Cryptocurrency. In Proceedings of the 2019 ACM Symposium on Principles of Distributed Computing, PODC 2019, Toronto, ON, Canada, July 29 - August 2, 2019, Peter Robinson and Faith Ellen (Eds.). ACM, 307–316. [13] Patrick McCorry, Chris Buckland, Bennet Yee, and Dawn Song. 2021. SoK: Validating Bridges as a Scaling Solution for Blockchains. IACR Cryptol. ePrint Arch. (2021), 1589. [14] Marco Patrignani and Sam Blackshear. 2021. Robust Safety for Move. CoRR abs/2110.05043 (2021). arXiv:2110.05043
[15] Jerome H Saltzer and Michael D Schroeder. 1975. The protection of information in computer systems. Proc. IEEE 63, 9 (1975), 1278–1308. [16] Jingyi Emma Zhong, Kevin Cheang, Shaz Qadeer, Wolfgang Grieskamp, Sam Blackshear, Junkil Park, Yoni Zohar, Clark W. Barrett, and David L. Dill. 2020. The Move Prover. In Computer Aided Verification - 32nd International Conference, CAV 2020, Los Angeles, CA, USA, July 21-24, 2020, Proceedings, Part I (Lecture Notes in Computer Science, Vol. 12224), Shuvendu K. Lahiri and Chao Wang (Eds.). Springer, 137–150.
No comments yet