主页 > 苹果如何下载imtoken钱包 > 区块链节点服务器虚拟机、区块链(二)Windows Ethereum私链搭建连接多节点

区块链节点服务器虚拟机、区块链(二)Windows Ethereum私链搭建连接多节点

苹果如何下载imtoken钱包 2023-07-16 05:20:35

智能合约虚拟机赋予区块链运行去中心化应用程序(Dapps)的能力。 它让区块链进化为“操作系统”以太坊全节点搭建,孕育出繁荣的Dapp生态。 一个优秀的VM不仅是能够明确、高效、安全的完成执行合约字节码的功能,还应该具备足够的通用性,最大程度的节省开发者的成本,甚至形成一个独立的开发者生态。

从架构上看,VM为智能合约提供计算资源和运行容器,区块链共识和执行模块与VM完全解耦。 在区块链2.0项目中,我们看到大部分项目使用VM作为区块链项目的子模块,一起编译成二进制文件; Fabric更进一步,将chaincode编译成一个独立的程序,运行在一个独立的docker容器中,通过grpc与node进行交互。 这样,数据和逻辑就可以完全分离; 未来VM可能以硬件的形式安装在“矿机”中,通过PCIe等底层接口与区块链进行通信。 业界的 Nervos CKB 使用 RISC-V 实现 VM以太坊全节点搭建,为向硬件模块演进做准备。

架构设计

以太坊全节点搭建_以太坊节点一天分红多少_以太坊搭建私链

验证层

验证层会对合约字节码和传递的参数进行一些验证,包括ABI验证、环境检查和版本检查。

解释器模块是否就绪。

版本检查:检查合同版本,选择对应版本的解释器。

注入层

注入层主要是将一些必要的代码注入到合约字节码中,并构建相应的执行上下文。

燃气计量

Gas计量用于统计每次操作所需的Gas。 原理很简单:

实现 Env_api 方法 useGas。

将 wasm 字节码恢复为易于解析的格式化文本(如 JSON)。

将 useGas 注入格式化文本

将格式化文本转换回 wasm 字节码。

这里有一个值得考虑的问题:**Gas Metering是否可以放到编译时? **在编译器中做Gas计量注入的好处是只需要注入一次,节省了执行开销。 但是这样的缺点也很明显:

Gas Table 是区块链协议的一部分,但它被放置在合约编译器中。 恶意用户只需更改编译器的Gas Table即可完成作恶,作恶成本大大降低。

如果需要修改Gas Table,部署的旧合约无法更新Gas Metering,导致新旧合约Gas收费标准不一致。

以太坊节点一天分红多少_以太坊搭建私链_以太坊全节点搭建

每次执行都会进行一次Gas Metering注入,虽然牺牲了一些执行效率,但是换来Gas的灵活变化,这对于不断调整迭代的公链项目来说至关重要。 更好的解决方案是以合约的形式部署Gas Table,Gas Table的参数无需硬分叉即可更改。

环境 API 注入

env_api是区块链提供给合约层与区块链进行交互的接口。 注入原理如下:

合约字节码 (wast) 包含形式的代码段 (import "env" "getAddress" (func ...))。 意思是从env模块导入getAddress函数。

env 模块来自哪里? 虚拟机使用解释器的API构建原生模块,实现预先设计好的Env_api。 这里的Env_api需要用native language实现。

在执行代码之前使用解释器的 moduleResolver 进行注入。

以太坊基金会Go-team的Gary推荐,这里对EVMC项目进行了隆重的介绍。 它提供虚拟机和客户端之间的通用交互界面。 不同的VM只需要实现这些接口就可以为以太坊客户端提供交互功能。 这样就实现了客户端和虚拟机的分离,底层的虚拟机实现可以根据实际情况灵活切换。

上下文构建

我们还需要构建合理的合约执行上下文,提供合约使用所需的内部模块和数据,包括:

执行层

执行层是虚拟机的核心模块,负责执行合约字节码并返回结果。 它必须具有以下属性:

确定性:即相同的输入参数和上下文,无论在什么设备上运行,什么时候运行,运行多少次,都必须得到相同的结果。

高效执行:虚拟机的执行时间不大于共识算法给定的事务执行的最大时间。

关闭和回滚:必须有相应的关闭机制。 当执行失败时,需要回滚本次执行涉及的所有状态变化。

