Navigation

    Vite Forum
    • Register
    • Login
    • Search
    • Unsolved
    • Solved
    • Recent
    • Tags
    • Popular
    • Groups
    • Github
    1. Home
    2. Charles
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    Charles

    @Charles

    Founder and CEO of Vite Labs

    43
    Reputation
    18
    Posts
    132
    Profile views
    8
    Followers
    2
    Following
    Joined Last Online
    Website vite.org Location Beijing

    Charles Follow

    Best posts made by Charles

    • Vite gets listed on Bittrex

      We are delighted to be informed of the Bittrex listing! I want to thank my team for their hard work, and we continue to be committed to our mission of building the fast and fee-less network that also makes DAG + Smart contract possible.
      6cf3e869-bafb-4760-91c5-2e2ad4eead32-image.png

      posted in Discussion
      Charles
      Charles
    • VEP-5: Remove Explicit Snapshot Block Hash as Timestamps

      VEP-5: Remove Explicit Snapshot Block Hash as Timestamps

      Background

      In Section 6.2.2(Resource Quantification) of Vite White Paper Version 1.0, it mentions

      Because snapshot chain is equivalent to a global clock, we can use it to quantify the resource usage of an account accurately. In each transaction, the Hash of a snapshot block is quoted, the height of the snapshot block is took as the timestamp of the transaction. Therefore, according to the difference between the two transaction timestamps, we can judge whether the interval between the two transactions is long enough.

      explicit_timestamp.png

      Figure 1. explicit timestamps

      In Figure 1, each transaction contains an explicit hash reference to snapshot block as transaction creation time. The main purpose of this timestamp is to calculate whether the resource consumption of an account exceeds quota.

      In addition to "explicit" timestamp, there is another "implicit" timestamp in the system, which is the latest transaction hash for each account recorded in snapshot block, representing the "confirmation time" of a transaction.

      The two types of timestamp cause two-way dependency between transactions and snapshot chain, as shown in Figure 2:

      timestamps.png

      Figure 2. explicit timestamps and implicit timestamps

      The red arrows indicate the references from transaction to snapshot block, representing explicit timestamps (the creation time of transaction)

      The blue arrows indicate the references from snapshot block to transaction, representing implicit timestamps (the confirmation time of transaction) .

      Impact of Snapshot Chain Fork on Timestamp

      In structure, snapshot chain is actually a tree due to the possibility of fork.
      The newer the snapshot block is, the more probably it could be rolled back. Both types of timestamps will be impacted when rollback occurs.
      However, explicit timestamps will receive bigger impact, as explained below

      explicit_forked.png

      Figure 3. explicit timestamps with snapshot chain forks

      In Figure 3,
      the right-side snapshot block #N is rolled back and replaced by another forked snapshot block(left side).
      All transactions referring to this snapshot block must be rolled back as well, including the last transactions in account A and B.
      This is because the hash value of snapshot block was involved in signing, as part of the transaction data.
      The transactions have to be re-signed and re-sent by the original users since the previously referenced snapshot block is invalid.
      However, re-signing transaction is very expensive and therefore should be avoided in practice.
      An alternative strategy is to reference an older snapshot block, which means the "trunk" part of the snapshot chain. Unfortunately, this approach deviates from the purpose of explicit timestamp as transaction creation time and also is hard to tell which block is most appropriate.

      A conclusion can be reached now that except the benefit, explicit timestamps have problem.

      In contrast, implicit timestamps do not have this problem.

      implicit_forked.png

      Figure 4. implicit timestamps with snapshot chain forks

      Implicit timestamps are simply discarded along with the snapshot block during a rollback. In the example of Figure 4, the second transaction of account A and first transaction of account B will be re-marked as unconfirmed.
      A forked snapshot block #N will produce a set of new implicit timestamps, but not necessarily the same as those in the original block.
      Since implicit timestamp is reversed reference, transactions in DAG ledger do not have to change.
      Therefore, it is not necessary for users to re-sign their transactions any more, making fork resolution simple.

      Calculate Resource Consumption with Implicit Timestamps

      So, using implicit timestamps, is it still possible to accurately measure the resource usage of each account and calculate quota consumption? The answer is yes.

      As shown in Figure 2, if explicit timestamps are used as the original manner, in two consecutive time slots from snapshot #N-2 to snapshot #N, account A created 4 transactions, and account B created 2.
      With implicit timestamps, in one time slot between snapshot #N-1 and snapshot #N, 2 transactions were confirmed for account A, and 1 transaction for account B.
      In this way, according to the total amount of resources consumed by transactions confirmed in each account within fixed period, average resource consumption can still be accurately measured, thereby finding out whether a new transaction will exceed quota or not.

      Indeed, since the creation and confirmation of transaction is asynchronous in Vite, as well as transaction propagation and account state calculation consumes time, a small calculation gap may be caused by using transaction confirmation time.
      However, it is reasonable to reduce the gap by extending statistical cycle, in other words, calculating average resource consumption for a longer period of time.
      In the system of Vite, as long as the calculation scheme of resource consumption for different accounts are kept the same, this quota model based on confirmation time is feasible.

      Conclusions

      Based on above discussion, this proposal suggests to remove all explicit timestamps from Vite's ledger and keep only implicit timestamps.

      In this proposal, although the exact creation time of transaction is no longer saved on chain and as consequence losing some semantics depending on timestamp, in general the impact is very limited.
      Particularly, quota model and related resource consumption calculation can still be implemented with implicit timestamp, aka "confirmation time".

      This proposal can bring the following optimizations:

      • Remove two-way dependency between DAG ledger and snapshot chain, so they can be constructed asynchronously
      • Simplify rollback processing to increase system throughput
      • No need to re-sign transaction after rollback, and therefore simplifying client processing logic
      • Reduce the size of DAG ledger
      posted in Tech News & Updates
      Charles
      Charles
    • Libra Move硬核解读

      Facebook最近发表了联盟链项目Libra,其中的最大亮点是Move语言。
      下面我们从技术视角解读一下“Move: A Language With Programmable Resources”这篇白皮书,供大家参考。

      为了便于理解,我们拿比特币、以太坊和Libra来做一个对比。

      可编程货币、可编程应用与可编程资源

      其实,单从白皮书的标题,就可以大概看出三个项目在设计目标上的差异。

      比特币的目标是——可编程货币(Programmable Money),所以白皮书标题是“Bitcoin: A peer-to-peer electronic cash system”。

      以太坊的目标是——可编程的去中心化应用(Programmable dApps),在货币的基础上,扩展到更通用的领域。所以白皮书标题是:“Ethereum: a next generation smart contract and decentralized application platform”,黄皮书标题是:“Ethereum: A secure decentralized generalized transaction ledger”。

      而Libra的设计目标恰好介于二者中间——可编程资源(Programmable Resources),或者叫可编程资产。

      Facebook的技术路线比较务实,没有尝试更颠覆性的创新,而是把目光聚焦在“货币”和“通用应用”之间的“资产”,围绕解决实际问题,便于工程实现而展开。从这点来看,Libra既不是区块链3.0也不是4.0,而是区块链1.5。但这并不代表Libra的目标没有挑战,事实上,实现一个可以保证资产安全性,又能够提供足够灵活性的系统,比臆想出一个解决“不可能三角”的永动机还要困难。

      那么,“可编程货币”、“可编程应用”、“可编程资源”,这三者到底有什么不同呢?

      既然都是“可编程XX”句式,他们的主要区别就在于两点:1)对什么编程,2)如何编程。

      对什么编程

      对什么编程,是指系统所描述或者抽象的,到底是现实世界中的什么东西。

      比特币系统抽象的是“货币”,或者说是“账本”的概念。货币可以用一个数字来描述,也就是某一个账户的“余额”。用户可以通过“交易”,把一部分钱转给别人。当比特币网络接收到一笔交易的时候,每个节点都会检查交易是否合法,比如你花的是不是自己的钱,有没有足够的余额(比特币不允许透支)。当这些检查都成功后,节点会做一个简单的加减计算:在你的账户中扣减转账的数额,并在对方账户中加上同样的数量。因此,比特币唯一的功能就是记账,保证在账户彼此转账的过程中,货币的总量不会莫名其妙的增加或减少(不考虑挖矿奖励和黑洞地址等特例)。

      以太坊系统抽象的是“应用”,应用的种类包罗万象,比如游戏、借贷系统、电商系统、交易所等,这些都是应用。理论上讲,任何传统的计算机程序都可以移植到以太坊上。因此,以太坊中记录的是各种应用的内部数据(即“合约状态”),比如一个电商系统的库存、订单、结算信息等。这些信息无法用一个简单的数字来描述,必须允许用户定义非常复杂的数据结构,并且允许用户通过代码(智能合约),来对这些数据进行任意所需的操作。当然,这些应用也包含了“货币账本”。事实上,目前在以太坊上应用最广泛的正是此类应用(称为“ERC20智能合约”)。由于以太坊把这类应用看作是平台所能支持的多种应用中的一种,与其他类型的应用相比,并没有什么特别之处,所以也就没有针对此类应用提供更多的安全保护,只提供了类似ERC20这样的接口规范。一个在以太坊上新发行的“货币”,其转账逻辑的正确性完全由开发者负责。
      723e5e7f-712d-46dc-9bd4-88d08ffd7013-image.png

      在以太坊的存储结构中,ERC20代币的账本是“二级对象”,和ETH原生代币余额存储在不同的地方。例如上图所示,0x0,0x1和0x2是三个以太坊地址,其中,0x0和0x2是普通账户地址(External accounts),而0x1是一个合约地址(Contract accounts)。我们可以看到,每个账户都存储了一个ETH的余额,这个数据是顶级对象(First-Class Object)。在合约地址0x1中,还存储了一个智能合约代码MyCoin,它是一个ERC20代币应用。而MyCoin这个代币的整个账本,都存储在0x1的空间中,怎么修改都由0x1中的合约代码说了算。

      无论是有意还是无意,ERC20代币非常容易出现安全漏洞。也就是说,在以太坊系统中,原生代币ETH和用户发行的代币并不享有同样的安全级别。

      那么,能否不那么走极端,试图去抽象一些比简单数字更复杂的资产类型,而又不追求包罗万象的“通用性”呢?这正是Libra的出发点。Libra可以定义类似一篮子货币、金融衍生品等比货币更复杂的资产类型,以及如何对他们进行操作,这种资产被称为“资源”。Move通过限制对资源的操作来防止不恰当的修改,从而提高资产的安全性。无论资源的操作逻辑如何,都必须满足两个约束条件:

      • 稀缺性。即资产总量必须受控,不允许用户随意复制资源。通俗的说,就是允许银行印钞,但不允许用户用复印机来“制造”新钱;
      • 权限控制。简单的说就是资源的操作必须满足某种预先定义的规则。例如,张三只能花自己的钱,而不允许花李四的钱。

      6b220eb9-8529-4453-a593-92bdd05b79ba-image.png

      上图是Move的世界状态,与以太坊不同,它把所有资产都当作是“顶级资源”(First-Class Resources),无论是Libra的原生代币,还是用户自己发行的资产。任何一个“币种”的余额,都存储在用户地址对应的空间中,对其进行操作受到严格的限制。这种被称为资源(resource)的对象,在交易中只能被移动,而且只能移动一次,既不能被复制,也不能被消毁。甚至严格到在代码中赋值给一个局部变量,而后面没有使用它也不允许。

      这种资产的存储方式并非Libra独创,在此前的一些公链中已有应用,例如在Vite公链中,用户发行的币种余额也是顶级对象。不过Move可以支持更为复杂的资产类型,并对其提供额外的保护,这是Libra的主要贡献。

      如何编程

      我们再来看看三个项目如何通过编程来实现丰富的扩展性。

      在比特币中,定义了一种“比特币脚本”,用来描述花一笔钱的规则。比特币是基于UTXO模型的,只有满足了预先定义的脚本规则,才能花费一笔UTXO。通过比特币脚本,可以实现“多重签名”之类的复杂逻辑。比特币脚本是一种非常简单的基于栈的字节码,不支持循环之类的复杂结构,也不是图灵完备的。虽然利用它可以在比特币网络上发行新的货币(Colored Coins),但它的描述能力非常有限,对开发者也不友好,无法应用到更复杂的场景中。

      在以太坊中,定义了一种Solidity的编程语言,可以用来开发“智能合约”。智能合约代码可以编译成一种基于栈的字节码——EVM Code,在以太坊虚拟机EVM中执行。Solidity是一种高级语言,参考了C++、Python和Javascript的语法,是一种静态类型、图灵完备的语言,支持继承,允许用户自定义复杂的类型。Solidity更像是一种通用的编程语言,理论上可以用来开发任何类型的程序,它没有针对货币或者资产类型的数据,在语法和语义上做任何限制和保护。比如用它来开发一个新的代币合约,代币的余额通常声明为uint类型,如果编码时对余额增减逻辑的处理不够小心,就会使余额变量发生溢出,造成超额铸币、随意增发、下溢增持等严重错误。

      再来看Libra,它定义了一种新的编程语言Move,这种语言主要面向资产类数据,基于Libra所设定的“顶级资源”结构,主要设计目标是灵活性、安全性和可验证性。目前,Move高级语言的语法设计还没有完成,白皮书只给出了Move的中间语言(Move IR)和Move字节码定义。因此我们无法评估最终Move语言对开发者是否友好,但从Move IR的设计中,可以感受到它在安全性和可验证性方面的特点。

      Move的语法

      下面我们来简单介绍一下Move的语法。Move的基本封装单元是“模块”(Module),模块有点类似于以太坊中的“智能合约”,或者面向对象语言中的“类”。模块中可以定义“资源”(Resource)和“过程”(Procedure),类似于类中的“成员”(Member)和“方法”(Method)。所有部署在Libra上的模块都是全局的,通过类似于Java中的包名+类名的方式来引用,例如0x001.MyModule,0x001是一个Libra地址,MyModule是一个模块名。模块中的过程有public和private两种可见性,公有过程可以被其他模块调用,私有过程只能被同模块的过程调用。而模块中的资源都是私有的,只有通过公有过程才能被其他模块访问。而且,外部模块或者过程对本模块资源的修改受到严格的限制,唯一允许的操作就是“移动”(Move),不能随意对资源赋值。例如,Move中是不允许出现一个类似于MyCoin.setBalance()这样的接口,让其他用户有机会随意修改某个币种余额的。

      除了受限的资源类型,Move模块中也允许定义非受限的成员,被称为非受限类型(Unrestricted Type),包括原生类型(boolean、uint64、address、bytes)和非资源类的结构体(struct)。这些非受限类型就没有那么严格的访问限制,可以用来描述与资产无关的其他应用类数据。从这个角度来说,Move语言理论上应该具有和Solidity同样的描述能力,但由于实际的去中心化应用中,总会涉及到资产类的数据,而任何引用了资源类型的结构体也都是受限的,能够真正脱离Move语言严格限制的机会并不多。所以在实际使用Move语言开发的时候,程序员一定会有一种戴着镣铐跳舞的感觉,代码出现编译时和运行时失败的可能也更大。通俗的说,用Move写代码不会让你感觉“很爽”,这就是安全性和可验证性的代价。想想你用C语言自己控制内存的分配和释放时,虽然有一种“我是上帝”的感觉,但也会时刻忧虑缓冲区溢出、内存泄露等潜在风险;而用Java语言开发,虽然你不再能够为所欲为的控制内存,但也不用担心这些内存安全性问题了。自由还是安全,往往是不兼得的。

      在一个Libra的交易(Transaction)中,也可以嵌入一段Move代码,被称为交易脚本(Transaction Script)。这段代码不属于任何模块,是一次性执行的,不能再被其他代码调用。脚本中可以包含多个过程,通过main过程作为入口来执行,在其中也可以调用其他模块中的过程。这个设计有点类似比特币,而和以太坊完全不同。在以太坊中,一个交易本身是不能包含一段可执行代码的,只能部署新合约或者调用一个已部署的合约。我不太喜欢Libra的这个设计,由于任何Move代码都必须经过字节码验证器(Bytecode Verifier)的严格检查才能发布到链上,这种一次性代码的边际成本远远高于可复用的模块,会拖慢交易被确认的速度,降低系统的吞吐量。交易脚本并不是必须的,大部分现实场景都可以通过模块来覆盖,而且,它的存在还增加了Libra钱包的开发和使用难度,有机会的时候我会向Libra的开发团队提议取消这一设计。

      下面我来看一下白皮书中的示例代码片段,直观感受一下Move语言。请注意,这段代码是Move中间语言的(IR),未来Move高级语言肯定会提供一系列语法糖,使代码更加简洁优雅。

      public main(payee: address, amount: u64) {
          let coin: 0x0.Currency.Coin = 0x0.Currency.withdraw_from_sender(copy(amount)); // 从sender余额扣除amount个Coin
          0x0.Currency.deposit(copy(payee), move(coin)); // 将coin累加到payee的Coin余额中
      } 
      

      这段代码是一个交易脚本,只有一个main过程,实现的是一个叫做Coin的代币转账逻辑,接受一个目标地址和转账金额作为参数,预期执行结果是把amount数量的Coin,从交易发起者的账户转移给address地址。

      过程体只有两行,第2行声明了一个coin变量,类型是0x0.Currency.Coin。0x0是部署Currency模块的Libra地址,Coin是一个资源类型,属于Currency模块。这是一个赋值语句,coin的值是调用0x0.Currency模块的withdraw_from_sender()过程获得的。这个过程被执行的时候,会从sender的余额中扣除amount数量的Coin;

      第3行调用0x0.Currency模块的另一个过程deposit(),把上面取得的coin这个资源累加到payee地址的余额中。

      这段代码的特别之处在于,每个取变量右值的地方都有一个copy()或者move()。这就是Move语言最有特点的地方,它借用了C++ 11和Rust的move语义,要求在读取变量的值时,必须指定取值的方式,要么是copy,要么是move。用copy的方式取值,相当于把变量克隆出一份,原来的变量值不变,还可以继续使用;而用move的方式取值,原变量的引用,或者说所有权转移给了新的变量,原变量就失效了。C++中引入move语义的目的,是为了减少不必要的对象拷贝,以及临时变量的构造和析构,提高代码执行效率;而Move语言的目的,是为了通过更严格的语法和语义限制,来提高“资源”变量的安全性。在Move中,资源类型只能move,不能copy,而且只能move一次。

      假如程序员的咖啡喝完了,状态很差,在写这段代码时出了一个bug,把第3行的move(coin)写成了copy(coin),会发生什么呢?

      public main(payee: address, amount: u64) {
          let coin: 0x0.Currency.Coin = 0x0.Currency.withdraw_from_sender(copy(amount));
          0x0.Currency.deposit(copy(payee), copy(coin)); // move(coin) -> copy(coin)
      } 
      

      由于coin是资源类型,不允许copy,Move的字节码验证器会在第3行报错。

      再假如程序员写代码时,他的猫刚好从键盘上走过,踩到了Command和D键,于是,第3行代码重复出现了两次(第4行),又会发生什么呢?

      public main(payee: address, amount: u64) {
          let coin: 0x0.Currency.Coin = 0x0.Currency.withdraw_from_sender(copy(amount));
          0x0.Currency.deposit(copy(payee), move(coin));
          0x0.Currency.deposit(copy(payee), move(coin)); // Cat did it!
      }
      

      这一次bug更严重,会导致来源地址只扣除了一次金额,而目标地址却增加了双倍的金额。在这个场景下Move的静态检查就真正发挥作用了,由于第一次coin变量经过move取值后已经不可用,那么第二次move(coin)就会引起字节码验证器报错。

      在以太坊中就没有那么幸运了,比如下面的代码:

      pragma solidity >=0.5.0 <0.7.0;
       
      contract Coin {
          mapping (address => uint) public balances;
          event Sent(address from, address to, uint amount);
       
          function send(address receiver, uint amount) public {
              require(amount <= balances[msg.sender], "Insufficient balance.");
              balances[msg.sender] -= amount;
              balances[receiver] += amount;
              balances[receiver] += amount; // Cat did it again!
              emit Sent(msg.sender, receiver, amount);
          }
          …………
      }
      

      以太坊是无法找到代码中多出来的一行balances[receiver] += amount;的(第11行), 每次send()被调用,Coin这个代币的总量都会凭空多出amount个。

      Move字节码验证器

      读到这里,大家应该能够意识到,Move中最核心的组件就是字节码验证器。让我们来看看它是如何对一段Move字节码进行验证的,验证过程通常包括以下步骤:

      • 控制流图构建:这一步会将字节码分解成代码块,并构建它们之间的跳转关系;
      • 栈高度检查:这一步主要是防止栈的越界访问;
      • 类型检查:这一步会通过一个“类型栈”模型来对代码进行类型检查;
      • 资源检查:这一步主要针对资源类型进行安全性检查,防止资源被复制或消毁,并确保-资源变量被后续代码所使用。上文举的例子中的bug,就是在这一步被发现的;
      • 引用检查:这一步参考了Rust的类型系统,对引用进行静态和动态检查。检查是在字节码级别进行的,确保没有悬空的引用(指向未分配内存的引用),以及引用的读写权限是安全的;
      • 全局状态链接:这一步主要检查结构体类型和过程的签名,确保模块的私有过程不会被调用,以及调用的参数列表符合过程的声明。

      Move虚拟机

      Move的虚拟机,和EVM相似的地方比较多。它也是一个基于栈的虚拟机。指令集包含6类指令:数据加载和移动、栈操作/代数运算/逻辑运算、模块成员及资源操作、引用相关操作、控制流操作、区块链相关操作。

      与EVM类似,每一条指令都会计算一个gas,耗光gas后代码会停机。Move中,一个交易的代码执行符合原子性,要么全部执行成功,要么一条也不执行。有趣的是,虽然Libra是一个标准的区块链账本结构,所有交易都是全局有序的,但Move语言本身支持并行执行,这意味着,也许以后Libra可以改进成类似Vite的DAG账本,提高交易并行处理的效率。

      未来工作

      当前Move还处于一个比较早起的开发阶段,后续工作包括:

      • 实现Libra链的基本功能,包括账户、Libra代币、准备金管理、验证节点的加入和移除、交易手续费管理、冷钱包等;
      • 新的语言功能,包括范型、容器、事件、合约升级等;
      • 提高开发者体验,包括设计一个人性化的高级语言等;
      • 形式化建模和验证工具;
      • 支持第三方Move模块。

      本文如有错误,请读者不吝指正。想获取更多的细节,可以阅读白皮书或开源代码。
      顺便说一句,这篇白皮书写的相当不错,概念准确,而且通俗易懂,没有使用特别形式化的描述或者复杂的数学知识,一个对区块链技术有所了解的读者完全可以一次读懂。这也从侧面反映出Facebook团队专业和务实的风格。


      本文作者:刘春明,Vite Labs创始人,区块链技术专家,中国区块链应用研究中心常务理事。转载请注明出处。

      posted in 技术讨论
      Charles
      Charles
    • 去中心化交易所的演进

      石器时代——场外交易

      自从以比特币为代表的数字加密资产诞生以来,人们就有交易这些资产的需求。最初,这些需求主要通过社交媒体来满足,人们在论坛上发帖,或者在聊天群里发布信息,寻找可能的交易对手。这种交易方式通常也被称为场外交易(OTC, Over The Counter)。

      场外交易的主要问题是效率低下、违约风险高、缺乏有效的价格发现机制。随着区块链行业的发展,数字资产的种类越来越多,交易者的数量和他们对交易频次的要求也越来越高,场外交易已经无法满足他们的需求。在这个背景下,集中的交易场所——交易所(Exchange)随之诞生。

      工业时代——交易所

      交易所为用户提供一套交易工具以及相关的服务,将所有交易者集中起来,通过计算机程序来快速撮合买单和卖单,并通过锁定流动性为买卖双方提供履约担保。通常,用户必须将某种数字资产预先“充值”到交易所,通过执行“下单”操作,约定一个可接受的“汇率”,并将一定数量的资产锁定在系统中。系统会自动找到那些交换方向相反,并且在汇率上能够达成一致的订单,完成交易对手之间的资产结算,这个过程通常叫做“撮合”(match)。由于在撮合完成之前,等待交易的资产流动性会被交易所锁定,买家和卖家都无法动用,这就保证了交易完成后双方的可靠履约。

      安全——中心化交易所的基因缺陷

      交易所的诞生,极大提高了数字资产交易的效率,消除了违约风险,也提供了一个高效的价格发现机制。然而,这些体验的提升并不是没有代价的。

      首先,为了确保可靠履约,用户必须将资产托管到交易所。交易所实际控制着数量巨大的数字资产,产生了严重的安全隐患。历史上多次发生的交易所资产被盗事件,极大的动摇了用户对交易所安全性的信心。而运营交易所的机构,既面临挪用用户资产获利的诱惑,又面临内部安全管理的挑战。在很多“被盗”事件中,你甚至无法分辨这些被盗的资产,是真的被“黑客”洗劫,还是被交易所挪用,或者被交易所内部员工窃取。

      资产被盗虽然只是小概率事件,但交易所为了控制安全风险,或者为了挪用资产,通常都会对用户“提现”环节进行种种限制。如果你使用过任何一个交易所,都会发现,“充值”环节总是免费并且极为便利的,而在“提现”的时候,就会有最大数量、到账时间等种种限制,有时候还必须通过人工审核环节。

      垄断——中心化交易所的原罪

      此外,从商业的视角来看,中心化运营的交易所,实际上是以公司的组织形式来参与市场竞争,他们必须基于商业利益来选择交易标的。一旦某个交易所形成垄断地位,他们就会充分利用垄断优势,提高准入门槛,设置有利于自己的规则,向项目方收取高额的“上币费”,从而达到自身利润的最大化。这种垄断威胁了数字资产市场的公平竞争,提高了交易者的风险和成本。很多优质项目是以开源社区的方式来组织的,“项目方”并没有足够的融资来承担这些头部交易所的“上币费”;与之相对,有很多区块链项目将融资的一半甚至一多半交给交易所,用余下的资金与交易所合作进行市场操纵(有时候称其为“市值管理”),这类项目往往没有足够的资源用于实际的项目开发,缺乏价值支撑,投资风险非常高。这种垄断交易所与项目方合谋向投资者转嫁风险,收割投资者的行为,造成了“劣币驱逐良币”的恶性循环,加剧了区块链市场的泡沫化,威胁了整个行业的健康发展。

      因此,作为一个加密资产投资者,对中心化交易所的态度可以用“爱恨交织”来形容。总结起来,用户的痛点主要来自于以下几个方面:

      1)资产的安全性无法保证;

      2)某些环节的体验较差,尤其是注册、提现等环节;

      3)只能在交易所选定的标的范围内交易,无法满足多样性需求;

      4)治理机制高度不透明。无论是规则制定、收费标准还是撮合逻辑,都是由交易所集中控制。

      信息时代——去中心化交易所

      在这个背景下,一种被称为“去中心化交易所”(DEX, Decentralized Exchange)的新型交易所逐渐吸引了人们的目光,去中心化交易所的一些特性,有效弥补了传统中心化交易所的先天缺陷。

      在谈论去中心化交易所之前,我们应该首先明确“去中心化”的实际含义。在我看来,去中心化交易所与中心化交易所的区别,主要体现在“技术”和“治理”两个维度。

      从技术维度来看,去中心化交易所是一个建立在区块链之上的去中心化应用(dApp),通过智能合约,发挥区块链“无需信任”(trustless)、不可篡改的特点;

      从治理维度来看,去中心化交易所是一个开放的、社区驱动的、权利和义务高度分散的去中心化组织。

      事实上,目前的很多“去中心化交易所”项目,并没有在这两方面同时做到“去中心化”。要么是采用中心化技术,在治理层面鼓励社区参与;要么是只采用了去中心化技术,商业模式和运营仍然是中心化的。

      那么,一个真正的、理想的去中心化交易所,到底应该是什么样子,它又能给用户带来什么具体的好处呢?

      上链与跨链——技术视角下的“去中心化”

      交易所的系统,主要分为“资产管理”和“订单撮合引擎”两个模块,前者存储账户数据,负责资产托管和交易结算;后者存储订单簿数据,执行订单的撮合计算。

      去中心化的技术方案,是将这两个模块都用链上的智能合约来实现。这样,用户的资产托管到智能合约中,没有任何个人或组织可以轻易盗取或挪用,用户提现也不受任何人为的限制。而订单的撮合逻辑也受智能合约限制,使“抢先交易”(front running)这类作弊行为无法得逞。

      得益于区块链系统自身的特性,去中心化交易所可以保证极高的可用性。几乎在任何时候,总能在线上找到可用的节点提供服务,从而保证交易撮合和资产结算永不中断。在最坏情况下,用户还可以选择自己运行一个区块链的节点,来完成中断的交易,并将资产安全的转移到自己的钱包中。

      实现这种完全去中心化的技术方案,要求交易所底层的公链平台有足够好的性能,而且智能合约执行的成本足够低。目前,由于大部分公链平台无法同时满足这两点,因此,很多去中心化交易所只能作出妥协,采用一种二层协议(Layer 2),只将低频的资产管理模块部署到链上,而将高频的订单撮合模块放在链下。这种方案虽然牺牲了订单撮合逻辑的去中心化,提高了去中心化交易所开发和运维成本,但至少解决了最为迫切的托管资产安全性问题,也不失为一种可行的折衷方案。

      最后,支持多种不同公链平台上的资产之间进行交易,或者说具有“跨链”能力,也是去中心化交易所的一个重要技术目标。

      所有权、运营权、收益权——治理视角下的“去中心化”

      从治理的视角来看,交易所是中心化还是去中心化的,主要体现在它的所有权、经营权和收益权是归属于某一个特定的商业组织,还是归属于一个开放的社区。

      在中心化交易所的治理模式中,某个中心化组织有权决定交易何时开放和关闭,有权修改交易规则;这个组织有权决定允许哪些用户来交易,以及哪些数字资产可供交易;交易所产生的收益也归属于这个组织。

      而在去中心化交易所的治理模式中,交易所的所有权归属于社区,所有的规则变更必须通过投票或者分叉的形式来获得共识;交易所向社区用户开放,选择交易标的、制定手续费等运营权也归属于社区;同样,交易所所产生的收益也全部归属于社区。

      目前,无论是中心化交易所,还是去中心化交易所,通常都会对交易所的某种权益代币化,发行一种交易所的“平台币”。有趣的是,通过交易所平台币的经济模型,我们可以清晰的分辨出它的治理模式。

      如果平台币只能用于抵扣交易手续费,某种意义上来说相当于交易所的“优惠券”或“会员卡”,持币用户仅仅作为消费者享受优惠服务,那么,基于这种平台币经济模型的交易所,其治理模式也是中心化的;

      相反,如果交易所的平台币大部分由社区持有,而持币用户拥有交易所重大决策的投票权,并且可以获得交易所的利润作为分红,那么这个交易所的治理模式就是去中心化的;

      由于去中心化治理的开放性,任何用户,或者任何用户想交易的资产,都无法被某个垄断组织出于自身利益考虑而挡在门外。不同的交易标的可以在统一的市场规则下自由竞争,优胜劣汰。任何个人或组织都无法轻易修改游戏规则,个体的退出也不会对交易所产生重大影响。

      同时,开放性还可以带来更好的流动性,在统一的协议框架下,所有交易者共享同一个市场的深度。

      最后,交易所收益权的社区化,为整个交易生态提供了一个有效的激励,最终会降低所有交易者的平均成本。

      进化之路——去中心化交易所演进模型

      如果按照以上两个维度,按照交易所的去中心化阶段绘制成图形,如下图所示。我们会发现,去中心化交易所演进的起点和终点都是相同的,演进的路径都是从左下角开始,选择不同的进化方向,逐步向右上角推进。
      b7c0462d-84a0-47a8-97c2-265119e17c05-image.png

      问题与挑战

      当前阶段,去中心化交易所的用户体验与中心化交易所还存在相当的差距。最大的问题体现在撮合速度慢、交易成本高和流动性不足三个方面。任何用户都无法接受每笔订单需要等待十几秒甚至几十秒才能成交,或者每下一单,甚至撤单都需要支付高额的手续费。用户更无法接受一个数字资产想卖的时候卖不掉,想买的时候买不到。

      在技术层面,去中心化交易所需要解决撮合的性能和经济性问题,这个挑战主要依靠基础设施,也就是底层公链平台的进化来解决。基于这个原因,很多去中心化交易所项目甚至选择自行开发一个公链。

      另外,由于不同的公链在协议、账本和共识算法上的巨大差异,解决资产的跨链流动性也是一个巨大的挑战。虽然目前出现了很多所谓的“跨链”方案,但都无法完美的解决问题。

      目前,去中心化交易所比较现实的选择是基于“公证人”(或者称为“网关”)的跨链方案。这一方案的弱点在于过于依赖链下信任,无法实现去中心化。即使引入不同公证人之间彼此监督、互相竞争、形成某种共识的机制,仍然存在公证人合谋作恶的可能。

      而“原子交换”这类“方案,本质上是不同公链的资产在两个用户之间的对等交换,而不是资产跨越公链的单向转移。例如,当你想把代币从比特币网络转移到以太坊网络上时,必须找到一个想把同样数量的代币反向转移的交易对手,他拿走了你在比特币网络上的代币,而你拿走了他在以太坊网络上的代币。显然,原子交换更适用于OTC交易,无法满足交易所这种集中撮合的场景。

      还有一类“同构跨链”的解决方案,例如Cosmos或者Polkadot,通过设计某种顶层协议,来提高符合该协议的“链”之间的互操作性。这类方案的问题在于无法使现存的公链之间实现“跨链”,除非比特币、以太坊等主流公链都能够兼容这种顶层协议。这一点短期很难实现,因为“跨链”的难题恰恰在于“跨协议”交互,而公链之间的竞争本质上正是协议之间的竞争。所以,试图通过统一协议来完成“跨链”的目标,显然不会是一件容易的事。

      在治理层面,去中心化交易所需要解决流动性激励问题,这主要依靠合理的治理模型和激励模型。这个问题往往被人们所忽略,其实它才是很多去中心化交易所最大的短板。一个中心化治理的交易所,甚至不应该被称为“去中心化”交易所。但治理的去中心化, 远比技术的去中心化难度更高。无论是经济模型的设计、社区的建立,还是交易生态的发展,都是一个漫长的过程。在这个过程中,交易用户、传统交易所、项目方、做市商、加密资产投资人等,整个生态中的不同角色通过持续的竞争和合作,最终达到利益的平衡。因此,一个真正的去中心化交易所,应该着眼于建立一个完整的交易生态,把原本分散在不同“中心”的流动性汇集在一起,而不是试图成为一个新的“中心”,这样才符合“去中心化”的真正内涵。

      进化的终点——完全去中心化交易所

      随着公链技术的进步和治理模式的迭代,去中心化交易所已经逐步具备了商业应用的条件。用户正在期待着一个进化到完全形态,从技术到治理都完全体现去中心化的新一代交易所的诞生。

      这个交易所应该构建在一条高性能、低成本的公链之上,可以在链上完成订单的撮合,并且具有跨链能力。

      同时,这个交易所应该有一个充分开放的生态,由社区所有、社区运营、社区受益。它的治理模型应该能够充分平衡所有生态参与者的利益,无论是交易用户、运营者、流动性提供者还是项目方,都可以从这个生态中找到自己的位置。

      蓝图已经勾画完成,是时候做一些事把它变成现实了。按照理想中去中心化交易所的终极形态,我们打造了一个商业应用级别的去中心化交易所——ViteX。我不打算在这篇文章中讲述太多ViteX的细节,只给好奇的读者提供一些线索:

      • ViteX是一个体验接近传统交易所的去中心化交易所,资产由用户自己通过私钥控制,在交易前不需要复杂的注册和KYC流程。

      • ViteX是一个开放的平台,任何人都可以利用它“开自己的去中心化交易所”,就像在淘宝开店一样简单。

      • ViteX运营的核心角色是“交易所运营商”,他们类似淘宝的“商家”。这些运营商将来自传统交易所品牌持有者、区块链项目方、Token Fund,或者社区KOL等。运营商有自己的交易专区(类似淘宝的“店铺”),保留自己的品牌,拥有开通交易对、设置手续费等运营权。运营商的品牌和信用将成为他们在竞争中取胜的关键因素。例如,上币标准和尽职调查更为严格的运营商,可能更容易被用户认可。

      • ViteX是一组运营去中心化交易所所需要的基础设施,包括智能合约、网站、API、SDK等。运营商也可以基于ViteX API来搭建自己的交易网站,或者和自己的交易系统打通。

      • ViteX将基于平台币VX来完成激励和去中心化治理。VX代币没有明显的利益相关方,也没有融资和预挖。获取VX的方式包括:完成一笔交易、开通新的交易对、为ViteX智能合约提供公链资源的配额、为ViteX提供流动性、邀请新的用户等。这些规则将被写入智能合约,成为协议的一部分。

      • ViteX平台归属于VX持有者,任何协议和规则的修改都将通过VX投票来决策。同时,ViteX平台产生的利润,也将100%分配给VX代币的持有者。

      • ViteX是构建在Vite公链之上的,Vite公链是一个基于DAG账本、支持智能合约的异步高性能公链平台,秒级确认,无手续费,支持多币种及跨链。Vite公链就是为DEX这一类复杂的dApp而设计的,可以很好的满足链上撮合的性能和成本要求。

      希望我们的探索和实践,可以加速去中心化交易所的演进速度,催生更多的商业机会,并让加密资产交易生态和整个区块链行业走向繁荣。

      (本文作者:刘春明,欢迎转载。)

      posted in 公告
      Charles
      Charles
    • VEP-5: 移除作为时间戳的快照块哈希显式引用

      VEP-5: 移除作为时间戳的快照块哈希显式引用

      背景

      在Vite白皮书1.0版中,章节6.2.2(资源量化)提到:
      由于快照链相当于一个全局时钟,我们可以利用它准确的量化一个账户的资源使用情况。在每个交易中,必须引用一个快照块的哈希,将快照块的高度作为该交易的时间戳。因此可以根据两个交易时间戳的差,来判断这两个交易之间是否间隔足够长的时间。

      explicit_timestamp.png

      如上图所示,每个交易都包含一个快照块哈希的显式引用,作为交易创建时间的证明。这个时间戳的主要用途是计算一个账户的资源消耗是否超出配额。

      除了这个时间戳之外,系统中还存在另一个"隐式"的时间戳,也就是一个快照块中所记录的每个账户的最新交易哈希,代表的是一个交易的"确认时间"。

      由于这两种时间戳的存在,DAG账本中的交易和快照链之间存在双向依赖关系,如下图所示:

      timestamps.png

      红色的箭头表示交易对快照链的引用,也就是显式时间戳(交易的创建时间);蓝色的箭头表示快照块对账本中交易的引用,也就是隐式时间戳(交易的确认时间)。

      快照链分叉对时间戳的影响

      由于快照链存在分叉的可能,实际上是一个树状结构,快照块的高度越大,被回滚的概率越高。当快照块被回滚时,这两种时间戳都会受到影响。
      其中,显式时间戳受到的影响更大,如下图所示:

      explicit_forked.png

      快照链末尾右侧的快照块被回滚,为另一个分叉的快照块所取代。所有引用该快照块的交易都将作废,包括图中A和B账户的最后一个交易。
      这是由于这些交易在签名时使用了被回滚的快照块哈希,在更新这个字段后,必须由持有私钥的用户重新签名并发布新的交易。
      重新签名交易是一个非常昂贵的操作,在实际应用中应该尽量避免。
      一个比较保守的策略是尽量引用比较旧的快照块,也就是快照链的“树干”的部分。这种做法又失去了显式时间戳作为交易创建时间的现实意义。
      因此,显式时间戳的存在非常鸡肋。

      与此相对,隐式时间戳在快照块回滚时就没有同样的问题,如下图所示:

      implicit_forked.png

      一个快照块被回滚,其中的隐式时间戳与这个快照块一起被废弃,A账户的第二个交易变成未确认状态。另一个分叉中新的快照块仍然会包含一组隐式时间戳,只是与原分叉中的记录未必相同。
      由于隐式时间戳是反向引用,DAG账本中的交易没有发生改变,因此,时间戳的更新只与SBP有关,用户无需重新签名交易,分叉处理逻辑相对简单。

      采用隐式时间戳计算资源消耗

      那么,使用隐式时间戳,是否仍然可以准确量化每个账户的资源使用并计算配额消耗呢?答案是肯定的。

      如图2所示,如果按照原来的方式,使用显式时间戳计算,在快照N-2到快照N的2个时间单位内,账户A创建了4个交易,账户B创建了2个交易;
      而采用隐式时间戳计算,在快照N-1到快照N的1个时间单位内,账户A被确认了2个交易,账户B被确认了1个交易。
      这样,按照每个账户在固定时间间隔内被确认的交易所消耗的资源总量,仍然可以准确量化该账户近期的平均资源消耗,从而判断出该账户新增的交易是否超出其配额。

      当然,由于交易的创建和确认是异步的,交易在网络上传输,以及账户的状态计算都会消耗一定时间,用交易确认时间来判断配额可能会存在一定误差。
      我们可以通过提高统计的时间间隔数,也就是统计更长时间的平均资源消耗,来减小这种误差的影响。
      在Vite系统中,只要在同一时间段内,针对不同账户的资源消耗统计是公平的,就足以保证配额模型的正常工作。

      结论

      基于以上讨论,本提案建议将Vite账本中所有显式时间戳移除,只保留隐式时间戳。

      这样,虽然链上数据中不再保存交易的创建时间,会损失一些依赖该时间戳的语义,但这种影响非常有限。尤其是,资源消耗计算和配额模型仍然可以使用"确认时间"这个隐式时间戳来实现。

      而这个优化却可以带来如下收益:

      • 去除DAG账本和快照链结构之间的双向依赖,使DAG账本和快照链可以异步构建;
      • 简化了快照块的回滚处理逻辑,有助于提高系统的吞吐量;
      • 时间戳失效后,无需重新签名交易,简化了客户端处理逻辑;
      • 减少了DAG账本的存储空间。
      posted in 技术讨论
      Charles
      Charles
    • RE: 去中心化交易所的演进

      @qiangqiang666 这个问题非常棒,我也分享一下我的观点:
      1)去中心化交易所应该是一个完整的生态,需要传统的中心化交易所运营者参与其中,将他们既有的品牌价值和流量输入到新的生态中,共享更大的用户群体和流动性,形成更广泛的共识。任何类型的交易所,通过某种方式来获取用户和提高流动性都是至关重要的,但方式并不唯一。
      2)去中心化交易所是谁开发的并不重要,重要的是它的治理模型。也就是说,交易所是谁的,谁说了算,收益归谁,这些决定了它是哪种类型的交易所。
      3)传统的中心化交易所如果沿用中心化的运营思路,开发新产品的目的是为了加强自身的垄断优势,修筑“护城河”,将竞争对手排除在外,那么,这个新产品即使应用了区块链和智能合约技术,本质上仍然是“中心化”交易所。这有点像传统互联网公司基于区块链技术开发联盟链或者私有链,不具备公有链的“去中心化”特性。
      4)去中心化交易所的竞争和其他区块链项目一样,依然是“共识的竞争”。比特币就是一个很好的例子,它并不是某个大公司孵化出来的,但它足够去中心化,因此更容易凝聚共识。

      posted in 公告
      Charles
      Charles
    • RE: Questions regarding the upcoming Vite DEX

      The design of Vite DEX is open and anyone can share the order pool through DEX API, but DEX API is not available in the first version.
      We are working with existing stable coin issuers and USDO (https://usdo.com/) may be the first stable coin to be issued on Vite.

      posted in Questions
      Charles
      Charles
    • RE: VITE block Explorer

      good idea! we will implement it in coming versions.

      posted in Support
      Charles
      Charles
    • RE: < SBP提案> 关于vite前25垄断问题,对作恶作弊节点团队进行公示指引。

      这个问题我们也讨论过很久。不过目前还没有有效的治理机制能确保公平。即使通过公示,也没办法防范借用他人名义运行多个节点。另外,如果Vite Labs作为仲裁方,对节点进行尽调,并惩罚作弊行为,这样又违背了去中心化的治理原则,而且我们也很难获取作弊证据。EOS的治理措施目前来看也无法有效防止垄断。大家有什么好的建议可以提出来,社区一起讨论。

      posted in 超级节点
      Charles
      Charles
    • RE: Snap Secure is Developing a Coin Faucet!

      impressive👍

      posted in Community Collaborations
      Charles
      Charles

    Latest posts made by Charles

    • RE: Vite Developer Committee

      DECLARATION OF CANDIDACY

      Name:

      Charles Liu

      Discord username:

      Chunming Liu#5035

      Telegram username:

      @ghostself

      How long you've been with Vite community:

      Since the beginning of Vite

      Why you are interested in becoming a member of the Vite Developer Committee:

      As the founder of the project, I have the responsibility to keep contributing.

      What contribution you will be able to bring to this committee:

      Ideas, codes, technical solutions.

      Other information about you (Optional, such as example ideas of new projects to build on Vite, or your past involvement in tech):

      The original idea proposer, white paper author.

      posted in Tech
      Charles
      Charles
    • RE: 从0到1开发一款基于Vite公有链的DApp-开发指南

      一篇很棒的文章,非常感谢!

      posted in 技术讨论
      Charles
      Charles
    • Libra Move硬核解读

      Facebook最近发表了联盟链项目Libra,其中的最大亮点是Move语言。
      下面我们从技术视角解读一下“Move: A Language With Programmable Resources”这篇白皮书,供大家参考。

      为了便于理解,我们拿比特币、以太坊和Libra来做一个对比。

      可编程货币、可编程应用与可编程资源

      其实,单从白皮书的标题,就可以大概看出三个项目在设计目标上的差异。

      比特币的目标是——可编程货币(Programmable Money),所以白皮书标题是“Bitcoin: A peer-to-peer electronic cash system”。

      以太坊的目标是——可编程的去中心化应用(Programmable dApps),在货币的基础上,扩展到更通用的领域。所以白皮书标题是:“Ethereum: a next generation smart contract and decentralized application platform”,黄皮书标题是:“Ethereum: A secure decentralized generalized transaction ledger”。

      而Libra的设计目标恰好介于二者中间——可编程资源(Programmable Resources),或者叫可编程资产。

      Facebook的技术路线比较务实,没有尝试更颠覆性的创新,而是把目光聚焦在“货币”和“通用应用”之间的“资产”,围绕解决实际问题,便于工程实现而展开。从这点来看,Libra既不是区块链3.0也不是4.0,而是区块链1.5。但这并不代表Libra的目标没有挑战,事实上,实现一个可以保证资产安全性,又能够提供足够灵活性的系统,比臆想出一个解决“不可能三角”的永动机还要困难。

      那么,“可编程货币”、“可编程应用”、“可编程资源”,这三者到底有什么不同呢?

      既然都是“可编程XX”句式,他们的主要区别就在于两点:1)对什么编程,2)如何编程。

      对什么编程

      对什么编程,是指系统所描述或者抽象的,到底是现实世界中的什么东西。

      比特币系统抽象的是“货币”,或者说是“账本”的概念。货币可以用一个数字来描述,也就是某一个账户的“余额”。用户可以通过“交易”,把一部分钱转给别人。当比特币网络接收到一笔交易的时候,每个节点都会检查交易是否合法,比如你花的是不是自己的钱,有没有足够的余额(比特币不允许透支)。当这些检查都成功后,节点会做一个简单的加减计算:在你的账户中扣减转账的数额,并在对方账户中加上同样的数量。因此,比特币唯一的功能就是记账,保证在账户彼此转账的过程中,货币的总量不会莫名其妙的增加或减少(不考虑挖矿奖励和黑洞地址等特例)。

      以太坊系统抽象的是“应用”,应用的种类包罗万象,比如游戏、借贷系统、电商系统、交易所等,这些都是应用。理论上讲,任何传统的计算机程序都可以移植到以太坊上。因此,以太坊中记录的是各种应用的内部数据(即“合约状态”),比如一个电商系统的库存、订单、结算信息等。这些信息无法用一个简单的数字来描述,必须允许用户定义非常复杂的数据结构,并且允许用户通过代码(智能合约),来对这些数据进行任意所需的操作。当然,这些应用也包含了“货币账本”。事实上,目前在以太坊上应用最广泛的正是此类应用(称为“ERC20智能合约”)。由于以太坊把这类应用看作是平台所能支持的多种应用中的一种,与其他类型的应用相比,并没有什么特别之处,所以也就没有针对此类应用提供更多的安全保护,只提供了类似ERC20这样的接口规范。一个在以太坊上新发行的“货币”,其转账逻辑的正确性完全由开发者负责。
      723e5e7f-712d-46dc-9bd4-88d08ffd7013-image.png

      在以太坊的存储结构中,ERC20代币的账本是“二级对象”,和ETH原生代币余额存储在不同的地方。例如上图所示,0x0,0x1和0x2是三个以太坊地址,其中,0x0和0x2是普通账户地址(External accounts),而0x1是一个合约地址(Contract accounts)。我们可以看到,每个账户都存储了一个ETH的余额,这个数据是顶级对象(First-Class Object)。在合约地址0x1中,还存储了一个智能合约代码MyCoin,它是一个ERC20代币应用。而MyCoin这个代币的整个账本,都存储在0x1的空间中,怎么修改都由0x1中的合约代码说了算。

      无论是有意还是无意,ERC20代币非常容易出现安全漏洞。也就是说,在以太坊系统中,原生代币ETH和用户发行的代币并不享有同样的安全级别。

      那么,能否不那么走极端,试图去抽象一些比简单数字更复杂的资产类型,而又不追求包罗万象的“通用性”呢?这正是Libra的出发点。Libra可以定义类似一篮子货币、金融衍生品等比货币更复杂的资产类型,以及如何对他们进行操作,这种资产被称为“资源”。Move通过限制对资源的操作来防止不恰当的修改,从而提高资产的安全性。无论资源的操作逻辑如何,都必须满足两个约束条件:

      • 稀缺性。即资产总量必须受控,不允许用户随意复制资源。通俗的说,就是允许银行印钞,但不允许用户用复印机来“制造”新钱;
      • 权限控制。简单的说就是资源的操作必须满足某种预先定义的规则。例如,张三只能花自己的钱,而不允许花李四的钱。

      6b220eb9-8529-4453-a593-92bdd05b79ba-image.png

      上图是Move的世界状态,与以太坊不同,它把所有资产都当作是“顶级资源”(First-Class Resources),无论是Libra的原生代币,还是用户自己发行的资产。任何一个“币种”的余额,都存储在用户地址对应的空间中,对其进行操作受到严格的限制。这种被称为资源(resource)的对象,在交易中只能被移动,而且只能移动一次,既不能被复制,也不能被消毁。甚至严格到在代码中赋值给一个局部变量,而后面没有使用它也不允许。

      这种资产的存储方式并非Libra独创,在此前的一些公链中已有应用,例如在Vite公链中,用户发行的币种余额也是顶级对象。不过Move可以支持更为复杂的资产类型,并对其提供额外的保护,这是Libra的主要贡献。

      如何编程

      我们再来看看三个项目如何通过编程来实现丰富的扩展性。

      在比特币中,定义了一种“比特币脚本”,用来描述花一笔钱的规则。比特币是基于UTXO模型的,只有满足了预先定义的脚本规则,才能花费一笔UTXO。通过比特币脚本,可以实现“多重签名”之类的复杂逻辑。比特币脚本是一种非常简单的基于栈的字节码,不支持循环之类的复杂结构,也不是图灵完备的。虽然利用它可以在比特币网络上发行新的货币(Colored Coins),但它的描述能力非常有限,对开发者也不友好,无法应用到更复杂的场景中。

      在以太坊中,定义了一种Solidity的编程语言,可以用来开发“智能合约”。智能合约代码可以编译成一种基于栈的字节码——EVM Code,在以太坊虚拟机EVM中执行。Solidity是一种高级语言,参考了C++、Python和Javascript的语法,是一种静态类型、图灵完备的语言,支持继承,允许用户自定义复杂的类型。Solidity更像是一种通用的编程语言,理论上可以用来开发任何类型的程序,它没有针对货币或者资产类型的数据,在语法和语义上做任何限制和保护。比如用它来开发一个新的代币合约,代币的余额通常声明为uint类型,如果编码时对余额增减逻辑的处理不够小心,就会使余额变量发生溢出,造成超额铸币、随意增发、下溢增持等严重错误。

      再来看Libra,它定义了一种新的编程语言Move,这种语言主要面向资产类数据,基于Libra所设定的“顶级资源”结构,主要设计目标是灵活性、安全性和可验证性。目前,Move高级语言的语法设计还没有完成,白皮书只给出了Move的中间语言(Move IR)和Move字节码定义。因此我们无法评估最终Move语言对开发者是否友好,但从Move IR的设计中,可以感受到它在安全性和可验证性方面的特点。

      Move的语法

      下面我们来简单介绍一下Move的语法。Move的基本封装单元是“模块”(Module),模块有点类似于以太坊中的“智能合约”,或者面向对象语言中的“类”。模块中可以定义“资源”(Resource)和“过程”(Procedure),类似于类中的“成员”(Member)和“方法”(Method)。所有部署在Libra上的模块都是全局的,通过类似于Java中的包名+类名的方式来引用,例如0x001.MyModule,0x001是一个Libra地址,MyModule是一个模块名。模块中的过程有public和private两种可见性,公有过程可以被其他模块调用,私有过程只能被同模块的过程调用。而模块中的资源都是私有的,只有通过公有过程才能被其他模块访问。而且,外部模块或者过程对本模块资源的修改受到严格的限制,唯一允许的操作就是“移动”(Move),不能随意对资源赋值。例如,Move中是不允许出现一个类似于MyCoin.setBalance()这样的接口,让其他用户有机会随意修改某个币种余额的。

      除了受限的资源类型,Move模块中也允许定义非受限的成员,被称为非受限类型(Unrestricted Type),包括原生类型(boolean、uint64、address、bytes)和非资源类的结构体(struct)。这些非受限类型就没有那么严格的访问限制,可以用来描述与资产无关的其他应用类数据。从这个角度来说,Move语言理论上应该具有和Solidity同样的描述能力,但由于实际的去中心化应用中,总会涉及到资产类的数据,而任何引用了资源类型的结构体也都是受限的,能够真正脱离Move语言严格限制的机会并不多。所以在实际使用Move语言开发的时候,程序员一定会有一种戴着镣铐跳舞的感觉,代码出现编译时和运行时失败的可能也更大。通俗的说,用Move写代码不会让你感觉“很爽”,这就是安全性和可验证性的代价。想想你用C语言自己控制内存的分配和释放时,虽然有一种“我是上帝”的感觉,但也会时刻忧虑缓冲区溢出、内存泄露等潜在风险;而用Java语言开发,虽然你不再能够为所欲为的控制内存,但也不用担心这些内存安全性问题了。自由还是安全,往往是不兼得的。

      在一个Libra的交易(Transaction)中,也可以嵌入一段Move代码,被称为交易脚本(Transaction Script)。这段代码不属于任何模块,是一次性执行的,不能再被其他代码调用。脚本中可以包含多个过程,通过main过程作为入口来执行,在其中也可以调用其他模块中的过程。这个设计有点类似比特币,而和以太坊完全不同。在以太坊中,一个交易本身是不能包含一段可执行代码的,只能部署新合约或者调用一个已部署的合约。我不太喜欢Libra的这个设计,由于任何Move代码都必须经过字节码验证器(Bytecode Verifier)的严格检查才能发布到链上,这种一次性代码的边际成本远远高于可复用的模块,会拖慢交易被确认的速度,降低系统的吞吐量。交易脚本并不是必须的,大部分现实场景都可以通过模块来覆盖,而且,它的存在还增加了Libra钱包的开发和使用难度,有机会的时候我会向Libra的开发团队提议取消这一设计。

      下面我来看一下白皮书中的示例代码片段,直观感受一下Move语言。请注意,这段代码是Move中间语言的(IR),未来Move高级语言肯定会提供一系列语法糖,使代码更加简洁优雅。

      public main(payee: address, amount: u64) {
          let coin: 0x0.Currency.Coin = 0x0.Currency.withdraw_from_sender(copy(amount)); // 从sender余额扣除amount个Coin
          0x0.Currency.deposit(copy(payee), move(coin)); // 将coin累加到payee的Coin余额中
      } 
      

      这段代码是一个交易脚本,只有一个main过程,实现的是一个叫做Coin的代币转账逻辑,接受一个目标地址和转账金额作为参数,预期执行结果是把amount数量的Coin,从交易发起者的账户转移给address地址。

      过程体只有两行,第2行声明了一个coin变量,类型是0x0.Currency.Coin。0x0是部署Currency模块的Libra地址,Coin是一个资源类型,属于Currency模块。这是一个赋值语句,coin的值是调用0x0.Currency模块的withdraw_from_sender()过程获得的。这个过程被执行的时候,会从sender的余额中扣除amount数量的Coin;

      第3行调用0x0.Currency模块的另一个过程deposit(),把上面取得的coin这个资源累加到payee地址的余额中。

      这段代码的特别之处在于,每个取变量右值的地方都有一个copy()或者move()。这就是Move语言最有特点的地方,它借用了C++ 11和Rust的move语义,要求在读取变量的值时,必须指定取值的方式,要么是copy,要么是move。用copy的方式取值,相当于把变量克隆出一份,原来的变量值不变,还可以继续使用;而用move的方式取值,原变量的引用,或者说所有权转移给了新的变量,原变量就失效了。C++中引入move语义的目的,是为了减少不必要的对象拷贝,以及临时变量的构造和析构,提高代码执行效率;而Move语言的目的,是为了通过更严格的语法和语义限制,来提高“资源”变量的安全性。在Move中,资源类型只能move,不能copy,而且只能move一次。

      假如程序员的咖啡喝完了,状态很差,在写这段代码时出了一个bug,把第3行的move(coin)写成了copy(coin),会发生什么呢?

      public main(payee: address, amount: u64) {
          let coin: 0x0.Currency.Coin = 0x0.Currency.withdraw_from_sender(copy(amount));
          0x0.Currency.deposit(copy(payee), copy(coin)); // move(coin) -> copy(coin)
      } 
      

      由于coin是资源类型,不允许copy,Move的字节码验证器会在第3行报错。

      再假如程序员写代码时,他的猫刚好从键盘上走过,踩到了Command和D键,于是,第3行代码重复出现了两次(第4行),又会发生什么呢?

      public main(payee: address, amount: u64) {
          let coin: 0x0.Currency.Coin = 0x0.Currency.withdraw_from_sender(copy(amount));
          0x0.Currency.deposit(copy(payee), move(coin));
          0x0.Currency.deposit(copy(payee), move(coin)); // Cat did it!
      }
      

      这一次bug更严重,会导致来源地址只扣除了一次金额,而目标地址却增加了双倍的金额。在这个场景下Move的静态检查就真正发挥作用了,由于第一次coin变量经过move取值后已经不可用,那么第二次move(coin)就会引起字节码验证器报错。

      在以太坊中就没有那么幸运了,比如下面的代码:

      pragma solidity >=0.5.0 <0.7.0;
       
      contract Coin {
          mapping (address => uint) public balances;
          event Sent(address from, address to, uint amount);
       
          function send(address receiver, uint amount) public {
              require(amount <= balances[msg.sender], "Insufficient balance.");
              balances[msg.sender] -= amount;
              balances[receiver] += amount;
              balances[receiver] += amount; // Cat did it again!
              emit Sent(msg.sender, receiver, amount);
          }
          …………
      }
      

      以太坊是无法找到代码中多出来的一行balances[receiver] += amount;的(第11行), 每次send()被调用,Coin这个代币的总量都会凭空多出amount个。

      Move字节码验证器

      读到这里,大家应该能够意识到,Move中最核心的组件就是字节码验证器。让我们来看看它是如何对一段Move字节码进行验证的,验证过程通常包括以下步骤:

      • 控制流图构建:这一步会将字节码分解成代码块,并构建它们之间的跳转关系;
      • 栈高度检查:这一步主要是防止栈的越界访问;
      • 类型检查:这一步会通过一个“类型栈”模型来对代码进行类型检查;
      • 资源检查:这一步主要针对资源类型进行安全性检查,防止资源被复制或消毁,并确保-资源变量被后续代码所使用。上文举的例子中的bug,就是在这一步被发现的;
      • 引用检查:这一步参考了Rust的类型系统,对引用进行静态和动态检查。检查是在字节码级别进行的,确保没有悬空的引用(指向未分配内存的引用),以及引用的读写权限是安全的;
      • 全局状态链接:这一步主要检查结构体类型和过程的签名,确保模块的私有过程不会被调用,以及调用的参数列表符合过程的声明。

      Move虚拟机

      Move的虚拟机,和EVM相似的地方比较多。它也是一个基于栈的虚拟机。指令集包含6类指令:数据加载和移动、栈操作/代数运算/逻辑运算、模块成员及资源操作、引用相关操作、控制流操作、区块链相关操作。

      与EVM类似,每一条指令都会计算一个gas,耗光gas后代码会停机。Move中,一个交易的代码执行符合原子性,要么全部执行成功,要么一条也不执行。有趣的是,虽然Libra是一个标准的区块链账本结构,所有交易都是全局有序的,但Move语言本身支持并行执行,这意味着,也许以后Libra可以改进成类似Vite的DAG账本,提高交易并行处理的效率。

      未来工作

      当前Move还处于一个比较早起的开发阶段,后续工作包括:

      • 实现Libra链的基本功能,包括账户、Libra代币、准备金管理、验证节点的加入和移除、交易手续费管理、冷钱包等;
      • 新的语言功能,包括范型、容器、事件、合约升级等;
      • 提高开发者体验,包括设计一个人性化的高级语言等;
      • 形式化建模和验证工具;
      • 支持第三方Move模块。

      本文如有错误,请读者不吝指正。想获取更多的细节,可以阅读白皮书或开源代码。
      顺便说一句,这篇白皮书写的相当不错,概念准确,而且通俗易懂,没有使用特别形式化的描述或者复杂的数学知识,一个对区块链技术有所了解的读者完全可以一次读懂。这也从侧面反映出Facebook团队专业和务实的风格。


      本文作者:刘春明,Vite Labs创始人,区块链技术专家,中国区块链应用研究中心常务理事。转载请注明出处。

      posted in 技术讨论
      Charles
      Charles
    • RE: 去中心化交易所的演进

      @btxkenshin 从目前的进展来看,上币环节已经体现了高度的去中心化。而基于BNB的交易所治理、手续费和上币费的分配、底层币安链的DPOS节点竞选等环节暂未完成去中心化。综合来看,币安DEX在这个演进模型中已经比较接近右上角的终极形态了,将成为这个赛道上最有力的竞争者之一。

      posted in 公告
      Charles
      Charles
    • RE: 去中心化交易所的演进

      @Snaker 感谢鼓励,期待和大家有更多的交流,相互学习,共同进步!

      posted in 公告
      Charles
      Charles
    • RE: 去中心化交易所的演进

      @qiangqiang666 这个问题非常棒,我也分享一下我的观点:
      1)去中心化交易所应该是一个完整的生态,需要传统的中心化交易所运营者参与其中,将他们既有的品牌价值和流量输入到新的生态中,共享更大的用户群体和流动性,形成更广泛的共识。任何类型的交易所,通过某种方式来获取用户和提高流动性都是至关重要的,但方式并不唯一。
      2)去中心化交易所是谁开发的并不重要,重要的是它的治理模型。也就是说,交易所是谁的,谁说了算,收益归谁,这些决定了它是哪种类型的交易所。
      3)传统的中心化交易所如果沿用中心化的运营思路,开发新产品的目的是为了加强自身的垄断优势,修筑“护城河”,将竞争对手排除在外,那么,这个新产品即使应用了区块链和智能合约技术,本质上仍然是“中心化”交易所。这有点像传统互联网公司基于区块链技术开发联盟链或者私有链,不具备公有链的“去中心化”特性。
      4)去中心化交易所的竞争和其他区块链项目一样,依然是“共识的竞争”。比特币就是一个很好的例子,它并不是某个大公司孵化出来的,但它足够去中心化,因此更容易凝聚共识。

      posted in 公告
      Charles
      Charles
    • 去中心化交易所的演进

      石器时代——场外交易

      自从以比特币为代表的数字加密资产诞生以来,人们就有交易这些资产的需求。最初,这些需求主要通过社交媒体来满足,人们在论坛上发帖,或者在聊天群里发布信息,寻找可能的交易对手。这种交易方式通常也被称为场外交易(OTC, Over The Counter)。

      场外交易的主要问题是效率低下、违约风险高、缺乏有效的价格发现机制。随着区块链行业的发展,数字资产的种类越来越多,交易者的数量和他们对交易频次的要求也越来越高,场外交易已经无法满足他们的需求。在这个背景下,集中的交易场所——交易所(Exchange)随之诞生。

      工业时代——交易所

      交易所为用户提供一套交易工具以及相关的服务,将所有交易者集中起来,通过计算机程序来快速撮合买单和卖单,并通过锁定流动性为买卖双方提供履约担保。通常,用户必须将某种数字资产预先“充值”到交易所,通过执行“下单”操作,约定一个可接受的“汇率”,并将一定数量的资产锁定在系统中。系统会自动找到那些交换方向相反,并且在汇率上能够达成一致的订单,完成交易对手之间的资产结算,这个过程通常叫做“撮合”(match)。由于在撮合完成之前,等待交易的资产流动性会被交易所锁定,买家和卖家都无法动用,这就保证了交易完成后双方的可靠履约。

      安全——中心化交易所的基因缺陷

      交易所的诞生,极大提高了数字资产交易的效率,消除了违约风险,也提供了一个高效的价格发现机制。然而,这些体验的提升并不是没有代价的。

      首先,为了确保可靠履约,用户必须将资产托管到交易所。交易所实际控制着数量巨大的数字资产,产生了严重的安全隐患。历史上多次发生的交易所资产被盗事件,极大的动摇了用户对交易所安全性的信心。而运营交易所的机构,既面临挪用用户资产获利的诱惑,又面临内部安全管理的挑战。在很多“被盗”事件中,你甚至无法分辨这些被盗的资产,是真的被“黑客”洗劫,还是被交易所挪用,或者被交易所内部员工窃取。

      资产被盗虽然只是小概率事件,但交易所为了控制安全风险,或者为了挪用资产,通常都会对用户“提现”环节进行种种限制。如果你使用过任何一个交易所,都会发现,“充值”环节总是免费并且极为便利的,而在“提现”的时候,就会有最大数量、到账时间等种种限制,有时候还必须通过人工审核环节。

      垄断——中心化交易所的原罪

      此外,从商业的视角来看,中心化运营的交易所,实际上是以公司的组织形式来参与市场竞争,他们必须基于商业利益来选择交易标的。一旦某个交易所形成垄断地位,他们就会充分利用垄断优势,提高准入门槛,设置有利于自己的规则,向项目方收取高额的“上币费”,从而达到自身利润的最大化。这种垄断威胁了数字资产市场的公平竞争,提高了交易者的风险和成本。很多优质项目是以开源社区的方式来组织的,“项目方”并没有足够的融资来承担这些头部交易所的“上币费”;与之相对,有很多区块链项目将融资的一半甚至一多半交给交易所,用余下的资金与交易所合作进行市场操纵(有时候称其为“市值管理”),这类项目往往没有足够的资源用于实际的项目开发,缺乏价值支撑,投资风险非常高。这种垄断交易所与项目方合谋向投资者转嫁风险,收割投资者的行为,造成了“劣币驱逐良币”的恶性循环,加剧了区块链市场的泡沫化,威胁了整个行业的健康发展。

      因此,作为一个加密资产投资者,对中心化交易所的态度可以用“爱恨交织”来形容。总结起来,用户的痛点主要来自于以下几个方面:

      1)资产的安全性无法保证;

      2)某些环节的体验较差,尤其是注册、提现等环节;

      3)只能在交易所选定的标的范围内交易,无法满足多样性需求;

      4)治理机制高度不透明。无论是规则制定、收费标准还是撮合逻辑,都是由交易所集中控制。

      信息时代——去中心化交易所

      在这个背景下,一种被称为“去中心化交易所”(DEX, Decentralized Exchange)的新型交易所逐渐吸引了人们的目光,去中心化交易所的一些特性,有效弥补了传统中心化交易所的先天缺陷。

      在谈论去中心化交易所之前,我们应该首先明确“去中心化”的实际含义。在我看来,去中心化交易所与中心化交易所的区别,主要体现在“技术”和“治理”两个维度。

      从技术维度来看,去中心化交易所是一个建立在区块链之上的去中心化应用(dApp),通过智能合约,发挥区块链“无需信任”(trustless)、不可篡改的特点;

      从治理维度来看,去中心化交易所是一个开放的、社区驱动的、权利和义务高度分散的去中心化组织。

      事实上,目前的很多“去中心化交易所”项目,并没有在这两方面同时做到“去中心化”。要么是采用中心化技术,在治理层面鼓励社区参与;要么是只采用了去中心化技术,商业模式和运营仍然是中心化的。

      那么,一个真正的、理想的去中心化交易所,到底应该是什么样子,它又能给用户带来什么具体的好处呢?

      上链与跨链——技术视角下的“去中心化”

      交易所的系统,主要分为“资产管理”和“订单撮合引擎”两个模块,前者存储账户数据,负责资产托管和交易结算;后者存储订单簿数据,执行订单的撮合计算。

      去中心化的技术方案,是将这两个模块都用链上的智能合约来实现。这样,用户的资产托管到智能合约中,没有任何个人或组织可以轻易盗取或挪用,用户提现也不受任何人为的限制。而订单的撮合逻辑也受智能合约限制,使“抢先交易”(front running)这类作弊行为无法得逞。

      得益于区块链系统自身的特性,去中心化交易所可以保证极高的可用性。几乎在任何时候,总能在线上找到可用的节点提供服务,从而保证交易撮合和资产结算永不中断。在最坏情况下,用户还可以选择自己运行一个区块链的节点,来完成中断的交易,并将资产安全的转移到自己的钱包中。

      实现这种完全去中心化的技术方案,要求交易所底层的公链平台有足够好的性能,而且智能合约执行的成本足够低。目前,由于大部分公链平台无法同时满足这两点,因此,很多去中心化交易所只能作出妥协,采用一种二层协议(Layer 2),只将低频的资产管理模块部署到链上,而将高频的订单撮合模块放在链下。这种方案虽然牺牲了订单撮合逻辑的去中心化,提高了去中心化交易所开发和运维成本,但至少解决了最为迫切的托管资产安全性问题,也不失为一种可行的折衷方案。

      最后,支持多种不同公链平台上的资产之间进行交易,或者说具有“跨链”能力,也是去中心化交易所的一个重要技术目标。

      所有权、运营权、收益权——治理视角下的“去中心化”

      从治理的视角来看,交易所是中心化还是去中心化的,主要体现在它的所有权、经营权和收益权是归属于某一个特定的商业组织,还是归属于一个开放的社区。

      在中心化交易所的治理模式中,某个中心化组织有权决定交易何时开放和关闭,有权修改交易规则;这个组织有权决定允许哪些用户来交易,以及哪些数字资产可供交易;交易所产生的收益也归属于这个组织。

      而在去中心化交易所的治理模式中,交易所的所有权归属于社区,所有的规则变更必须通过投票或者分叉的形式来获得共识;交易所向社区用户开放,选择交易标的、制定手续费等运营权也归属于社区;同样,交易所所产生的收益也全部归属于社区。

      目前,无论是中心化交易所,还是去中心化交易所,通常都会对交易所的某种权益代币化,发行一种交易所的“平台币”。有趣的是,通过交易所平台币的经济模型,我们可以清晰的分辨出它的治理模式。

      如果平台币只能用于抵扣交易手续费,某种意义上来说相当于交易所的“优惠券”或“会员卡”,持币用户仅仅作为消费者享受优惠服务,那么,基于这种平台币经济模型的交易所,其治理模式也是中心化的;

      相反,如果交易所的平台币大部分由社区持有,而持币用户拥有交易所重大决策的投票权,并且可以获得交易所的利润作为分红,那么这个交易所的治理模式就是去中心化的;

      由于去中心化治理的开放性,任何用户,或者任何用户想交易的资产,都无法被某个垄断组织出于自身利益考虑而挡在门外。不同的交易标的可以在统一的市场规则下自由竞争,优胜劣汰。任何个人或组织都无法轻易修改游戏规则,个体的退出也不会对交易所产生重大影响。

      同时,开放性还可以带来更好的流动性,在统一的协议框架下,所有交易者共享同一个市场的深度。

      最后,交易所收益权的社区化,为整个交易生态提供了一个有效的激励,最终会降低所有交易者的平均成本。

      进化之路——去中心化交易所演进模型

      如果按照以上两个维度,按照交易所的去中心化阶段绘制成图形,如下图所示。我们会发现,去中心化交易所演进的起点和终点都是相同的,演进的路径都是从左下角开始,选择不同的进化方向,逐步向右上角推进。
      b7c0462d-84a0-47a8-97c2-265119e17c05-image.png

      问题与挑战

      当前阶段,去中心化交易所的用户体验与中心化交易所还存在相当的差距。最大的问题体现在撮合速度慢、交易成本高和流动性不足三个方面。任何用户都无法接受每笔订单需要等待十几秒甚至几十秒才能成交,或者每下一单,甚至撤单都需要支付高额的手续费。用户更无法接受一个数字资产想卖的时候卖不掉,想买的时候买不到。

      在技术层面,去中心化交易所需要解决撮合的性能和经济性问题,这个挑战主要依靠基础设施,也就是底层公链平台的进化来解决。基于这个原因,很多去中心化交易所项目甚至选择自行开发一个公链。

      另外,由于不同的公链在协议、账本和共识算法上的巨大差异,解决资产的跨链流动性也是一个巨大的挑战。虽然目前出现了很多所谓的“跨链”方案,但都无法完美的解决问题。

      目前,去中心化交易所比较现实的选择是基于“公证人”(或者称为“网关”)的跨链方案。这一方案的弱点在于过于依赖链下信任,无法实现去中心化。即使引入不同公证人之间彼此监督、互相竞争、形成某种共识的机制,仍然存在公证人合谋作恶的可能。

      而“原子交换”这类“方案,本质上是不同公链的资产在两个用户之间的对等交换,而不是资产跨越公链的单向转移。例如,当你想把代币从比特币网络转移到以太坊网络上时,必须找到一个想把同样数量的代币反向转移的交易对手,他拿走了你在比特币网络上的代币,而你拿走了他在以太坊网络上的代币。显然,原子交换更适用于OTC交易,无法满足交易所这种集中撮合的场景。

      还有一类“同构跨链”的解决方案,例如Cosmos或者Polkadot,通过设计某种顶层协议,来提高符合该协议的“链”之间的互操作性。这类方案的问题在于无法使现存的公链之间实现“跨链”,除非比特币、以太坊等主流公链都能够兼容这种顶层协议。这一点短期很难实现,因为“跨链”的难题恰恰在于“跨协议”交互,而公链之间的竞争本质上正是协议之间的竞争。所以,试图通过统一协议来完成“跨链”的目标,显然不会是一件容易的事。

      在治理层面,去中心化交易所需要解决流动性激励问题,这主要依靠合理的治理模型和激励模型。这个问题往往被人们所忽略,其实它才是很多去中心化交易所最大的短板。一个中心化治理的交易所,甚至不应该被称为“去中心化”交易所。但治理的去中心化, 远比技术的去中心化难度更高。无论是经济模型的设计、社区的建立,还是交易生态的发展,都是一个漫长的过程。在这个过程中,交易用户、传统交易所、项目方、做市商、加密资产投资人等,整个生态中的不同角色通过持续的竞争和合作,最终达到利益的平衡。因此,一个真正的去中心化交易所,应该着眼于建立一个完整的交易生态,把原本分散在不同“中心”的流动性汇集在一起,而不是试图成为一个新的“中心”,这样才符合“去中心化”的真正内涵。

      进化的终点——完全去中心化交易所

      随着公链技术的进步和治理模式的迭代,去中心化交易所已经逐步具备了商业应用的条件。用户正在期待着一个进化到完全形态,从技术到治理都完全体现去中心化的新一代交易所的诞生。

      这个交易所应该构建在一条高性能、低成本的公链之上,可以在链上完成订单的撮合,并且具有跨链能力。

      同时,这个交易所应该有一个充分开放的生态,由社区所有、社区运营、社区受益。它的治理模型应该能够充分平衡所有生态参与者的利益,无论是交易用户、运营者、流动性提供者还是项目方,都可以从这个生态中找到自己的位置。

      蓝图已经勾画完成,是时候做一些事把它变成现实了。按照理想中去中心化交易所的终极形态,我们打造了一个商业应用级别的去中心化交易所——ViteX。我不打算在这篇文章中讲述太多ViteX的细节,只给好奇的读者提供一些线索:

      • ViteX是一个体验接近传统交易所的去中心化交易所,资产由用户自己通过私钥控制,在交易前不需要复杂的注册和KYC流程。

      • ViteX是一个开放的平台,任何人都可以利用它“开自己的去中心化交易所”,就像在淘宝开店一样简单。

      • ViteX运营的核心角色是“交易所运营商”,他们类似淘宝的“商家”。这些运营商将来自传统交易所品牌持有者、区块链项目方、Token Fund,或者社区KOL等。运营商有自己的交易专区(类似淘宝的“店铺”),保留自己的品牌,拥有开通交易对、设置手续费等运营权。运营商的品牌和信用将成为他们在竞争中取胜的关键因素。例如,上币标准和尽职调查更为严格的运营商,可能更容易被用户认可。

      • ViteX是一组运营去中心化交易所所需要的基础设施,包括智能合约、网站、API、SDK等。运营商也可以基于ViteX API来搭建自己的交易网站,或者和自己的交易系统打通。

      • ViteX将基于平台币VX来完成激励和去中心化治理。VX代币没有明显的利益相关方,也没有融资和预挖。获取VX的方式包括:完成一笔交易、开通新的交易对、为ViteX智能合约提供公链资源的配额、为ViteX提供流动性、邀请新的用户等。这些规则将被写入智能合约,成为协议的一部分。

      • ViteX平台归属于VX持有者,任何协议和规则的修改都将通过VX投票来决策。同时,ViteX平台产生的利润,也将100%分配给VX代币的持有者。

      • ViteX是构建在Vite公链之上的,Vite公链是一个基于DAG账本、支持智能合约的异步高性能公链平台,秒级确认,无手续费,支持多币种及跨链。Vite公链就是为DEX这一类复杂的dApp而设计的,可以很好的满足链上撮合的性能和成本要求。

      希望我们的探索和实践,可以加速去中心化交易所的演进速度,催生更多的商业机会,并让加密资产交易生态和整个区块链行业走向繁荣。

      (本文作者:刘春明,欢迎转载。)

      posted in 公告
      Charles
      Charles
    • RE: REVIEW OF THE VITE DECENTRALIZED EXCHANGE

      Bravo! It's a great video.

      posted in General Discussion
      Charles
      Charles
    • RE: VEP-5: Remove Explicit Snapshot Block Hash as Timestamps

      @Oleg Thank you! 😁

      posted in Tech News & Updates
      Charles
      Charles
    • VEP-5: 移除作为时间戳的快照块哈希显式引用

      VEP-5: 移除作为时间戳的快照块哈希显式引用

      背景

      在Vite白皮书1.0版中,章节6.2.2(资源量化)提到:
      由于快照链相当于一个全局时钟,我们可以利用它准确的量化一个账户的资源使用情况。在每个交易中,必须引用一个快照块的哈希,将快照块的高度作为该交易的时间戳。因此可以根据两个交易时间戳的差,来判断这两个交易之间是否间隔足够长的时间。

      explicit_timestamp.png

      如上图所示,每个交易都包含一个快照块哈希的显式引用,作为交易创建时间的证明。这个时间戳的主要用途是计算一个账户的资源消耗是否超出配额。

      除了这个时间戳之外,系统中还存在另一个"隐式"的时间戳,也就是一个快照块中所记录的每个账户的最新交易哈希,代表的是一个交易的"确认时间"。

      由于这两种时间戳的存在,DAG账本中的交易和快照链之间存在双向依赖关系,如下图所示:

      timestamps.png

      红色的箭头表示交易对快照链的引用,也就是显式时间戳(交易的创建时间);蓝色的箭头表示快照块对账本中交易的引用,也就是隐式时间戳(交易的确认时间)。

      快照链分叉对时间戳的影响

      由于快照链存在分叉的可能,实际上是一个树状结构,快照块的高度越大,被回滚的概率越高。当快照块被回滚时,这两种时间戳都会受到影响。
      其中,显式时间戳受到的影响更大,如下图所示:

      explicit_forked.png

      快照链末尾右侧的快照块被回滚,为另一个分叉的快照块所取代。所有引用该快照块的交易都将作废,包括图中A和B账户的最后一个交易。
      这是由于这些交易在签名时使用了被回滚的快照块哈希,在更新这个字段后,必须由持有私钥的用户重新签名并发布新的交易。
      重新签名交易是一个非常昂贵的操作,在实际应用中应该尽量避免。
      一个比较保守的策略是尽量引用比较旧的快照块,也就是快照链的“树干”的部分。这种做法又失去了显式时间戳作为交易创建时间的现实意义。
      因此,显式时间戳的存在非常鸡肋。

      与此相对,隐式时间戳在快照块回滚时就没有同样的问题,如下图所示:

      implicit_forked.png

      一个快照块被回滚,其中的隐式时间戳与这个快照块一起被废弃,A账户的第二个交易变成未确认状态。另一个分叉中新的快照块仍然会包含一组隐式时间戳,只是与原分叉中的记录未必相同。
      由于隐式时间戳是反向引用,DAG账本中的交易没有发生改变,因此,时间戳的更新只与SBP有关,用户无需重新签名交易,分叉处理逻辑相对简单。

      采用隐式时间戳计算资源消耗

      那么,使用隐式时间戳,是否仍然可以准确量化每个账户的资源使用并计算配额消耗呢?答案是肯定的。

      如图2所示,如果按照原来的方式,使用显式时间戳计算,在快照N-2到快照N的2个时间单位内,账户A创建了4个交易,账户B创建了2个交易;
      而采用隐式时间戳计算,在快照N-1到快照N的1个时间单位内,账户A被确认了2个交易,账户B被确认了1个交易。
      这样,按照每个账户在固定时间间隔内被确认的交易所消耗的资源总量,仍然可以准确量化该账户近期的平均资源消耗,从而判断出该账户新增的交易是否超出其配额。

      当然,由于交易的创建和确认是异步的,交易在网络上传输,以及账户的状态计算都会消耗一定时间,用交易确认时间来判断配额可能会存在一定误差。
      我们可以通过提高统计的时间间隔数,也就是统计更长时间的平均资源消耗,来减小这种误差的影响。
      在Vite系统中,只要在同一时间段内,针对不同账户的资源消耗统计是公平的,就足以保证配额模型的正常工作。

      结论

      基于以上讨论,本提案建议将Vite账本中所有显式时间戳移除,只保留隐式时间戳。

      这样,虽然链上数据中不再保存交易的创建时间,会损失一些依赖该时间戳的语义,但这种影响非常有限。尤其是,资源消耗计算和配额模型仍然可以使用"确认时间"这个隐式时间戳来实现。

      而这个优化却可以带来如下收益:

      • 去除DAG账本和快照链结构之间的双向依赖,使DAG账本和快照链可以异步构建;
      • 简化了快照块的回滚处理逻辑,有助于提高系统的吞吐量;
      • 时间戳失效后,无需重新签名交易,简化了客户端处理逻辑;
      • 减少了DAG账本的存储空间。
      posted in 技术讨论
      Charles
      Charles