Facebook Libra Blockchain Technology White Paper (Chinese version)

Libra blockchain

White Paper: Zachary Amsden, Ramnik Arora, Shehar Bano, Mathieu Baudet, Sam Blackshear, Abhay Bothra, George Cabrera, Christian Catalini, Konstantinos Chalkias, Evan Cheng, Avery Ching, Andrey Chursin, George Danezis, Gerardo Di Giacomo, David L. Dill , Hui Ding, Nick Doudchenko, Victor Gao, Zhenhuan Gao, François Garillot, Michael Gorven, Philip Hayes, J. Mark Hou, Yuxuan Hu, Kevin Hurley, Kevin Lewi, Chunqi Li, Zekun Li, Dahlia Malkhi, Sonia Margulis, Ben Maurer , Payman Mohassel, Ladi de Naurois, Valeria Nikolaenko, Todd Nowacki, Oleksandr Orlov, Dmitri Perelman, Alistair Pott, Brett Proctor, Shaz Qadeer, Rain, Dario Russi, Bryan Schwab, Stephane Sezer, Alberto Sonnino, Herman Venter, Lei Wei, Nils Wernerfelt, Brandon Williams, Qinfan Wu, Xifan Yan, Tim Zakian, Runtian Zhou*

Translation: Babbitt Information (Free and Happy, Kyle)

Summary

The Libra Blockchain is a decentralized, programmable database designed to support a low-volatility cryptocurrency that can serve as an effective medium for serving billions of people around the world. We propose a proposal for the Libra protocol that will implement the Libra blockchain to create a financial infrastructure that promotes innovation, reduces barriers to entry, and improves access to financial services. To validate the design of the Libra protocol, we have built an open source prototype implementation, Libra Core, and jointly promote this new ecosystem on a global scale.

The Libra protocol allows a set of replicas (called certifiers) from different entities to jointly maintain a database of programmable resources. These resources are owned by different user accounts that are verified by public key cryptography and adhere to custom rules specified by these resource developers. The verifier processes the transactions and interacts to reach a consensus on the state of the database. Transactions are based on pre-defined, and in future releases, user-defined smart contracts will be written in a new programming language called Move .

We use the Move language to define the core mechanisms of the blockchain, such as currency and certifier members. These core mechanisms create a unique governance mechanism based on the established stability of the existing project, but the Libra system will be completely open over time.

Libra

(Image courtesy of Libra.org)

I. Introduction

The popularity of the Internet and the resulting digitization of products and services have increased efficiency, reduced barriers to entry, and reduced costs in most industries. This connectivity has driven economic empowerment by allowing more people to enter the financial ecosystem. Still, for those who need financial services the most, access to financial services is still limited, driven by cost, reliability, and the ability to seamlessly send funds.

This technical paper proposes a proposal for the Libra protocol to support this new Libra ecosystem and address these challenges, expand capital access, and serve as a platform for innovative financial services. The ecosystem will provide a new global currency, Libra , which will be fully supported by a basket of bank deposits and government bonds from a quality central bank.

These benchmark currencies have experienced relatively low inflation, so the Libra Stabilizer inherits this property and it also has a geographically diverse combination of advantages. The Libra agreement must be expanded to support its currency growth as a global financial infrastructure that provides the flexibility to implement economics and governance to support its operational strategy. The design of the Libra protocol addresses these needs from the outset, based on existing projects and research. Libra combines novel methods with techniques that are widely understood.

A key prerequisite for healthy competition and innovation in the financial services industry is to rely on transactions, maintain accounts, and ensure interoperable public infrastructure across services and organizations. By reducing barriers to entry and switching costs, the Libra agreement will enable start-ups and existing large enterprises to compete in a level playing field and experiment with new business models and financial applications. Blockchain technology can solve these problems well because it can be used to ensure that no single entity can control the ecosystem or can unilaterally shape its evolutionary advantage [2].

The Libra blockchain will be decentralized and consists of a set of co-workers of verifiers that handle transactions and maintain the state of the blockchain. These verifiers also form members of the Libra Association, which will provide a framework for network management and support for currency reserves. Initially, the association (verifier) ​​will consist of a group of geographically dispersed founding members. These members are selected based on objective participation criteria, including their interest in guiding the Libra ecosystem and investing in its success. Over time, membership will be turned into full open, based only on Libra's holdings . The Libra Association has published a report outlining its vision [1], the proposed structure [3], the economics of money [4], and the road map to the transition to an unlicensed system [5].

This article is the first step in building a technology infrastructure that supports the Libra ecosystem.

We published this early report to solicit feedback from the community on Libra's initial design, system development plans, and current unresolved research challenges. Therefore, the association has established an open source community [6] for discussion and support for project development.

Libra agreement . The Libra blockchain is a database of cryptographic proofs maintained using the Libra protocol [7, 8, 9]. The database stores a ledger of programmable resources such as Libra coins. The resource follows the custom rules specified by its declaration module, which is also stored in the database. Resources are owned by an account that is authenticated using a cryptographic public key. Accounts can represent direct end users of the system as well as entities (such as managed wallets) that represent their users. The owner of the account can sign a transaction that operates on resources within the account.

Figure 1 shows two types of entities that interact using the Libra protocol: (1) the verifier, which is responsible for maintaining the database, and (2) the client, which performs queries against the database and commits the transaction to modify it.

P1

Figure 1: Overview of the Libra protocol

The verifier maintains this database and processes the transactions submitted by the client contained in the database (1). The verifier uses a distributed consensus protocol to agree on a growing list of transactions that have been committed to the database and the results of executing those transactions. Even if a small number of verifiers are malicious or wrong, this consensus agreement must be reliable. The verifier drives the process of accepting transactions in turn. When the verifier acts as the leader, it will present to other verifiers (2) the transactions that the client directly submits to it, as well as the transactions that are indirectly submitted by other verifiers. All certifiers execute the transaction (3) and form a validated data structure containing the new book history. As part of the consensus agreement (4), the verifier votes on the validator of the data structure. As part of submitting a transaction ti in version i, the consensus protocol outputs the full state signature of the database (including the entire history) in version i to confirm the response to the query from the client (5).

The client can issue a query to the verifier to read the data from the database. Because the database is validated, the accuracy of the client's response to its queries is guaranteed. As part of the response to the read query, the verifier returns the signature verifier of the latest version i of the database known to the verifier.

In addition, the client can choose to create a copy of the entire database by synchronizing the transaction history with the verifier. When creating a replica, the client can check if the certifier has performed the transaction correctly, which improves the system's accountability and transparency. Other clients can read the copy from the client that holds the copy, in the same way that the copy is read from the verifier to verify the authenticity of the response.

For the sake of simplicity, the rest of this article assumes that the client directly queries a verifier instead of a copy.

Composition. This article discusses the components of the Libra protocol:

  1. Logical Data Model : (Section 2) describes a logical data model that organizes a decentralized database visible to both the verifier and the client.
  2. Execution Transactions : (Section 3) describes the use of the Move [10] programming language, a new programming language for defining and executing database transactions.
  3. Proven data structures and storage : (Section 4) describes the mapping of Merkle tree-based logical models to validated data structures [11].
  4. Byzantine Fault Tolerance Consensus : (Section 5) describes a variant of the HotStuff protocol [13], LibraBFT [12], which allows networks with potentially malicious certifiers to perform Move language transactions and perform transactions using validated data structures. Agree to maintain a single, consistent database.
  5. Network : (Section 6) describes a protocol that enables verifiers to communicate securely with one another based on the need for consensus.

Later, we showed the open source Libra Core prototype [6]. Section 7 discusses how Libra Core combines components of the Libra protocol to handle transactions.

Section 8 discusses performance considerations.

Finally, we will explain how to use this protocol to support the economic stability and governance of Libra ecosystem policies.

Section 9 shows how we use the Move language to achieve low volatility, reserve-backed Libra currency, and a verifier management system that reflects Libra Association governance.

Section 10 discusses future plans for the Libra ecosystem and the challenges it is currently facing, and this will be the end of this article.

Second, the logical data model

All data in the Libra blockchain is stored in a single version of the database [14, 15]. The version number is an unsigned 64-bit integer that corresponds to the number of transactions the system has executed. In each version i, the database contains a tuple (Ti, Oi, Si) that represents transaction (Ti) , transaction output (Oi), and ledger status (Si) . Given a deterministic execution function Apply , the meaning of this tuple is: reconciliation state Si−1 execution transaction Ti will produce output Oi and new account state Si, ie Apply(Si−1, Ti) → ⟨Oi, Si⟩ .

The Libra protocol uses the Move language to implement deterministic execution functions (see Section 3). In this section, we will focus on the versioned database, which allows the verifier:

  1. Execute a transaction based on the latest version of the ledger status;
  2. Respond to the client's query about current and previous versions of the ledger history;

We first explain the structure of the book state stored in a single version, and then discuss the purpose of the versioned book history view.

2.1 Book status

The book status represents the basic facts about the Libra ecosystem, including the number of Libra coins held by each user in a given version. Each certifier must know the current version of the ledger status in order to execute a new transaction.

The Libra protocol uses an account-based data model [16] to encode the book state. The state is constructed as a key-value store that maps the account address key to the account value. The account value in the book state is a collection of published Move resources and modules. This Move resource stores the data values, while the module stores the code. The initial account set and its status are specified in the Founding Book Status (see Section 3.1).

Account Address : The account address is a 256-bit value. To create a new account, the user first generates a new authentication/signing key pair (vk, sk) for the signature scheme and uses the cryptographic hash of the public authentication key vk as the account address a = H(vk) . When the create_account(a) Move command is called from a transaction sent from an existing account, the new account is created in the ledger state. This usually happens when a transaction attempts to send Libra to an account at address a that has not yet been created.

