首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >关于 Libra 币交易, 你需要了解的一切...

关于 Libra 币交易, 你需要了解的一切...

作者头像
区块链大本营
发布于 2019-07-11 07:31:28
发布于 2019-07-11 07:31:28
97700
举报
文章被收录于专栏:区块链大本营区块链大本营
运行总次数:0

作者 | Second State

责编 | 乔治

出品 | 区块链大本营(blockchain_camp)

在上一篇文章中,我们初步探索了 Libra & Move 语言 。在这篇文章中,我们将探讨使用者如何跟 Libra 进行互动。

本文以向 Libra 水龙头(Faucet)索取 Libra 币为例子,解释 Libra Client 与 Validator 的内部是如何处理与执行交易的。

与 Libra 互动

Libra 技术白皮书用下面这张图来解释 Libra Client 与 Validator 之间的关系:

Libra 将参与区块链的人分成两类:Client(普通的使用者) 与 Validator(LibraBFT 共识节点)。

普通的使用者通过 Client 向 Validator 提交交易与 query。而 Validators 的任务就是处理好共识与执行 Client 发出的请求。

使用者向 Faucet 索取 LibraCoin

1、启动 Libra CLI (Libra command line interface)以后,等待 Libra CLI 连上 测试网(testnet) ,并提示使用者可以进行输入 libra%

2、使用者输入account mint <Address> <Number of Coins> 后, Libra CLI 首先会将 <Address>, <Number of Coins> 打包成交易中的参数数据(parameter data),并从language/stdlib/transaction_scripts 下载入 mint 程式的 Move IR 档案,作为交易中的交易脚本。(关于交易格式请参考文末的参考资料)。

3、打包好一笔交易以后,Libra CLI 便会将这笔交易提交给 Validator。

4、Validator 收到这笔交易时,并不会立刻执行它,而是先将其放入 mempool 里面,并与其他的 Validator 分享。

5、当 Validator 要执行这笔交易时,每位 Validator 将轮流成为领导者(Leader),领导者 会从 mempool 里面挑选等待执行的交易做成一个 拟议区块(proposed block),并广播给其他的 validators,等待投票。在至少 2f+1 个 validator 投票同意拟议区块,领导者将会制作法定人数证书( quorum certificate )并广播给全部的 validators。

6、经过这个过程,在这个拟议区块中的交易就会被执行,并且提交到版本数据库(versioned database)。

Validator 是如何执行交易的?

Libra 专门为 Move 语言设计了 Move 虚拟机。当 Validator 要执行交易时,需要通过 Move 虚拟机来执行。

1. 检查签名: 检查交易签名是否跟交易数据以及发送者的公钥吻合。此阶段是直接比对交易的资料,尚未跟版本数据库与 Move 虚拟机互动。

2. 运行预处理程序(Prologue):

依序会进行以下三个检查:a)检查交易中的交易发起者公钥是否与版本数据库中交易发起者账户中留存的验证密钥一致。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HASH(Sender Public Key) == SenderAddr.LibraAccount.T.AuthenticationKe

b)检查交易发起者是否有足够的 Libra coin 来支付 gas 费

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Transaction.gasPrice * Transaction.maxGasAmount <= SenderAddr.LibraAccount.T.balance

c)检查交易的序列号是否跟当前版本数据库中交易发起者账户的序列号一致。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Transaction.SequenceNumber == SenderAddr.LibraAccount.T.SequenceNumber

这三个检查都是通过执行 built-in Module 0x0.LibraAccount 的procedure - prologue()

因为此阶段为必要的检查,虽然通过 Move 虚拟机执行了0x0.LibraAccount.prologue() 但并不会向交易发起者收取执行的 gas 费。

3. 验证交易脚本(Transaction Script)和模块(Module)

安全性是 Move 非常重要的设计原则,因此在 Move 提供了字节码验证器来检查即将执行的交易脚本或者部署的模块,以确保 type, reference, resource 的安全。

4. 发布模块:若交易中有需要部署的模块,则在此阶段将模块部署到该地址中。(请参考文末参考资料中的 Libra 存储布局)

5. 运行交易脚本:Move 虚拟机将交易中的参数绑定进交易脚本中的参数(arguments)后,便会开始执行。