沙盒环境:保证合约之间、合约与宿主系统之间的资源隔离。 能够防范恶意和故障合约的不良影响。

申请

执行合约字节码实际上调用了合约代码中的apply函数。 合约上下文,包括用户指定的合约方法名和对应的入参,在实际apply实现中通过Env_api获取,最终调用对应的合约方法。 有关栗子的详细信息,请参阅本系列的第二部分。

记忆

合约除了导出apply函数外,还需要导出内存对象。 内存对象在合约编译时由wasm编译器自动注入,通常会分配一页内存(64KB)(memory $0 1)。 解释器会初始化一个线性字节数组作为内存,供 wasm 使用。 wasm与区块链数据的交互依赖于内存共享的形式,通过字节数组传递。 (这也是为什么在Env_api的设计中,很多值都是作为offset和length的组合来传递的)

以太坊全节点搭建_以太坊节点一天分红多少_以太坊搭建私链

Wasm的内存数组是按照|的顺序划分的静态内存 | 动态记忆|。 静态内存在编译时存储字符串或数组,动态内存用于运行时数据存储,可以动态扩展。 为了防止动态内存无限扩展,需要合理的计费机制和内存分配上限。

AssemblyScript 在静态内存之前提供了额外的预留空间,称为预留内存。 这允许我们在运行时将一些可变长度的数据(如字符串、数组等)以 Global 的形式导入到 wasm 中。 这样wasm就可以不用调用Env_api直接使用context变量,比如sender,receiver,合约地址,当前调用的合约方法名等。

状态存储

VM最本质的需求是状态存储的需求,状态存储是共识的、不可逆的,从而实现数据在去中心化应用中的可信存储。

以太坊 1.0 中的状态爆炸问题已经给我们敲响了警钟——每次读写只收费,存储不收费,这是不合理的。 如果占用存储不收费,用户可以无限制占用区块链稀缺的存储资源; 并且由于没有良好的数据清洗机制,区块链的状态会不断增长,也就是所谓的“爆炸”。

为状态存储付费是一种自然的解决方案。 如何设计合理的状态存储支付方案,有两个底层逻辑需要考虑:

EOS 使用 [RAM] 来解决状态费用的问题。 开发者需要使用代币从系统合约中购买RAM,存储状态数据需要相应数量的RAM资源。 当数据被删除时,RAM 资源会相应释放,并可以卖回给系统取回代币。 但是,开发者需要承担 RAM 和代币价值波动的风险。 内存如何定价? EOS 创新性地引入了 Bancor 算法来模拟 RAM 的市场定价。 Bancor算法有两个特点:

也正是因为以上两个特点,在EOS主网上线之初,囤积了大量RAM资源,RAM价格瞬间被拉高,随后一周快速下跌,造成了“割开发者韭菜”的局面。

Vitalik 在 2018 年提出使用【state rent】来解决 state explosion 问题。 状态租与当前云计算服务的商业模式非常相似。 用户不仅为占用空间的大小付费,还购买占用的时间。 对于国租方案的具体设计,我们还需要考虑以下问题:

用户体验:状态租用时间即将到期,如何提醒用户续订? 时间到后是否立即清除状态数据? 不同级别的数据是否有不同的处理方式? (云服务商会提供到期后的赎回期,防止关键数据被误删)

谁支付:哪些数据需要支付租金? 除了必须支付租金的合约状态数据外,账户本身的元数据(余额、随机数等)是否也必须支付租金? 如有必要,超时后清零,势必会损害用户的资金安全(与区块链保护数字资产的理念相悖),同时nonce为0后,可能遭受来自重放攻击。 如果不需要,仍然没有办法抑制由于创建新帐户而导致的状态爆炸问题。

定价:链上存储资源的稀缺性与区块链生态价值和当前市场需求密切相关。 如何建立合理的定价模型是一个非常重要的问题。

以太坊研究的一位大师细化了state rent scheme,引入了租约到期发现和确认的激励机制,允许状态数据删除后申请恢复。

Nervos CKB 结合了状态交易和状态租金的优势,使用原生代币来代表对全局状态的占有权,并且汇率恒定,即 1 CKB 代表 1 Bytes 的存储空间。 同时,巧妙地利用【二次发行】机制,为代币持有者(存储空间占有者)设置【通货膨胀税】作为支付给矿工的国家租金。 通货膨胀收租的方式,既保留了RAM方案中买断存储空间的使用方式,又解决了前面提到的用户体验问题,将定价转移到通货膨胀部分对应的法币价值上,这完全是通过二级市场价值发现来进行的。 但这使得状态空间的上限严格等于当前的代币流通量,可能会在前期限制生态的发展。