After creating a new account in address a , the user can sign the transaction to be sent from the account using the private signature key sk . The user can also change the key used to sign the transaction without changing its address (for example, if the key is actively changed or the response key may be stolen).

The Libra protocol does not link the account to the user's true identity (ie no KYC) . Users can create multiple accounts by generating multiple key pairs. Accounts controlled by the same user are not inherently related. The program refers to Bitcoin and Ethereum, providing users with pseudonymous (also known as semi-anonymous) [19].

Resource value : A resource value or resource is a record that binds a named field to a simple value, such as an integer or complex value.

(Footnote 1: Specifically, we instantiate the hash function using SHA3-256 [17] and implement the EdDSA digital signature using the edwards25519 curve [18])

P2

Figure 2: Example of a ledger status with four accounts. In this figure, an ellipse represents a resource and a rectangle represents a module. From the resource to the directed edge of the module, it means that the module declares the type of resource. An account with address 0x12 containing the Currency.T resource declared by the currency module. The code for this currency module is stored at address 0x56. The account at address 0x34 contains both a Currency.T resource and a StateChannel.T resource, which is declared by the module stored at address 0x78.

Each resource has a type declared by the module. The resource type is a nominal type [20], which consists of the name of the type and the name and address of the resource's declaration module. For example, the type of Currency.T resource in Figure 2 is 0x56.Currency.T. Here, 0x56 is the address of the storage currency module, Currency is the name of the module, and Currency.T is the name of the resource.

To retrieve the resource 0x56.Currency.T at account address 0x12, the client will request 0x12/resources/0x56.Currency.T .

The purpose of this design is to let the module define a predictable pattern for top-level account values—that is, each account stores its 0x56.Currency.T resource in the same path. Therefore, each account can store up to one resource of a given type. However, this limitation is unconstrained because programmers can define wrapper resources to organize resources in a custom way. (for example, resource TwoCoin { c1: 0x56.Currency.T, c2: 0x56.Currency.T } ).

Rules for changing, deleting, and publishing resources, encoded in modules that create resources and declare their types.

Move's security and validation rules prevent other code from modifying the resource.

Module value : A so-called module value or module containing the Move bytecode that declares the resource type and program (see Section 3.4 for more details). Like the resource type, the module is identified by the account address of the claim module. For example, the identifier of the Currency module in Figure 2 is 0x56.Currency .

Modules must be uniquely named in an account, and each account can only declare at most one module with the given name. For example, the account at address 0x56 in Figure 2 cannot declare another module named Currency . On the other hand, an account with an address of 0x34 can declare a module of Currency. The identifier for this module will be 0x34.Currency . Note that 0x56.Currency.T and 0x34.Currency.T are different types and they are not interchangeable with each other.

In the current version of the Libra protocol, the modules are immutable. Once a module is declared under the account address, it cannot be modified or deleted unless it is hard-forged . We are working on a solution option to enable security module updates in a future release.

2, 2 transactions (Transactions)

The client of the Libra blockchain updates the state of the books by committing transactions. From a high-dimensional perspective, a transaction consists of a transaction script (written in Move bytecode) and a transaction script's parameters (for example, the recipient's account address or the number of Libra coins to send). The verifier executes the transaction by running the script and its parameters and the current ledger state as input to generate a fully determined transaction output. By consensus (Section 5), by agreeing to a binding commitment to transaction output (Section 4), the book status does not change until the transaction is committed.

We will discuss the structure and execution of transactions in more detail in Section 3.

Transaction output : Executing a transaction Ti will generate a new ledger state Si and execution status code, gas usage, and event list (summarized in output Oi). The execution status code records the result of executing a transaction (eg, success, exit due to error e , gas exhaustion, etc.).

Gas usage, which records the number of gas units used to execute a transaction (see Section 3.1 for details on how to use gas to manage transaction-related expenses).

Events : A list of events that are a set of side effects (2) that are generated when a transaction is executed. The Move code can trigger an event through an event structure. Each event is associated with a unique key that identifies the structure from which the event was sent and the payload that provides the activity details. Once a transaction is submitted in accordance with the consensus agreement, the event generated by the transaction is added to the agreed-book history and provides evidence that the successful execution of the transaction resulted in a particular effect. For example, a payment transaction sends an event that allows the recipient to confirm that the payment has been received and to confirm the payment amount.

At first glance, the incident seems to be superfluous. Instead of querying events through a transaction Ti, the client can ask if the transaction Ti is included in the blockchain. However, this is very error-prone, because including Ti does not mean successful execution (for example, gas may be interrupted after it is used up). In systems where a transaction may fail, the event not only provides evidence that a particular transaction has been executed, but also provides evidence that it has completed successfully with the expected effect.

Transactions can only generate events – they cannot read events. This design allows transactions to execute functions that are only the current state, not historical information (such as previously generated events).

2, 3 book history

The book history stores a sequence of committed and executed transactions, as well as associated events that they issue. The purpose of the book history is to record how the most recent book status is calculated.

There is no concept of a set of transactions in the book history (3). The consensus protocol batches the transaction to the block as an optimization and driver for this consensus protocol (see Section 5 for more information on consensus). However, in the logical data model, transactions occur sequentially, without distinguishing which block contains each transaction.

(Footnote 2: The role of the event, similar to the log and event concept in Ethereum [16], however, the event mechanism in the Libra protocol is completely different.

Footnote 3: This is in contrast to Bitcoin and Ethereum. In Bitcoin and Ethereum, the concept of block and block maxima plays an important role. )

Although the verifier can execute a new transaction without knowing the book history, the client can perform a verified query against the ledger history and use the book history to review the transaction execution.

Respond to client queries : The verifier can use the ledger history to answer client queries about previous ledger status, transactions, and output. For example, the client might ask about the status of a particular version of the ledger (for example, what is the account balance at address 30 of the 30th version?), or the history of a particular type of event (for example, an account with a Y address is received in the last 20 minutes) What payment is there?).

Audit transaction execution : The client can check whether the account status is correct by re-executing each transaction Ti in the history and comparing the calculated book status with the corresponding book status Si and transaction output Oi in the version database.

This mechanism allows the client to audit the certifier to ensure that the transaction is executed correctly.

Third, the implementation of the transaction

In the Libra blockchain, the only way to change the state of a blockchain is to execute a transaction.

This section outlines the requirements for transaction execution, defines the structure of the transaction, explains how the Move virtual machine (VM) executes a transaction, and describes the key concepts of the Move language.

In the original version of the Libra protocol, only a limited subset of Move functions were available to the client . Although Move is used to define core system concepts, such as Libra currency, users cannot publish custom modules that declare their own resource types. This approach allows the Move language and toolchain to mature before being exposed to the user. This approach also delays the scalability challenges in transaction execution and data storage, which are inherent in the general intelligence contract platform.

As we discussed in Section 10, we are committed to demonstrating full programmability through the Move language.

3, 1 implementation requirements

Initial state is known : All certifiers must agree to the initial or founding book status of the system.

Because the core components of the Libra blockchain (such as account logic, transaction verification, verifier selection, and Libra currency) are defined by the Move module, the originating state must define these modules. The originating state must also have sufficient instantiation of these core components so that transactions can be processed (for example, at least one account must be able to pay for the first transaction; the set of validators must be defined so that the set of quorums of the group can be dedicated The confirmer of the first transaction is signed).

To simplify the design of the system, the initial state of the system is shown as empty . A founding state is then created by defining a special transaction T0 for a particular module that defines the specific modules and resources to be created, rather than through a normal transaction process. The client and verifier are configured to accept only the ledger history beginning with a specific T0, which is identified by its cryptographic hash.

These special transactions cannot be added to the book history through a consensus agreement and can only be configured. (4)

Certainty : Transaction execution must be deterministic and tight. This means that the output of the transaction execution is fully predictable and based only on the information contained in the transaction and current book status. Transaction execution does not have external effects (such as interacting with the network). Deterministic and closed execution ensures that multiple verifiers can agree on the state of the same transaction sequence, even if the transaction is performed independently by each verifier.

This also means that the transaction history of the blockchain can be re-executed from the founding block to generate the current book state (see Section 2.3).

Metrology: In order to manage the demand for computing power, the Libra Agreement charges transaction fees denominated in Libra (5). This refers to the gas model popularized by Ethereum [16].

The approach we take is to select a verifier with sufficient capacity to meet the needs of the Libra ecosystem (see Section 8). The sole purpose of this fee is to reduce the demand when the system load is higher than the capacity provided by the system (for example, in a denial of service attack). The system is designed to have sufficient capacity when it is in normal operation. The cost will be lower.

This approach differs from some existing blockchains, which sometimes require more transaction processing than throughput. In these systems, costs are proliferating in the face of high demand, which is a source of revenue for the verifier, but creates cost problems for users.

The size of the fee is determined by two factors: the gas价格 and the gas消耗 . Each transaction specifies the price per unit of gas (in Libra) that the submitter is willing to pay. The execution of the transaction dynamically illustrates its computational power consumed by gas. When the system is blocked, the verifier will prioritize transactions with higher gas prices and may abandon lower-priced transactions. This reduces the need for transactions to be initiated under high system load conditions.

In addition, a transaction contains a maximum amount of gas that specifies the maximum number of gas units that the submitter is willing to pay at the specified price. During execution, the virtual machine tracks the number of gas units used. If the maximum gas limit is reached before execution is complete, the virtual machine will stop immediately. Some changes caused by such a transaction will not be submitted to the status. However, the transaction will still appear in the transaction history, and the sender's account will still be charged for the used gas.