若执行成功,将会产生事件(events)并将此次执行结果写回全球状态(global state)中。若执行失败(包含 out of gas、执行错误等),则会还原本次执行对全球状态的修改。

6. 运行收尾程序(Epilogue):不论执行成功或失败,都会触发此阶段。

通过呼叫 built-in Module 0x0.LibraAccount 的procedures - Epilogue() 来进行收取gas 费和调整序列号的操作:

收取 gas 费

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SenderAddr.LibraAccount.T.Balance -= Transaction.gasPrice * Transaction.gasUse

调整序列号

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SenderAddr.LibraAccount.T.SequenceNumber += 1

此阶段跟预处理程序阶段相同,虽然会通过 Move 虚拟机执行LibraAccount.Epilogue(),但不会向交易发起者收取运行收尾程序的 gas 费。

Libra CLI 如何处理

account mint <address> <number of coin>

当我们启动 Libra CLI 时,会经过下面的流程来初始化 client ,让使用者得以输入指令与 Libra 测试网互动。

在使用者看到libra% 的输入提示前, Libra CLI 会从配置文件中将 genesis, faucet account, local account 等信息载入,并进行 ClientProxy 的初始化,来连接上测试网。在后续的操作中,使用者的指令将全部通过 ClientProxy 来包装,将使用者的指令与对应的交易合成,并发送给 Libra 的 Validator。

LibraCommand

当使用者希望为自己的第一个账户索取 100 个 Libra coin 时,输入account mint 0 100,此时 Libra CLI 会解析整个输入字串并调用对应的 LibraCommand 来执行。

指令中的account 代表着 Command 要调用CommandAccount::execute()来执行mint 0 100。此时 CommandAccount又看见指令中的mint ,

因此会再解析一次,以0 100`0 100` 去调用subcommand - CommandAccountMint::execute() 来执行 。

ClientProxy

但AccountCommandMint::execute()并不是直接发送交易给 Libra validators,而是通过 Libra CLI 最重要的核心 ClientProxy 代为操作,下面是具体的流程。

AccountCommandMint::execute()会将 0(第一个账号), 100(libra coin 的数量) 发送给ClientProxy::mint_coins()来执行。

在执行时, ClientProxy 会先确认在本机上的帐号是否存在水龙头(faucet)账号。

a) 若本机不存在水龙头账号,ClientProxy 则会调用mint_coins_with_faucet_service(),将mint 0 100 打包成一个链接 (https://<faucet server>?amount=100&account=0),来对远程水龙头服务器发送mint 的请求。

b) 当本机存在水龙头账号时,ClientProxy 则会采用完全不同的路径来执行 mint 请求,

改为调用:

ClientProxy::mint_coins_with_local_faucet_account(),

此时会真的建构一个 Libra 交易:

通过vm_genesis::encode_mint_program()方法,取得放置在

“language/stdlib/transaction_scripts” 下 mint.mvir。

mint.mvir 是 Libra 团队用 Move 语言预先写好的交易脚本。

接着调用 ClientProxy::create_submit_transaction_req() ,

将交易脚本 (mint.mvir), sender address, gas price, max gas amount 等信息打包到 Libra 交易。

c) 使用GRPCClient::submit_transaction()将这个交易发送给 Validator。

注:如果使用者在调用account mint 0 100 时,要求等交易完成后才返回,这时ClientProxy 会调用wait_for_transaction()卡住输入区并显示`waiting…` 直到交易完成后才会再次提示使用者可以进行下一步的操作。

附:参考资料

1、交易格式

Libra 详细定义了一笔交易应该有以下栏位:

Sender Address:交易发起者地址,将用来查询在 Ledger 中此地址的 LibraAccount 的资讯。

Sender Public Key:交易发起者公钥,将用来验证此交易是否由发送者所签署;以及检查此公钥是否与此地址中 LibraAccount 留存的验证密钥相符。

Program Move:模块(Move Module) 或者交易脚本(Transaction Script)。

Gas Price:此交易的单位 Gas 的价格。

Max Gas Amount:此交易的 Gas 上限。

Sequence Number:序列号,需要与当前地址中的SLibraAccount.T.SequenceNumber 相符,是用来检查是否发生重播攻击(replay attack )等攻击的验证栏位。