合同安全

我们在第一篇文章中提到,合约安全分为编译时安全和执行时安全。 本文主要讲解执行过程中安全的设计思路。

执行时安全也变成了运行时安全,VM主要从以下两个方面来保证:

数据安全

加密数字资产真正实现了人类梦寐以求的“神圣不可侵犯的私有财产”,象征着真正的自由。 为了捍卫这份“自由”,数据安全是重中之重。

以太坊节点一天分红多少_以太坊全节点搭建_以太坊搭建私链

VM需要为以下两个方面提供安全保障:

用户数据的安全是指使用密码算法来判断是否有修改状态数据的权限。

合约状态数据隔离,即任何合约都不能直接修改其他合约的状态数据,即使用户有权限。

第一个维度很容易理解。 合约会提供基于用户地址和交易签名的身份权限审核功能(甚至可以提供基于多个密钥对的权限管理)来判断本次合约调用是否具有修改相应数据的权限。 . 这也是“私有财产神圣不可侵犯”的根源。

第二个维度需要特别说明。 这里不能直接修改其他合约的状态数据,也就是说不能在合约A的方法中直接修改合约B的数据,为什么? 因为这会导致无法追溯的状态变化,带来不确定性。 我们知道,在区块链环境中,状态的改变只能由交易触发,而交易本身就是状态改变的日志。 如果允许在合约A中直接修改合约B的状态数据,则此次修改不会产生相关日志,使得状态修改无法追溯,这与区块链“可追溯”的特性相悖。

以太坊中没有为跨合约调用保留日志。 作者认为这是因为以太坊合约无法升级。 一旦部署,地址和代码将无法更改。 因此,可以结合事务和特定的代码片段来跟踪状态变化记录。 但是以太坊没有提供相关的索引,这使得状态修改记录几乎无法追踪,所以我认为这是一个重大的设计缺陷。 在 EOS 中,我们看到跨合约调用产生了一个新的 action,这个 action 被添加到原来的 action list 中,状态修改日志保存在链上。

是否可以通过静态代码分析来确定跨合约的交易对手地址和相关合约方法,从而追溯状态变化的细节? 当然是可行的,但是如果有多层调用(合约A -> 合约B -> ... -> 合约Z),这个方案显然是非常昂贵的。 虽然以太坊提供了tracer,可以跟踪交易执行过程中跨合约调用的对象,但是如果我想找出所有导致合约X状态变化的历史操作,上述方案就必须遍历并模拟所有历史交易。 显然是不可取的。

我们认为,跨合约交易的正确做法是以内联交易的形式调用合约B的方法,间接修改合约B的数据。 即生成一个新的交易来触发目标合约的状态改变。 该交易也应作为原始交易生成的日志包含在块中。 这样可以为状态的变化保留操作记录,也符合“可追溯”的特点。

资源安全

智能合约通常运行在虚拟机提供的沙盒环境中,我们需要适度控制它们可以使用的资源。 这些资源包括三类:CPU、内存和硬盘。 下面我们以QA的形式对涉及的问题进行解答——

CPU资源

Q1:合约最多可以运行多少个进程和线程?

一; 一个或多个。

Q2:是否允许在合约中开启新线程?

不允许。 合约不应有操作系统级调用,但虚拟机层应确定性地分配 CPU 资源(线程数)。

Q3:多线程下如何保证线程安全?

多线程下,不应该使用锁来保证线程安全,因为锁不能保证执行顺序,带来不确定性。 正确的做法是在执行前通过静态分析、注解等方式对合约调用进行分类。 互斥资源的调用顺序遵循交易发送的顺序; 非互斥资源的合约调用可以并行执行。

Q4:如何控制执行时间?

使用Gas机制控制合约执行时间(在本系列第一篇文章中提到),避免CPU时间过长。

以太坊节点一天分红多少_以太坊全节点搭建_以太坊搭建私链

Q5:如何捕捉错误并进行处理?

合约执行错误不应导致虚拟机进程终止,虚拟机应提供错误捕获和处理机制。 传统上,合约执行过程中的错误以错误的形式抛出,虚拟机层捕获并处理故障,包括终止交易执行、状态回滚、资源回收等。