As we discussed in this section, many parts of the core logic of the Libra blockchain are defined using Move, which includes the deduction of the gas fee. To avoid looping, the virtual machine disables gas metering during the execution of these core components. These core components must be defined in the founding state. It must be written in a defensive manner to prevent malicious transactions from triggering computationally expensive code. The cost of executing this logic can be included in the base fee charged for the transaction.

Asset Semantics: As we explained in Section 2.1, the book status directly encodes digital assets of real value. The execution of the transaction must ensure that assets such as Libra coins are not copied, lost or transferred without authorization. The Libra protocol uses the Move virtual machine (Section 3.4) to securely execute transactions and custom assets with these attributes.

(Footnote 4: We are exploring the use of this form of special transactions to clearly define the idea of ​​hard forks. The client can specify a preferred configuration that declares a similar special transaction (it is outside the standard transaction processing rules) Specific changes have been made to the resource), which should be attached to the book history in the i-th version. Since many parts of the Libra protocol are expressed in the Move language, this type of update can be expressed, but only for the client. The software makes configuration changes.

Footnote 5: In Section 4.4, we discussed ways to manage storage capacity requirements. )

3, 2 transaction structure

A transaction is a signed message that contains the following data:

  1. Sender address : The account address of the transaction sender. The virtual machine reads the sequence number, the authentication key, and the balance of the LibraAccount.T resource stored at the address;
  2. Sender public key : The public key corresponding to the private key used to sign the transaction. The hash of this public key must match the authentication key stored by the sender's LibraAccount.T resource.
  3. Program : The Move bytecode transaction script to be executed, an optional list of script inputs, and an optional list of Move bytecode modules to be published.
  4. Gas price : The sender is willing to pay the amount of gas per unit in order to perform this transaction.
  5. Maximum Gas Amount : The maximum number of Gas units allowed to be consumed before the transaction is aborted.
  6. Serial Number : An unsigned integer that must be equal to the serial number in the sender's LibraAccount.T resource. The serial number is incremented by one after this transaction is executed. Since only one transaction can be committed for a given serial number, the transaction cannot be replayed.

3, 3 executive affairs

Executing a transaction is accomplished by performing six steps within the virtual machine. Perform an update that is independent of the status of the ledger. First, executing a transaction is part of an attempt to reach a consensus on its order. Since the execution is closed, it does not cause external side effects. Then, if a consensus is reached, its output is written into the book history.

Executing a transaction will perform the following 6 steps:

1. Check signature : The signature on the transaction must match the sender's public key and transaction data. This step is only one effect of the transaction itself, it does not need to read any data from the sender's account.

2. Run prologue : prologue authenticates the transaction sender, ensuring that the sender has enough Libra coins to pay for the maximum number of gas units specified in the transaction and that the transaction is not a replay of the previous transaction. All of these checks are implemented in the Move language through the prologue process of the LibraAccount module. Gas metering is disabled during prologue execution. Specifically, this prologue will do the following:

(1) Check if the hash of the sender's public key is equal to the identity key stored under the sender's account : Without this check, the virtual machine will incorrectly accept transactions with a cryptographically valid signature, even if there is no associated association with the account. Key communication.

(2) Check gas_price * max_gas_amount <= sender_account_balance : If this check is not done, the virtual machine will perform transactions that may fail in epilogue because they will not be able to pay the gas fee.

(3) Ensure that the transaction serial number is equal to the serial number stored under the user account : if there is no such check, the malicious party can replay the old transaction (for example, Bob can replay the 10 Libra coins that Alice paid to him) transaction).

3. Verify transaction scripts and modules : Once the transaction prologue successfully completes the task, the virtual machine will use the Move bytecode validator to perform a well-formed check of the transaction scripts and modules. This bytecode verifier checks for things like type-safety, reference-safety (no dangling references), and resource-safety (resource-safety) before actually running or releasing any Move code. Key attributes such as being copied, reused, or accidentally destroyed.

4. Release module : Each module in the program field of the transaction is published under the account of the transaction sender. Duplicate module names are forbidden, for example, if a transaction attempts to publish a module named M to an account that already contains the module name M, then the step will fail;

5. Run the transaction script : The virtual machine binds the transaction parameters to the formal parameters and executes the transaction script. If this script execution completes successfully, the write operations performed by the script and the events issued by the script are submitted to the global state. If the script fails to execute (for example, due to gas exhaustion or runtime execution failure), then any changes in the script will not be committed to the global state.

6. Run epilogue : Finally, the virtual machine runs the transaction epipilue, charges the user for the cost of the used gas, and increases the serial number of the sender's account. Like prologue, this transaction epilogue is a process of the Move LibraAccount module, and it runs with gas metering disabled. If the execution jumps to step (2), including steps (3), (4), or (5), the epipilogue step will always run. This prologue step and the epilogue step will work together to ensure that all transactions in the book history are done with paid gas. Transactions that do not exceed step (2) will not be attached to the book history. If a transaction exceeds step (2), this prologue step will ensure that the account has enough Libra coins to cover the maximum number of gas units allowed for the transaction. Even if the transaction runs out of gas, the epilogue step can charge the maximum amount.

3, 4 Move programming language

As we have seen, a transaction is a valid wrapper around a Move bytecode program.

Move [10] is a new programming language we created during the design of the Libra protocol, which plays three important roles in the system:

  1. Enable flexible transactions through transaction scripts;
  2. Allow user-defined code and data types, including "smart contracts" through the module;
  3. Support for configuration and scalability of the Libra protocol (see Section 9);

A key feature of the Move language is the ability to define custom resource types that are inspired by linear logic [21]. A resource type used to encode a programmable asset that behaves like a normal program value:

Resources can be stored in data structures, passed as parameters to processes, and so on. However, this Move type system provides special security for resources. Resources cannot be copied and can only be moved. In addition, resource types can only be created or destroyed by modules that declare this type. These guarantees are statically enforced by the Move virtual machine. This allows us to represent Libra coins as a resource type in the Move language (this is different from Ethereum and Bitcoin, which have a special place in their respective languages).

We have published a more detailed article on the design of Move [10]. In the remainder of this section, we briefly outline the key Move concepts for transactional execution: developing Move transaction scripts and modules, and using the virtual machine to execute Move bytecode.

Write a Move program . The Move program has three different representations: source code, optimized intermediate code (IR), and bytecode . We are currently designing the Move source language, which will be an ergonomic language designed to make it easy to write and validate secure code. At the same time, programmers can develop modules and transaction scripts in Move IR. Move IR is sufficient for writing human-readable code, and it can also be converted directly to Move bytecode. Both the future Move source language and Move IR can be compiled into Move bytecode, which is the format used by the Libra protocol.

We use verifiable bytecode as an executable representation of Move for two reasons:

  1. The above security guarantees must apply to all Move programs. Ensuring the guarantees in these compilers is not enough. Malicious parties can always choose to bypass the compiler by writing malicious code directly using bytecode (as part of the transaction execution, running the compiler slows down and complicates execution, and requires the verifier to trust the full compiler code base The correctness), therefore, the protocol enforces all security guarantees for Move through bytecode verification (type safety, reference security, and resource security), thereby avoiding trust in the compiler.
  2. Move has fewer stack-based bytecode instructions than the advanced source language. In addition, each instruction has a simple semantics that can be represented by smaller atomic steps. This reduces the specification footprint of the Libra protocol and makes it easier for developers to spot implementation errors.

Transaction script : The transaction script is the main program of the Libra protocol. The transaction script is responsible for enabling flexible transactions because the script is an arbitrary Move bytecode program. The script can use conditional logic and perform local calculations to invoke multiple programs of the module published in the book state, which means that the script can perform expressive one-time operations, such as paying for a specific set of recipients.

We expect that most transaction scripts will execute a program call that contains a generic function. For example, the LibraAccount.pay_from_sender(recipient_address, amount) program encapsulates the logic for performing a peer-to-peer payment. The transaction script that takes the recipient_address (receiver address) and amount (amount) as parameters and calls this procedure is the same as the Ethereum transport transaction in Ethereum [16].

Module : A module is a unit of code that is published in the state of the ledger. The module is responsible for declaring the structure type and program. Structure values ​​contain data fields that hold primitive values, such as integers or other structure values.

Each structure must be marked as a resource or unrestricted (ie non-resource). Unrestricted structures are not subject to the above copying and destruction restrictions. However, an unrestricted structure cannot contain a resource structure (direct or delivery) and cannot be published in the account state.

From a high dimension, the module/structure/program relationship is similar to the class/object/method relationship in object-oriented programming. However, there are some important differences here. A module can declare multiple structure types (or zero structure types). No data fields can be accessed outside of its declaration module (ie, there are no public fields). The module's process is a static process, not an instance method; there is no concept of this or self in the process. The Move module is similar to the ML style module [22] with no limited version of higher order functions. The Move module is related to the "smart contract" concept of Ethereum and other blockchain platforms, but it is also different. An Ethereum smart contract contains the code and data published in the bookkeeping state. In Libra, the module contains code values, and the resource contains data values. In object-oriented terminology, the Ethereum smart contract is like a singleton object published under a single account address. A module is a way to create a resource, which can create any number of resources that can be published under different account addresses.

Move virtual machine : The Move virtual machine implements the validator and interpreter tasks for the Move bytecode. The bytecode targets the stack-based virtual machine, using the procedure local operand stack and registers. The unstructured control flow is encoded by goto and label.

The developer writes a transaction script or module in Move IR and then compiles it into a Move bytecode. Compilation converts structured control flow constructs (for example, conditions, loops) into unstructured control flows, and converts complex expressions into a small number of bytecode instructions to control an operand stack. The Move virtual machine performs a transaction by verifying and then running the bytecode.