2、Libra 存储布局

每个地址分别存在模块部分(Module Section)与资源部分(resource section)。

模块部分代表了每个地址可以拥有多种 Libra 模块,唯一的限制是在该地址中只能存在一个同名的 Module。

以下图为例,0x0 已经存在了 Account 模块,当使用者将发布在模块的交易发布到另一个Account 模块到 0x0 时,执行交易会中止并报错。

在 Libra 中,不同地址拥有完全独立的 namespace ,因此在不同的地址部署同一个模块会产生不同的模块名字。比如上图中虽然0x0 跟0x4 都有同名的Account 模块,但实际上在使用时,我们可以看到0x4 里面存在着0x0.Account.T {...} 与0x4.Account.T {... } ,他们分别表示完全不同的资源空间。

关于作者:

Second State 主要提供针对企业的区块链智能合约解决方案,已获得一线VC投资,目前处于未公开阶段。Second State 正在为业内领先的开源项目做贡献,即将发布第一批产品。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 区块链大本营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入探索Java类加载与字节码技术:从字节码指令集到Lambda表达式实现
在Java虚拟机(JVM)的执行过程中,类加载机制扮演着至关重要的角色。这一机制不仅决定了Java程序如何被加载到内存中,还影响着程序的运行效率和安全性。理解类加载机制是深入掌握JVM工作原理的基础,也是后续探讨字节码技术的前提。
用户6320865
2025/08/27
1950
深入探索Java类加载与字节码技术:从字节码指令集到Lambda表达式实现
深入探索Java类加载与字节码技术:双亲委派破坏、SPI机制与OSGi类加载隔离
在Java虚拟机(JVM)的体系结构中,类加载机制是实现动态性和安全性的核心基础设施。当我们在代码中写下new MyClass()时,背后隐藏着一套精密的类加载流程——从字节码文件的定位、验证到内存中的最终成型,整个过程构成了Java"一次编写,到处运行"能力的基石。
用户6320865
2025/08/27
2300
深入探索Java类加载与字节码技术:双亲委派破坏、SPI机制与OSGi类加载隔离
JVM-类加载子系统
​ Java虚拟机将描述类的数据从class字节码文件加载到内存,并且对数据进行校验,转化,解析,初始化的工作,最终形成在内存中可以直接使用的数据类型。这个过程叫做虚拟机的类加载机制。
程序员阿杜
2021/08/03
4930
JVM-类加载子系统
JVM深入原理(六)(一):JVM类加载器
摘星.
2025/05/20
1040
JVM深入原理(六)(一):JVM类加载器
JVM精通面试系列 | 掘金技术征文
JRE 仅包含运行 Java 程序的必需组件,包括 Java 虚拟机以及 Java 核心类库等。我们 Java 程序员经常接触到的 JDK(Java 开发工具包)同样包含了 JRE,并且还附带了一系列开 发、诊断工具。
蒋老湿
2020/03/27
9060
JVM精通面试系列 | 掘金技术征文
JVM-10.类加载
准备是为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中分配。
悠扬前奏
2019/05/28
4450
JVM实战 - 类加载的过程
任何程序都需要加载到内存才能与CPU进行交流 同理, 字节码.class文件同样需要加载到内存中,才可以实例化类 ClassLoader的使命就是提前加载.class 类文件到内存中 在加载类时,使用的是Parents Delegation Model(溯源委派加载模型)
JavaEdge
2019/02/15
1.3K0
JVM实战 - 类加载的过程
彻底搞懂JVM类加载器:基本概念
在Java面试中,在考察完项目经验、基础技术后,我会根据候选人的特点进行知识深度的考察,如果候选人简历上有写JVM(Java虚拟机)相关的东西,那么我常常会问一些JVM的问题。JVM的类加载机制是一个很经典的知识点,围绕这个知识点可以有下面这些难度不同的问题。
阿杜
2019/10/08
7080
彻底搞懂JVM类加载器:基本概念
jvm入门
java字节码:java语言编译成的字节码,.class文件,jvm与java语言无必然联系,只与特定的二进制文件-class文件格式关联。class文件包含了jvm指令集(或称字节码)和符号表,其他辅助信息
用户10832809
2025/02/23
2040
阿里架构师带你深入浅出jvm
本文跟大家聊聊JVM的内部结构,从组件中的多线程处理,JVM系统线程,局部变量数组等方面进行解析 JVM JVM = 类加载器(classloader) + 执行引擎(execution engine
用户1263954
2018/06/22
7740
【JVM】关于JVM,你需要掌握这些!!
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
冰河
2020/10/29
4510
【JVM】关于JVM,你需要掌握这些!!
JVM体系结构详解
虚拟机是物理机的软件实现。Java是用WORA(编写一次运行到任何地方)的概念开发的,它在VM上运行。编译器将Java文件编译成Java .class文件,然后将.class文件输入JVM, JVM加载并执行类文件。下面是JVM的架构图。
挨踢小子部落阁
2019/09/25
6480
JVM体系结构详解
JVM 架构解读
每个Java开发人员都知道字节码由JRE(Java运行时环境)执行。但许多人不知道JRE是Java Virtual Machine(JVM)的实现,它分析字节码,解释代码并执行它。作为开发人员,我们应该知道JVM的架构是非常重要的,因为它使我们能够更有效地编写代码。在本文中,我们将更深入地了解Java中的JVM架构和JVM的不同组件。
哲洛不闹
2018/09/18
7050
JVM 架构解读
Java虚拟机JVM介绍
Java虚拟机(JVM)是一个抽象的计算机,它为Java字节码提供了一个运行环境。以下是与JVM相关的一些主要概念:
运维开发王义杰
2023/08/16
2280
Java虚拟机JVM介绍
JVM简介—3.JVM的执行子系统
字节码是各种不同平台虚拟机与所有平台都能统一使用的程序存储格式,所以字节码(ByteCode)是构成平台无关性的基石,是语言无关性的基础。
东阳马生架构
2025/03/11
1970
java-jvm
JVM中类的装载是由ClassLoader和它的子类来实现的,Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。 Java中的所有类,都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中。在写程序的时候,我们几乎不需要关心类的加载,因为这些都是隐式装载的,除非我们有特殊的用法,像是反射,就需要显式的加载所需要的类。 类装载方式,有两种 (1)隐式装载,程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中,利用反射即隐式加载可绕过一些权限检查机制。 (2)显式装载,通过class.forname()等方法,显式加载需要的类 ,隐式加载与显式加载的区别:两者本质是一样的。 java中类加载是动态的,并不会一次性把所有的类全部加载后再运行,而是保证程序运行的基础类(像是基类)完全加载到jvm中,至于其他类,则在需要的时候才加载。这当然就是为了节省内存开销。
知识浅谈
2021/10/25
5090
java-jvm
深入理解JVM,虚拟机类加载机制
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括以下7个阶段:
李红
2019/09/17
5140
深入理解JVM,虚拟机类加载机制
独特视角解读JVM内存模型
每一个类被加载的时候,java 虚拟机都监视这个类,看它到底是被启动类加载器加载还是用户定义的类加载器加载。当被装载的类引用了另外一个类的时候,虚拟机就会使用装载第一个类的类装载器装载被引用的类。
大忽悠爱学习
2023/03/23
5240
独特视角解读JVM内存模型
JVM体系结构认知
虚拟机 何为虚拟机呢?虚拟机是模拟执行某种指令集体系结构(ISA)的软件,是对操作系统和硬件的一种抽象。其软件模型如下图所示: 计算机系统的这种抽象类似于面向对象编程(OOP)中的针对接口编程泛型(
xiangzhihong
2018/01/26
9170
JVM | 基于openJDK源码深度拆解Java虚拟机
在上一篇文章中,我通过探讨类的生命周期,为你详细解析了类在加载进JVM时的全过程。当然,这仅仅只是JVM虚拟机的冰山一角,像执行引擎的动态编译、垃圾回收系统的内存管理、本地方法接口的与本地库的交互,以及本地方法库的结构和功能等诸多核心内容还未涉及。
kfaino
2023/10/08
1.8K2
JVM | 基于openJDK源码深度拆解Java虚拟机
相关推荐
深入探索Java类加载与字节码技术:从字节码指令集到Lambda表达式实现
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档