内存资源

Q1:一个合约最多占用多少内存?

节点可以分配给虚拟机多少内存由矿工决定。 这本质上是一个经济学问题:扩大内存分配无疑会增加成本,这部分提升的执行效率又能给矿工带来多少收益。 如果可用内存太少,部分交易将无法执行,可能导致分叉; 如果可用内存过多,会造成资源浪费,降低矿工收益。

Q2:内存可以动态扩展吗?

可以,但是要收费。 为了防止无限扩展内存,虚拟机也应该对合约的内存使用量设置一个上限。

Q3:如何避免内存泄漏?

不应该让合约开发者来控制内存回收,虚拟机应该实现GC机制。

Q4:如何避免内存溢出?

Wasm虚拟机中的内存其实是一个字节数组,有边界控制,可以有效防止内存溢出。

磁盘资源

Q1:单个合约最多可以存储多少数据?

这也是一个经济问题,应该设置合理的硬盘使用计费。

Q2:我可以修改其他合约的持久化数据吗?

不能直接修改,因为这会影响【数据安全】章节提到的确定性。 虚拟机为合约创建的上下文环境包含相互隔离的数据空间。 可以通过创建一个新的上下文环境来进行数据修改,这样的操作被认为是一个新的合约调用(保留日志)。

Q3:如何防止未知数据丢失(如磁盘损坏)?

当数据丢失时,节点在执行合约时会得到不同的状态结果,导致区块被认定为非法,区块链无法延展。 这里就需要区块链系统有状态一致性检测机制。 硬盘故障解决后,同步主链区块,重放交易恢复。

系统合约

以太坊全节点搭建_以太坊节点一天分红多少_以太坊搭建私链

系统合约是指区块链系统启动时预部署、可升级、可治理的合约,提供权限控制、资源租赁、代币质押等基础服务。 系统合约通常具有以下三个特征:

系统合约可以采用普通合约的方式实现,部署在系统预先确定的合约地址。

未来优化方向

智能合约的并行执行

合约并行执行是提高智能合约执行效率的主要思路。 这里的并行执行不是指单个合约方法内部的并行,而是合约之间的并行。 要实现合约并行执行,我们需要考虑两个重要问题:

如何检测本次合约执行访问的资源对象? 比如读写状态数据,读取账户余额等互斥操作。

如何合理调度合约执行? 即哪些合约可以并行执行,哪些必须序列化?

一个很容易想到的思路是:通过静态代码分析,检测出合约方法可能访问的资源,将访问相同资源的合约调用归为同一组。 每个组的执行可以并行化,组内的执行可以串行化(按照交易发送顺序)。

然而,实际设计中需要考虑的因素要复杂得多:

甲骨文

预言机是智能合约获取链外数据的桥梁。 这些数据通常由第三方可信数据源提供,比如天气数据、事件数据、数字货币价格等,在传统的互联网应用中,我们可以简单地通过HTTP API获取这些数据。 但它在智能合约中不起作用,因为 HTTP 调用通常是异步的,时间不可预测且不确定。 因此,需要专门的基础设施来为智能合约提供这些链下数据。

预言机的设计原则主要考虑三点:

获取链下数据,保证数据的真实性和可用性。

通过智能合约调用以确定和同步的方式获得。

预言机网络本身的安全性和可用性。

隐私保护

密码学的研究推动了隐私领域的创新。 隐私研究主要涉及零知识、多方计算、全同态加密等领域。

多方计算 (MPC) 允许一组人根据他们的输入执行联合计算,而不需要每个人都透露他们输入的值。 例如,如果 Alice 和 Bob 想知道谁拥有更多的比特币,这可以在不要求他们披露他们拥有多少比特币的情况下完成。 不幸的是,目前多方计算的局限性是在实践中使用效率极低。

全同态加密(Fully homomorphic encryption)允许人们在加密数据上进行计算。 几十年来,这一直是密码学中未解决的问题,直到 2009 年,斯坦福大学博士生 Craig Gentry 使用“理想格”构建了第一个完全同态加密方案。 如果鲍勃想对爱丽丝的数据执行任意计算,例如训练机器学习模型,而不要求爱丽丝透露明文数据,理想格加密就会派上用场。 全同态加密和多方计算一样,基本上还停留在理论阶段,在实践中效率太低。