This Move virtual machine supports a small number of types and values: boolean (booleans), unsigned 64-bit integers, 256-bit addresses, fixed-size byte arrays, structures (including resources), and references. The structure field cannot be a reference type, which prevents the reference from being stored in the book status.

The Move virtual machine does not have a heap : local data is allocated on the stack and is released when the dispatcher returns. All persistent data must be stored in the ledger state.

Fourth, verified data structure and storage

After executing the transaction, the verifier converts the changes to the logical data model to a new version of the validated data structure [7, 8, 9] used to represent the database. The short validator for this data structure is a binding commitment to the history of the book, including newly executed transactions. As with transactional execution, the generation of this data structure is also deterministic. The consensus protocol uses this validator to agree on the order of the transactions and the execution of their results (we will discuss the consensus in detail in Section 5). As part of the commit transaction block, the verifier collectively signs the short validator to a new version of the results database.

Using this collective signature, the client can trust the database version to represent the complete, valid, and irreversible state of the database's book history.

The client can query any certifier (or a third-party copy of the database) to read a particular database value and validate the results using a validator and a short certificate.

Therefore, the client does not need to trust the party executing the query to ensure that the result is read correctly.

The data structure in the Libra protocol is based on the Merkle tree and is inspired by other blockchains; however, in some cases we have made slightly different decisions, which we will emphasize below. First, let's briefly discuss the Merkle tree method for creating a validator. Then we describe the validated data structure, starting with the root of the data structure, and then we discuss the substructures. Figure 3 depicts the data structure and provides a visual guide to the content of this section.

P3

Picture 3: (1) The root hash of the historical structure of the book is the verifier of the complete state of the system, ie (2) signed by the quorum verifier. When a transaction is added to the database, the validator (section 4.2) submitted to the book history will grow (indicated by the dashed arrow). Each sub-leaf of the book history is submitted to a (3) TransactionInfo structure. This structure promises (4) the signed transaction (Ti), (5) the list of events generated during the transaction (Ei, Section 4.5), and (6) the state of the transaction (Si, Section 4.3) after execution. This state is a 稀疏Merkle二叉树 with one (7) account spot on each cotyledon.

4, 1 background of the authentication data structure

The authentication data structure allows the verifier V control a short verifier a that forms a constraint commitment to a larger data structure D An untrusted prover P that controls the data structure D , computes f(D) → r and returns r to the verifier (calculation of the calculation of some functions f on the data structure D) and π (proof of the correct calculation result) ). The verifier V can run Verify(a, f, r, π) and return a true ( true ) value if and only if f(D) = r . In the context of the Libra blockchain, the prover is usually the verifier and the verifier is the client that executes the read query. However, the client (even a client with only a partial copy of the database) can act as a verifier and perform validated read queries for other clients.

P4

Figure 4: A Merkle tree that stores D = {0 : s0, . . .} . If f is a function that takes the third item (shown in dotted lines), then r = s2 ,π = [h3, h4] (these nodes are shown with dashed lines). Verify(a, f, r, π) will verify a ? = H(h4∥H(H(2∥r)∥h3)).

The Merkle tree [11] is a common form of authentication data structure used to store mappings between integers and strings. In a Merkle tree of size 2^k , structure D maps each integer key i ∈ [0, 2^k) to a string value si.

The validator consists of the root of the complete binary tree created by the string, marking the cotyledon as H(i||si) and the inner node as H(left||right) , where H is a cryptographic hash function (we call it For the hash) (6). The function f that the prover wishes to verify is a proof that the key-value pair (k, v) in the mapping D.

P verifies the lookup for item i in D by returning a proof π consisting of the labels of siblings of each ancestor of node i . Figure 4 shows the lookup for item 3 in a size 4 Merkle tree. The nodes of item 3 are indicated by dashed lines, and the nodes included in π are indicated by dashed lines.

(Footnote 6: The secure Merkle tree must use different hash functions, hash cotyles and internal nodes to avoid confusion between the two types of nodes. For the sake of simplicity, we omitted this detail in the example, and the Libra protocol uses one. A unique hash function that distinguishes between different hash function types to avoid type-based confusion attacks [23].)

4, 2 book history

Most blockchains starting with Bitcoin [24] maintain a consensus-consistent list of links for each trading block with a block containing a single ancestor hash.

This structure leads to inefficient client. For example, a client that trusts a block B and wants to verify the information in the ancestor block B' needs to acquire and process all intermediate ancestor blocks.

The Libra protocol uses a single Merkle tree to provide a validated data structure for the book history. Figure 3 illustrates the complete data structure supporting the Libra database, including the book history containing transactions, which in turn contain information about database status, events, and accounts. The book history is represented as a Merkle tree that maps the sequential database version number i to a TransactionInfoi structure. Each TransactionInfoi structure contains a signed transaction (Ti), a state validator after performing Ti (Si, discussed in Section 4.3), and an event validator generated by Ti (Ei, discussed in Section 4.5). . Like other Merkle trees, this ledger history supports proof of O(log n) size (where n is the total number of transactions processed) to validate a particular TransactionInfoi query. When the client wants to query the status of version I, or finds an event generated in version I, it will perform a verified lookup on TransactionInfoi using the included status or event list validator.

Specifically, the book history uses the Merkle Tree Accumulator [25, 26] method to form a Merkle tree, which also provides efficient additional operations. This is useful because you can incrementally calculate by appending a new transaction to the old ledger history. The Merkle tree accumulator can also generate a valid proof that the validator a' submits to the ledger information up to j > i has the same history as transaction i, given the accounting information before committer a commits to transaction I. In other words, this proves that a is the prefix of a'. These proofs can effectively verify that a book's historical commitment is a continuation of another commitment.

Trim Storage : The root hash of the book history Merkle accumulator is the validator for the complete state of the system. It commits the state on each existing version of the system, each transaction sent, and each event generated.虽然第4.3节中描述的状态存储允许有效地存储账本状态的多个版本,但验证者可能希望减少以前版本占用的空间。验证者可自由地删除旧状态,因为它们不是处理新事务所必需的。 Merkle树累加器支持修剪历史数据,其只需要O(log n)大小的存储来附加新记录[25]。

系统的任何副本都可以自由保留整个状态,并可以将其数据的真实性跟踪到由共识协议签名的根哈希。副本比验证者更易于扩展。副本不需要得到保护,因为它们不参与共识,可创建多个副本来并行处理读取查询操作。

4、3 账本状态

一个账本状态Si表示版本i中所有账户的状态,作为键值对的映射。密钥基于256位帐户地址,它们的对应值是账户确认者(在第4.4节中讨论)(7)。使用类似于图4的表示法,将映射表示为大小为2^256的一棵Merkle树,虽然一棵大小为2^256的树是一种难以处理的表示,但可以应用优化来形成一棵稀疏Merkle树。图5显示了两种用于将简单实现(1)转换为有效实现的优化方法。首先,完全由空节点组成的子叶将替换为证书透明度系统(certificate transparency system) [27]中使用的占位符值( 2 ) 。这种优化创建了一个可跟踪大小的表示,而没有实质性地改变Merkle树的证明生成。然而,子叶总是存储在二叉树的底层,这意味着结构需要在每次子叶修改时计算256个哈希。第二种优化,用单个节点( 3 )替换由一个子叶组成的子树。预期中,任何给定项的深度都是O(log n) ,其中n是二叉树中项目数。这种优化减少了在映射上执行操作时要计算的哈希数。

(脚注7: 地址的哈希作为密钥。即使地址是作为公钥的哈希,恶意方也可以在与真实地址几乎冲突的地址创建一个新帐户。虽然无法从此帐户发送任何事务,因为与该帐户地址对应的私钥未知,但树中存在此近似冲突,会增加邻近地址的证明长度。在将地址用作密钥之前对其进行哈希处理,可减少此类攻击的影响。)

P5

图5 : 一棵稀疏Merkle树存储D = {01002 : A, 10002 : B, 10112 : C}的三个版本有效实现,如Libra Core,可以优化它们的磁盘布局和节点的批处理层,以避免在查找过程中的请求。 (8)

(脚注8: 这种优化使磁盘性能与以太坊中使用的16元帕特里夏Merkle树方法相似,但其证明时间更短。)

当稀疏Merkle树在执行事务后更新时,新的树将重用上一版本的未更改部分,形成一个持久的数据结构[28,29]。如果一个事务修改了系统中n个帐户中的m个帐户,则在与以前版本不同的新账本状态树中平均创建了O(m · log n)个新分支和子叶。这种方法允许验证者有效地存储账本状态的多个版本。此功能还允许在处理事务后高效地重计算账本状态验证器。

我们考虑过基于AVL树结构 ,它比稀疏Merkle二叉树结构提供了更优的最坏情况证明长度[30]。然而,稀疏Merkle树方法允许实现者进行优化,例如跨服务器共享存储以及并行根哈希计算。

4、4 账户

从逻辑层来讲,帐户是存储在帐户地址下的资源与模块的集合。从物理层来讲,帐户被视为字节数组值访问路径的有序映射。访问路径是一个分隔字符串,类似于文件系统中的路径。

在协议的第一次迭代中,我们将一个帐户序列化(serialize)为按访问路径排序的访问路径和值列表。帐户的验证器是此序列化表示的哈希。注意,此表示要求在对帐户进行任何修改之后,对整个帐户重新计算验证器。这个操作的开销是O(n) ,其中n是完整帐户的字节表示长度。此外,从客户端读取,需要完整的帐户信息来验证其中的任何特定值。

我们在账户中存储数据的策略与其他系统(如以太坊)不同(9)。我们的方法允许Move语言通过将帐户表示为访问值路径的有序映射,以提供更好的编程抽象。这种表示允许Move通过虚拟机有效地管理资源的保护。Move鼓励每个用户在他们自己的账户当中持有资源。在最初发布的Libra当中,我们针对小客户进行了优化。而在未来的版本中,我们可能会考虑支持更高效的结构来代表更大的账户,比如说Merkle AVL二叉树结构 [30]。

(脚注9: 相反,以太坊[16]使用Merkle树将数据存储为稀疏memory映射,该二叉树表示256位key到256位值的无序映射。这种方法使以太坊能够有效地处理大的账户。)

账户收回和重加工 :我们预计,随着系统的使用,最终与帐户相关的存储增长可能会成为一个问题。正如gas鼓励负责任地使用计算资源(见第3.1节),我们预计存储可能需要一种租赁机制。我们正在评估最适合生态系统的租赁机制。我们讨论了一个可应用于任何确定过期时间的策略选项,在时间到期之后,数据就可以被收回。

在每个影响账户的事务执行之后,虚拟机计算逻辑过期时间,在该时间内,为帐户分配的存储可被释放。虚拟机可自由地应用任何确定性方法来确定到期时间。这种政策的一个例子是收取以Libra币计价的费用,该费用是基于账户的存储时间及其大小确定的。

帐户的验证器表示为H(H(AccountBlob)||(ExpirationTime) ,它对帐户的过期时间进行编码。到期后,虚拟机拒绝访问帐户,从而引发一个错误。由于AccountBlob是不可访问的,因此在ExpirationTime之后,验证者可以自由删除此数据。然而,验证者允许事务在过期后通过重新计算其内容来重新激活帐户。该事务必须包含AccountBlob的预映射(preimage),并具有包含进一步存储成本的关联交易费用。通过重新计算和检查与帐户关联的哈希值(不删除)来确保重新获取内容的真实性。这种租赁实现方法是对现有帐户收回方案的改进,而现有方法要求第三方发送一个事务来删除帐户的存储。

4、5 事件

Ei 是Ti执行期间发出的事件列表,每一个事件都以一个子叶存储在Merkle树中,该二叉树Ei形成一个验证器。事件被序列化为form (A, p, c)的一个元组,它表示发出事件(A)、数据有效负载(p)以及计数器值(c)的事件结构访问路径。这些元组按Ti执行期间发出的事件顺序j进行索引。根据惯例,我们把事件j→(a,p,c)包含在Ei中,表示为(j,(A, p, c)) ∈ Ei 。Ei的验证器包含在TransactionInfoi中,因此,验证者可构造一个包含证明,证明在第i个事务中,第j个事件是(A, p, c)。

包含在每个事件中计数器c,在允许客户端检索给定访问路径A的事件列表方面发挥了特殊作用。客户端也可以确保列表是完整的。在Move语言中,表示具有访问路径A的事件的事件结构,为其已发出的事件总数维护一个计数器C。

此计数器存储在账本状态中,并在每次事务执行,在访问路径A上发出事件后进行递增。

客户端可获取最近账本状态的验证器,查询与事件结构关联的计数器以获取访问路径A,并检索事件总数C。

然后,客户端可以查询不受信任的服务,以获取访问路径A上的事件列表。查询响应由一组元组(i, j, A, p, c)组成,每个元组对应一个事件,其中i是发出事件的事务序列号, j是此事务中事件发出的顺序。可以为每个事件提供(j,(A, p, c)) ∈ Ei的关联包含证明。由于客户端知道访问路径A发出的事件总数,因此它们可确保不受信任的服务提供了此数量的不同事件,并按其序列号0 ≤ c < C对其进行排序。这使客户端确信为A返回的事件列表是完整的。

此方案允许客户端保存对访问路径A上事件的已验证订阅。客户端可定期为事件访问路径A触发总计数器C,以确定订阅是否是最新的。例如,客户端可使用它在监视的地址上维护对传入付款事务的订阅。不受信任的第三方服务可为按访问路径索引的事件提供源,而客户端可有效地验证返回的结果。

五、拜占庭容错共识

拜占庭容错共识协议允许一组验证者创建单个数据库的逻辑层次。这种共识协议在验证者之间复制提交的事务,对当前数据库执行潜在的事务,然后就事务顺序和结果执行的绑定承诺达成一致。因此,所有验证者都可以按照状态机器复制范式[31]为给定的版本号维护相同的数据库。Libra 区块链使用了一种HotStuff [13]共识协议的变体,叫做LibraBFT协议。在传统的DLS[32]和PBF[33]以及更新的Casper[34]和Tendermint[35]的部分同步模型中,它提供了安全性和活力。本节概述LibraBFT共识机制中的关键决策。LibraBFT的完整报告[12]中包含了更详细的分析,包括安全性和活性的证明。

即使存在拜占庭错误[36],验证者之间也必须就数据库状态达成一致。拜占庭错误模型允许一些验证者不受约束地任意偏离协议,除了在计算上的界限(因此不能破坏密码学假设)。拜占庭错误是最坏的情况下的错误,在这种情况下,验证者串通一气,恶意破坏系统。一种可以容忍由恶意或被黑客攻击的验证者引起的拜占庭错误的共识协议,也可以减轻任意的硬件和软件故障。

LibraBFT假设一组3f + 1的投票分布在一组验证者中,这些验证者可能是诚实的,也可能是拜占庭式的。当最多f票由拜占庭验证者控制时,LibraBFT仍然是安全的,它可以防止双重支出和分叉等攻击。LibraBFT保持活性——向客户端提交事务,只要存在一个全球稳定时间(GST)之后,诚实的验证者之间的所有消息将在一个最大的网络延迟δ(这是引入的部分同步模型[32]发送到其他诚实的验证者。除了传统的保证之外,LibraBFT还在验证者崩溃和重启时维护安全性——即使所有验证者同时重启。

LibraBFT的概述 :验证者接收来自客户端的交易,并通过一个共享的mempool协议来彼此共享这些事务。然后LibraBFT协议按顺序进行。在每轮中,都有一个验证者会扮演领导者(leader)的角色,并提出一个事务区块来扩展一个包含完整的以前事务历史的经认证的区块序列(请参阅下面的法定人数证书quorum certificate)。验证者接收提议的区块并检查其投票规则,以确定是否应投票支持对该区块进行验证。这些简单的规则确保LibraBFT的安全性——它们的实现可以被清晰地分离和审计。如果验证者打算为这个区块投票,它将执行该区块的事务,而不受外部影响。这将导致验证器对数据库的计算,从而促成了区块的执行。这个验证者然后发送一个为这个区块和数据库验证人进行的投票给这个leader。leader收集这些投票,形成一个法定人数证书(quorum certificate(QC)),它为这个区块提供2f +1票的证据,并将该QC广播给所有验证者。

当满足连续的3-chain提交规则时,区块就会被提交。如果在第k轮有QC,并且在第k + 1轮和第k + 2轮有两个区块和QC确认,则区块被提交。提交规则最终允许诚实的验证者提交一个区块。LibraBFT保证所有诚实的验证者最终都将提交该区块(以及从它链接的区块的序列)。一旦提交了一个区块序列,执行事务所产生的状态就可以持续下去并形成一个复制的数据库。

HotStuff范例的优点 :我们针对验证者的性能、可靠性、安全性、健壮实现的易用性和运营开销等方面评估了几个基于BFT的协议。我们的目标是选择一种协议,该协议最初将支持至少100个验证者,并且能够随着时间的推移发展到支持500 – 1000个验证者。选择HotStuff协议作为LibraBFT的基础有三个原因:(1)安全性参数的简单性和模块化;(2)容易将共识与执行相结合;(3)早期实验中的性能表现良好。

这个HotStuff协议分解为安全模块(投票和提交规则)以及活性模块(pacemaker)。这种解耦提供了独立开发和并行测试不同模块的能力。由于投票和提交规则简单,协议安全性易于实现和验证。将执行作为共识的一部分进行集成是很简单的,以避免在基于领导者的协议中由非确定性执行引起的分叉问题。最后,我们的早期原型证实了HotStuff中独立测量的高吞吐量和低事务延迟[13]。我们没有考虑基于工作量证明(PoW)的协议,因为它们的性能差,能源(和环境)成本高[24]。

HotStuff扩展及修改 :在LibraBFT中,为了更好地支持Libra生态系统的目标,我们扩展和调整了核心HotStuff协议,并以多种方式进行实现。

重要的是,我们重新制定了安全条件,并提供安全、活力和乐观反应的扩展证明。我们还实现了一些附加功能。首先,我们让验证者集体签署区块的结果状态,而不仅仅是事务序列,从而使协议更能抵抗不确定性错误。这还允许客户端使用QC来验证从数据库中读取的内容。第二,我们设计了一个传出明确超时的pacemaker资源管理器,验证者依赖于这些pacemaker中的法定数量来进入下一轮,而不需要同步时钟。第三,我们设计了一个不可预测的leader选举机制,其中一轮的leader由最新提交区块的提议者使用可验证随机函数(VRF) [37]确定。

这种机制限制了恶意方对leader发起有效拒绝服务攻击的时间窗口。第四,我们使用聚合签名[38]来保留签署QC的身份验证者。这使我们能够向有助于QC的验证者提供激励(详见9.3节内容)。它也不需要复杂的阈值密钥设置[39]。

验证者管理 :Libra协议使用了一个Move模块管理一组验证者。这在共识系统和定义可信验证者集的密码学经济系统之间创建了一个清晰的分离。我们将在第9.2节中讨论Libra区块链对该合约的实施。以这种方式抽象验证者管理,是通过定义Move中的核心区块链原语而获得的灵活性的一个例子。

对验证者组的每次更改,都定义了一个新的epoch期。如果一个事务导致验证者管理模块更改验证者集,该事务将是当前epoch期提交的最后一个事务。该区块或该epoch期以后的区块中的任何后续事务,都将被忽略。一旦事务被提交,新的验证者集就可开启共识协议的下一个epoch期。

在一个epoch期内,客户端不需要同步每个QC。由于已提交的QC包含对所有以前状态的绑定承诺,客户端只需要同步到当前epoch期的最新可用QC。如果此QC是其epoch期的最后一个,则客户端可以看到新的一组验证者,更新其epoch,然后再次同步到最新的QC。如果验证者选择按照第4.2节的描述删减历史记录,那么它需要保留至少足够的数据,以向客户端提供验证者集更改的证明。

验证者管理合约,必须提供满足由共识协议要求的安全属性的验证者集。拜占庭验证者不能控制超过f的投票权。投票权必须在epoch期间以及epoch之后的一段时间内保持诚实,以允许客户端与新配置同步。离线时间超过此时间段的客户端需要使用一些外部真实性源重新同步,,以获取他们信任的检查点(例如,从其用于接收更新软件的源重新同步)。此外,验证者集不能过于频繁地转动,以致于破坏系统的性能,或者导致客户端为过多数量的epoch期下载QC。我们计划研究最佳的epoch期长度,预计这个时间会小于1天。

六、网络设计

Libra协议,与其他去中心化系统一样,需要一个网络基层来支持其成员之间的通信。验证者之间的共识和共享的mempool协议都需要通过互联网进行通信,如第5节和第7节所述。

这个网络层在设计上是通用的,灵感来自libp2p [40]项目。它目前提供了两个主要接口:(1) 远程过程调用(RPC)和(2) DirectSend ,实现了向单个接收方发送“即发即弃”(fire-and-forget)类型消息。

验证者之间的网络实现为一种点对点系统,使用了Multiaddr [41]方案进行对等(peer)寻址,使用TCP用于可靠传输,Noise[42]用于身份验证和完整的端到端加密,Yamux[43]用于在单个连接上的多路复用子流,push式gossip用于对等节点发现。每个新的子流都被分配了一个由发送方和接收方都支持的协议。每个RPC和DirectSend类型都对应一个这样的协议。

这个网络系统使用与共识系统相同的验证者集管理智能合约,作为当前验证者集的一个真实性来源。这种合约持有每个验证者的网络公钥和共识公钥。一个验证者通过监视这个智能合约中的更改来检测验证者集中的更改。要加入这个验证者间网络,一个验证者必须使用这个合约定义的最新验证者集中的网络公钥进行身份验证。启动一个验证者则需要一组种子对等节点(peers),首先对要加入的验证者进行身份验证,使其成为验证者间网络的合格成员,然后与这个新对等节点共享它们的状态。

Libra协议中的每个验证者都维护着系统的完全成员关系视图,并直接连接到需要与之通信的任何验证者。不能直接连接的验证者则被假定为属于系统拜占庭错误的范围。

p6

图6:写入事务通过Libra Core内部组件的流程

每个验证者的健康信息,使用周期性活性试样来确定,不会在各验证者之间进行共享;相反,每个验证者直接监视它的对等节点验证者的活动。我们期望这种方法在需要部分成员视图、复杂的故障检测器或通信中继之前,可以扩展到几百个验证者。

七、Libra Core实现

为了验证Libra协议,我们构建了一个开源的原型实现Libra Core[6]。这个实现是用Rust语言编写的, 我们选择Rust是因为这种语言专注于实现安全的编码实践,及其对系统编程的支持和高性能属性。我们将系统的内部组件拆分为gRPC [44]服务。模块化允许更好的安全性;例如,共识安全组件可以在单独的进程中运行,甚至可以在不同的机器上运行。

Libra 区块链的安全性取决于验证者、Move程序和Move 虚拟机的正确实现。目前,我们正在解决Libra Core存在的这些问题。这包括隔离代码中有助于一个验证者在共识期间签署一个事务区块的部分,并应用措施来增强这些组件正确性的保证(例如,广泛的测试、正式规范和正式验证)。高保证性方面的工作,还包括确保代码依赖项的安全性(例如,代码评审过程、源代码控制、开源库依赖项、构建系统和版本发布管理)。

7.1 写入请求生命周期

图6展示了Libra Core中支持对去中心化数据库进行写入操作的事务的生命周期。本节深入研究事务如何通过验证者的内部组件进行流动。

当客户端希望向数据库提交事务时,就会发起一个请求(request)。我们目前假设客户端有一个带外机制来查找要提交事务的验证者地址——这一机制的最终版本尚未设计出来。

准入控制(Admission control)。在接收一笔事务时,一个验证者的准入控制组件会执行初始语法检查(1)抛弃那些永远不会被执行的畸形事务。尽早进行这些检查可避免把资源用在垃圾事务上。准入控制可能访问VM(2),VM使用存储组件执行检查,如确保账户有足够的余额支付事务所需的gas。接纳控制组件设计,组件的验证器可以运行多个实例。这种设计允许验证者处理规模的事务和减轻拒绝服务攻击。这个准入控制组件的设计,可以使一个验证者运行多个组件实例。这种设计允许验证者扩展传入事务的处理,并减少拒绝服务攻击。

Mempool 。通过准入控制组件的检查的事务将被送入验证者的Mempool,Mempool容纳着等待在内存缓冲区被执行的事务(3)。Mempool中可能容纳着来自同一个地址的多笔事务。因为Mempool可以一次处理多笔事务,它能执行检查,比如验证同一地址上的一系列操作是否都能够支付准入控制系统无法支付的gas。使用这个共享Mempool协议(4),一个验证者可以在自己的Mempool中与其他验证者共享事务,将从其他验证者接收的事务放到自己的Mempool中。

共识。验证者通过从其Mempool中选择一系列事务来创建区块。当验证者充当共识协议的领导者(leader)时,它从其Mempool(5)中组成一个事务区块。它将此事务区块作为一个提议发送给其他验证者(6)。共识组件负责协调所有验证器之间关于这些事务区块的顺序及其使用LibraBFT协议的执行结果的协议(第5节)。

事务执行。作为达成协议的一部分,事务区块被传递给执行器组件(7),负责管理VM(8)中事务(第3节)的执行。这种执行发生在事务达成协议之前。这种早期执行是安全的,因为事务是具有确定性的,并且没有外部影响。在执行区块中事务之后,执行组件会构建一个这些事务的账本历史(第4.2节)。这个账本历史验证者将返回到共识组件(9)。

这个leader然后将尝试组成一个法定数量证书链(第5节)来就这个账本验证者达成共识,其中每一个证书都由一组验证者来进行签名,至少获得2f+1个投票。

提交一个区块。一旦共识算法达成一致,任何诚实的验证者都能确保所有其他诚实的验证者最终将提交一个一致的账本历史。验证者可以从执行组件的缓存中读取区块执行的结果并更新其本地数据库存储(10)。

7.2 读取请求生命周期

客户端还可以提交读取请求,为去中心化数据库中帐户的内容查询验证者。读取请求不会改变状态,可以在本地处理,而不需要经过共识。读取请求被提交到验证者的准入控制组件。准入控制组件执行初步检查,从存储中读取数据,然后将结果发送回客户端。这个响应附带一个法定数量证书(如第5节中描述),其中包含一个根哈希(如第4节中描述)。QC允许客户端对查询的响应进行身份验证。这个客户端使用与虚拟机相同的技术,使用逻辑数据模型(第2节)来解释帐户的原始字节。例如,要读取地址a 的账户余额,客户端需要解码嵌入到该帐户的原始字节中的LibraCoin.T资源。

八、 性能

Libra协议的使命是支持一个全球金融基础设施。性能是实现这一目标的一个组成部分。我们将讨论区块链性能的三个组成部分:

  1. 吞吐量:区块链每秒可处理的事务数;
  2. 延迟:客户端向区块链提交事务与另一方看到这笔事务之间的时间;
  3. 容量:区块链存储大量帐户数的能力;

Libra协议还处于原型阶段,因此我们还没有具体的性能指标,但我们预计Libra协议在最初发布时可支持每秒1000笔支付事务,事务提交到确认的最终时间为10秒 。随着时间的推移,我们希望能够增加系统的吞吐量,以满足网络的需求。 我们预计,许多支付事务将发生在链下进行,例如,在托管钱包内或通过使用支付通道 [45]。 因此,我们认为链上每秒支持1000笔事务,将满足生态系统的初始需求 。Libra协议旨在通过以下几种方式来实现这些目标:

协议设计:Libra协议的很多元素都是基于性能挑选的。例如,LibraBFT算法在三轮网络通信中获得共识结果,不需要任何实时延迟就区块进行提议或投票。这使得提交延迟只受验证者之间的网络延迟的限制。

我们还考虑采用并行化和分片(sharding)来选择协议的元素 。计算验证者的稀疏Merkle树方法允许跨多台机器对数据库进行分片((这增加了容量)或并行处理更新(这增加了吞吐量)。初始事务验证(包括计算昂贵的签名验证)也可以实现并行化。

验证者挑选:与大多数服务一样,Libra区块链的性能取决于操作它的底层验证器的性能。去中心化与性能之间存在着一种妥协。对资源非常充足的验证者需要,限制了可执行该角色实体的数量。然而,资源极度不足的验证者的存在,将限制整个系统的性能。

我们倾向于采取一种平衡的方法,将目标锁定在可以在商用硬件上运行的节点,许多实体都能买到这些硬件。但是,我们假设了这些节点运行在服务器级别硬件上,并且与数据中心能够连接良好。根据我们进行的一次近似分析显示,该系统很可能能满足每秒1000笔事务的需求。

带宽:如果我们假设每笔事务需要5 KB的流量——包括通过mempool接收事务、重播事务、接收来自leader的区块以及复制到客户端的成本——那么验证者需要40 Mbps的网络连接来支持每秒1000笔事务。这种级别的带宽还是能够广泛获得的。

CPU:签名验证是与支付转换操作相关的重要计算成本。我们设计了允许并行验证事务签名的协议。采用Modern签名方案,一个普通商用CPU就可以支持每秒1000多个事务验证。

磁盘:从大型服务器供应商那里,我们可以获得16TB SSD存储的服务器。由于当前状态是验证者处理事务所需的惟一信息,所以我们估计,如果帐户大小约为4 KB(包括所有形式的开销),那么这将使得验证者可存储40亿个帐户。我们预计,磁盘存储的发展、验证器向多个分片的扩展,以及经济激励措施将允许商用系统保持使用这个系统。

历史数据的增长可能会超出单个服务器所能处理的数量。验证者可随意丢弃那些在处理新事务的过程中所不需要的历史数据(参见第4.2节);但是,那些希望查询来自过去事务事件的客户端可能对这些数据感兴趣。由于验证者签署了对该数据的绑定承诺,客户端可自由地使用任何系统访问数据,而不必信任交付数据的系统。我们希望这种类型的读取流量能够很容易地通过并行进行扩展。

九、 用Move来实施Libra的生态系统政策

Libra 区块链是一个独特的系统,它平衡了传统金融网络的稳定性和由加密经济手段管理的系统所提供的开放性。正如我们在第1节中讨论的,Libra协议旨在支持Libra生态系统实现新的经济[4]和治理[3]策略。该协议指定了一个灵活的框架,该框架在关键系统组件(如本地货币、验证者管理和事务验证)中是参数化的。在本节中,我们将讨论Libra 区块链如何使用Move编程语言定制这些组件。我们的讨论集中在协调网络参与者和验证者激励的挑战,以及支持Libra生态系统的运行、治理和演化的挑战。

9.1 Libra币

许多加密货币没有真实世界资产的支持。因此,投资和投机一直是这些加密货币主要用例。投资者购买这些货币时,往往认为它们会大幅升值,然后可以以更高的价格卖出。对这些货币长期价值的信念波动,导致了相应的价格波动,有时会导致价值的大幅波动。

为了推动广泛采用,Libra被设计成一种货币,任何用户都会知道,Libra今天的价值与明天甚至更远未来的价值都是接近的。储备是实现价值保值的关键机制。通过储备,每枚币都有一套稳定的流动资产作为后盾。有了与储备挂钩的一群具有竞争力的流动性提供者的存在,用户就可以放心,他们所持有的任何一枚币都可以以高于或低于底层资产价值的狭窄价差,以法定货币出售。这从一开始就赋予了Libra内在价值,并有助于防范现有加密货币所经历的投机性波动。

Libra的储备资产是一个低波动性资产的集合,包括来自稳定且声誉良好的国家央行发行的法币和政府证券。由于Libra的价值实际上与一篮子法定货币挂钩,从任何特定货币的角度来看,Libra的价值都会有波动。储备金的组成旨在减轻这些波动的可能性和严重性,特别是在负面方向(例如,经济危机中)。为此,该货币篮子的结构考虑到了资本保值和流动性。

该储备由Libra协会管理(见第9.2节),该协会发布了一份关于该储备运行的详细报告[4]。用户不直接与储备接口。相反,为了支持更高的效率,会有一些授权转售商,他们是由Libra协会唯一授权的实体,来处理大量的法定货币和Libra在储备中的流入和流出。这些授权转售商与事务所和其他买卖加密货币的机构相结合,为那些希望将现金与Libra进行来回兑换的用户提供流动性。

为了实施这一计划,Libra的合约允许Libra 协会在需求增加时铸造新的Libra币,以及在需求减少时销毁它们 。该协会不制定货币政策。它只能根据授权经销商的要求铸造和销毁币。用户不必担心这种关联会导致通胀或货币贬值:要铸造新硬币,必须有相应的法定存款准备金。

使用Move自定义Libra合约的能力,允许在不修改底层协议或实现该协议的软件的情况下定义此计划。此外,还可以创建其他功能,比如需要多个签名来铸造货币和创建有限数量的密钥来提高安全性。

9.2 验证者管理和治理

共识算法依赖于验证者集管理Move模块来维护当前的验证者集,并管理验证者之间的投票分配。这种合约负责维护一个验证者集,其中3f + 1的总投票中最多有f票由拜占庭验证者控制。

最初,Libra区块链只向创始成员(Founding Members)授予投票权,这些实体:(1)满足一组预定义的创始成员资格标准[46],(2)拥有Libra投资代币(Libra Investment Tokens)。这些规则有助于确保对拥有一个安全且活动的验证者集的安全性需求。使用创始成员资格标准确保了创始成员都是已建立起声誉的组织,使其不太可能出现恶意行为,并暗示他们将勤奋地捍卫自己的验证者来抵御外部攻击。Libra投资代币代表对准备金利息回报的预期,进一步激励验证者去维持系统的运行。由于储备中的资产风险低、收益低,只有当网络成功、储备规模大幅增长时,早期投资者才能获得超额回报。

虽然这种评估验证者资格的方法是对传统许可区块链(通常形成一组封闭的业务关系)的改进,但我们希望Libra 区块链完全没有许可。为此,我们计划逐步过渡到权益证明(PoS)[47]系统,在该系统中,验证者的投票权与他们所持有的Libra币数量成正比。这将把生态系统的治理移交给它的用户,同时通过要求验证者持有稀缺资源并将它们的动机与健康系统操作结合起来,以防止Sybil攻击[48]。这种过渡需要(1)生态系统足够大,以防止单个坏行为者造成破坏;(2)为不想成为验证者的用户提供一个具有竞争性和可靠的委托市场;(3)解决Libra在Staking过程中面临的技术和可用性挑战。

Libra生态系统治理的另一个独特点是验证者形成了一个真实世界的实体,即非盈利的Libra协会,由一个验证者委员会管理。该协会的每一个理事会成员代表着每个验证者。理事会中成员的投票权重与共识协议中验证者的投票权重相同。协会执行的任务包括管理储备、评估验证者资格标准以及指导Libra协议的开源开发。

Move使将验证器管理和治理规则编码为一个模块成为可能。Libra投资代币可以使用Move资源来实现。Move通过将投资代币或Libra币包装在资源中,从而防止获得底层资产,从而允许对它们进行抵押。已抵押的资源可用于计算验证者的投票权。这个合约可以配置变更生效的时间间隔,以减少验证者集的变动。

Libra 协会的运作也得到了Move的帮助。由于该协会是储备的运营商,它可以创建Move模块,将Libra的铸造和销毁权力委托给与授权经销商进行交互的操作部门。该业务部门还可以评估潜在创始成员是否符合资格标准。Move允许灵活的治理机制,比如允许理事会行使其权力,通过投票收回其授权。

该协会发布了一份详细的文件,概述了其拟议的结构[3]。协会中的所有治理都源于验证者理事会——该理事会拥有最终的权利来维护提供给协会的任何授权。因此,随着验证者集从最初的创始成员集更改为基于PoS的集,整个Libra生态系统的治理也在不断发展。

9.3 验证者的安全与激励

在初始设置中,使用创始成员作为验证者,我们认为每个验证者的机构声誉和经济激励足以确保拜占庭验证器控制的投票不超过f。然而,在未来,一个以币所有权为代表的开放系统将需要一个完全不同的市场设计。我们已开始了解基于利益相关者和消费者对钱包和其他代表的信心的区块链系统的治理和均衡结构。在这个过程中,我们在Libra方法和更成熟的方法(如工作量证明(PoW))之间确定了新的市场设计妥协。

然而,要确定如何在确保网络安全和效率的同时,还能最好地保持生态系统中的长期竞争,这需要更多的研究。此外,由于基于份额(stake)的治理引入了对影响力的路径依赖,因此有必要探索保护较小利益相关者和服务提供者的机制。

Move允许灵活界定相关激励计划,如gas定价或staking。例如,通常讨论的stake slashing机制可以在Move中实现,方法是锁定stake一段时间,如果验证者违反LibraBFT算法的规则,影响安全性,则自动惩罚验证器。

类似地,当验证者在LibraBFT算法中投票时,这些投票可以记录在数据库中。该记录允许Move模块基于算法中的参与度来分发奖励,从而激励验证者保持活动。Libra储备的利息和gas支付也可以作为激励的来源。这两个来源都由Move模块管理,这增加了它们分配的灵活性。虽然需要更多的研究来设计一种方法来支持Libra生态系统的进化,但Move的灵活性确保了所需的方法可以在对Libra协议进行很少(如果有的话)更改的情况下实现。

十、 Libra接下来要做什么?

我们为Libra协议提出了一个提案,允许一组验证者提供一个去中心化数据库来跟踪可编程资源。我们讨论了Libra协议的一个开源原型——Libra Core,并展示了为智能合约引入的Move编程语言如何允许Libra协议实现Libra生态系统的独特设计。

本文描述的协议和实现目前都处于原型阶段。我们希望从新成立的Libra协会和更广泛的社区收集反馈,把这些想法变成一个开放的金融基础设施。我们目前正在运行一个测试网络,以允许社区对这个系统进行试验。

我们正致力于这个系统的首次启动,为了将其保持在可管理的范围内,我们计划在第一个版本中进行几个简化。在系统的早期,使用一组外部认可的创始成员减少了对共识激励系统的需求,并允许更快的更新速度。我们预计只对系统定义的模块使用Move语言,而不是让用户定义自己的模块,这将使Libra生态系统能够在完全形成Move语言之前启动。这还允许在不损害使用Move定义核心系统行为所带来的灵活性的情况下中断所做的更改。然而,我们打算在Libra协议的未来版本中提供对Move语言的开放使用。

最后,我们目前正在Libra协会的框架内工作,以启动这个新生态系统背后的技术基础设施。我们发布了一个路线图[50]的工作,我们计划为支持这个启动做出贡献。Libra协会的首要目标之一是将Libra的生态系统迁移到一个没有许可的系统中。我们已经记录了[5]在进行此迁移时所面临的技术挑战。该协会的开源社区[6]提供了有关如何开始使用Libra测试网、试用Move语言和为Libra生态系统做出贡献的信息。

Acknowledgement

感谢以下人士对本文的讨论和反馈:

Adrien Auclert,Morgan Beller,Tarun Chitra,James Everingham,Maurice Herlihy,Ravi Jagadeesan,Archana Jayaswal,Scott Duke Kominers,John Mitchell,Rajesh Nishtala, Roberto Rigobon,Jared Saia,Christina Smedley,Catherine Tucker, Kevin Weil,David Wong,Howard Wu,Nina Yiamsamatha,和Kevin Zhang。

Reference

[1] The Libra Association, “An Introduction to Libra,” https://libra.org/en-us/whitepaper.

[2] C. Catalini and JS Gans, “Some simple economics of the blockchain,” WP No. 22952, National Bureau of Economic Research, 2016.

[3] The Libra Association, “The Libra Association,” https://libra.org/en-us/association-council-principles.

[4] C. Catalini et al., “The Libra reserve,” https://libra.org/about-currency-reserve.

[5] S. Bano et al., “Moving toward permissionless consensus,” https://libra.org/permissionless-blockchain.

[6] The Libra Association, “Libra developers,” https://developers.libra.org/.

[7] PT Devanbu et al., “Authentic third-party data publication,” in Data and Application Security,Development and Directions, IFIP TC11/ WG11.3 Fourteenth Annual Working Conference onDatabase Security, Schoorl, The Netherlands, August 21-23, 2000, 2000, pp. 101–112.

[8] M. Naor and K. Nissim, “Certificate revocation and certificate update,” IEEE Journal on Selected Areas in Communications, vol. 18, no. 4, pp. 561–570, 2000.

[9] R. Tamassia, “Authenticated data structures,” in Algorithms – ESA 2003, 11th Annual European Symposium, Budapest, Hungary, September 16-19, 2003, Proceedings, 2003, pp. 2–5.

[10] S. Blackshear et al., “Move: A language with programmable resources,” https://developers.libra.org/docs/move-paper.

[11] RC Merkle, “A digital signature based on a conventional encryption function,” in Advances in Cryptology – CRYPTO '87, A Conference on the Theory and Applications of Cryptographic Techniques, Santa Barbara, California, USA, August 16-20, 1987, Proceedings, 1987, pp. 369–378.

[12] M. Baudet et al., “State machine replication in the Libra Blockchain,” https://developers.libra.org/docs/state-machine-replication-paper.

[13] M. Yin et al., “Hotstuff: BFT consensus in the lens of blockchain,” 2018. [Online]. Available:https://arxiv.org/abs/1803.05069

[14] PA Bernstein, V. Hadzilacos, and N. Goodman, “Concurrency control and recovery in database systems.” Addison-Wesley, 1987.

[15] DP Reed, “Naming and synchronization in a decentralized computer system,” Ph.D. dissertation, Massachusetts Institute of Technology, Cambridge, MA, USA, 1978.

[16] G. Wood, “Ethereum: A Secure Decentralised Generalised Transaction Ledger,” http://gavwood.com/paper.pdf, 2016.

[17] G. Bertoni et al., “Keccak,” in Advances in Cryptology – EUROCRYPT 2013, 32nd Annual International Conference on the Theory and Applications of Cryptographic Techniques, Athens, Greece, May 26-30, 2013. Proceedings, 2013, pp. 313–314.

[18] S. Josefsson and I. Liusvaara, “Edwards-curve digital signature algorithm (EdDSA),” RFC, vol.8032, pp. 1–60, 2017.

[19] A. Pfitzmann and M. Köhntopp, “Anonymity, unobservability, and pseudonymity—a proposal for terminology,” in Designing privacy enhancing technologies, 2001, pp. 1–9.27

[20] BC Pierce, “Types and programming languages.” MIT Press, 2002, ch. 19.

[21] J. Girard, “Light linear logic,” Inf. Comput., vol. 143, no. 2, pp. 175–204, 1998.

[22] R. Milner, M. Tofte, and R. Harper, “Definition of standard ML.” MIT Press, 1990.

[23] “Leaf-node weakness in Bitcoin merkle tree design,” https://bitslog.com/2018/06/09/leaf-nodeweakness-in-bitcoin-merkle-tree-design/.

[24] S. Nakamoto, “Bitcoin: A Peer-to-Peer Electronic Cash System,” https://bitcoin.org/bitcoin.pdf,2008.

[25] SA Crosby and DS Wallach, “Efficient data structures for tamper-evident logging,” in 18thUSENIX Security Symposium, Montreal, Canada, August 10-14, 2009, Proceedings, 2009, pp.317–334.

[26] L. Reyzin and S. Yakoubov, “Efficient asynchronous accumulators for distributed PKI,” in Security and Cryptography for Networks – 10th International Conference, SCN 2016, Amalfi, Italy,August 31 – September 2, 2016, Proceedings, 2016, pp. 292–309.

[27] B. Laurie, A. Langley, and E. Käsper, “Certificate transparency,” RFC, vol. 6962, pp. 1–27,2013.

[28] JR Driscoll et al., “Making data structures persistent,” J. Comput. Syst. Sci., vol. 38, no. 1,pp. 86–124, 1989.

[29] C. Okasaki, “Purely functional data structures.” Cambridge University Press, 1999.

[30] L. Reyzin et al., “Improving authenticated dynamic dictionaries, with applications to cryptocurrencies,” in Financial Cryptography and Data Security – 21st International Conference, FC 2017,Sliema, Malta, April 3-7, 2017, Revised Selected Papers, 2017, pp. 376–392.

[31] FB Schneider, “Implementing fault-tolerant services using the state machine approach: A tutorial,” ACM Computing Surveys (CSUR), pp. 299–319, 1990.

[32] C. Dwork, N. Lynch, and L. Stockmeyer, “Consensus in the presence of partial synchrony,”Journal of the ACM (JACM), vol. 35, no. 2, pp. 288–323, 1988.

[33] M. Castro and B. Liskov, “Practical Byzantine fault tolerance,” in USENIX Symposium on Operating Systems Design and Implementation (OSDI), 1999, pp. 173–186.

[34] V. Buterin and V. Griffith, “Casper the friendly finality gadget,” CoRR, vol. abs/1710.09437,2017.

[35] E. Buchman, J. Kwon, and Z. Milosevic, “The latest gossip on BFT consensus,” CoRR, vol. abs/1807.04938, 2018.

[36] L. Lamport, R. Shostak, and M. Pease, “The Byzantine generals problem,” ACM Transactions on Programming Languages and Systems (TOPLAS'82), vol. 4, no. 3, pp. 382–401, 1982.

[37] S. Micali, M. Rabin, and S. Vadhan, “Verifiable random functions,” in 40th Annual Symposium on Foundations of Computer Science (FOCS'99). IEEE, 1999, pp. 120–130.

[38] D. Boneh, B. Lynn, and H. Shacham, “Short signatures from the Weil pairing,” in Advances in Cryptology (ASIACRYPT 2001). Springer-Verlag, 2001, pp. 514–532.

[39] A. Kate and I. Goldberg, “Distributed key generation for the internet,” in IEEE International Conference on Distributed Computing Systems (ICDCS'09), 2009, pp. 119–128.

[40] “The libp2p project,” https://libp2p.io/.28

[41] “The multiaddr project,” https://multiformats.io/multiaddr/.

[42] T. Perrin, “The noise project,” https://noiseprotocol.org/noise.html, 2018.

[43] “The yamux project,” https://github.com/hashicorp/yamux/blob/master/spec.md, 2016.

[44] “The gRPC project,” https://grpc.io/.

[45] L. Gudgeon et al., “SoK: Off the chain transactions,” IACR Cryptology ePrint Archive, vol. 2019,p. 360, 2019.

[46] The Libra Association, “Becoming a Founding Member,” https://libra.org/becoming-foundingmember.

[47] I. Bentov, A. Gabizon, and A. Mizrahi, “Cryptocurrencies without proof of work,” in Financial Cryptography and Data Security – FC 2016 International Workshops, BITCOIN, VOTING, and WAHC, Christ Church, Barbados, February 26, 2016, Revised Selected Papers, 2016, pp. 142–157.

[48] JR Douceur, “The sybil attack,” in Peer-to-Peer Systems, First International Workshop, IPTPS 2002, Cambridge, MA, USA, March 7-8, 2002, Revised Papers, 2002, pp. 251–260.

[49] C. Catalini, R. Jagadeesan, and SD Kominers, “Market design for a blockchain-based financial system,” SSRN Working Paper No. 3396834, 2019.

[50] The Libra Association, “The path forward,” https://developers.libra.org/blog/2019/06/18/thepath-forward.