Solidity高级理论(二):Gas

solidity高级理论(二):Gas

关键字:Gas、结构体、节省小技巧

Gas是什么

在Solidity中,用户想要执行DApp都需要支付一定量的Gas,Gas可以用以太币购买,所以,用户每次使用DApp都会发费以太币。

一个 DApp 收取多少 gas 取决于功能逻辑的复杂程度。每个操作背后,都在计算完成这个操作所需要的计算资源,(比如,存储数据就比做个加法运算贵得多), 一次操作所需要花费的 gas 等于这个操作背后的所有运算花销的总和。

由于运行你的程序需要花费用户的真金白银,在以太坊中代码的编程语言,比其他任何编程语言都更强调优化。同样的功能,使用笨拙的代码开发的程序,比起经过精巧优化的代码来,运行花费更高,这显然会给成千上万的用户带来大量不必要的开销。

gas是计算费用的方式。不过,这些费用仍然是以ether计算,这与gas不同。gas成本是工作量,如劳动时数,而gas价格就像您为完成工作付出的小时工资。 两者的组合决定了您的总交易费用。如果您的gas价格太低,没有人会处理您的交易。如果您的gas价格不错,但交易的gas成本超过预算,交易失败,但仍然被打包进区块,劳动者工作了,您不会获得退款。这样确保没有任何东西永远运行,而且人们会对他们运行的代码注意一点。 它使矿工和用户都能安全避免错误的代码!

节省Gas的小技巧

其实很多人觉得,使用uint变种会节省gas,如uin8,其实并不是,即使使用uint8,solidity还是会为它保留256位的存储空间。

例如,使用uint8而不是使用uint256,消耗的gas是一样的。

结构封装(Struct packing)

有一种办法可以节省gas,那就是把uint绑定到struct里面。

如果一个struct中有多个uint,则尽可能使用较小的uint,solidity会将这些uint打包在一起,从而占用较小的存储空间。例如:

    struct da{
        uint a;
        uint b;
        uint c;
    }
    strcut xiao{
        uint32 a;
        uint32 b;
        uint c;
    }
    da normal = da(10, 20, 30);
    xiao mini = xiao(10, 20, 30);
    // 因为使用了结构打包,‘xiao’比‘da’占用的空间更少

这样就符合大家的逻辑了,使用uint32比uint256节省了很多的gas。

所以,当 uint 定义在一个 struct 中的时候,尽量使用最小的整数子类型以节约空间。 并且把同样类型的变量放一起(即在 struct 中将把变量按照类型依次放置),这样 Solidity 可以将存储空间最小化。例如,有两个 struct:

uint c; uint32 a; uint32 b; 和 uint32 a; uint c; uint32 b;

前者比后者需要的gas更少,因为前者把uint32放一起了。

原文地址:https://www.cnblogs.com/tokenpai/p/9175965.html

时间: 2024-08-04 01:38:31

Solidity高级理论(二):Gas的相关文章

Stm32高级定时器(二)

Stm32高级定时器(二) 1 主从模式:主?从? 谈论主从,可知至少有两个以上的触发或者驱动信号,stm32内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控制信号(TRGO). 从模式:复位模式, 在发生一个触发输入事件时,计数器和它的预分频器能够重新被初始化:同时,如果IMx_CR1寄存器的URS 位为低,还产生一个更新事件UEV :然后所有的预装载寄存器(TIMx_ARR ,TIMx_CCRx)都被更新了. 从模式:门控模式, 计数器的使能依赖于选

MySQL数据库 高级查询(二)

高级查询(二)  EXISTS 子查询 语法: SELECT ..... FROM  表名 WHERE EXISTS (子查询); EXISTS 关键字后面的参数是一个任意的子查询,如果该子查询有返回值,则EXISTS 子查询的结果为true,此时再执行外层查询语句.如果没有返回行,则EXISTS 子查询 的结果为false,此时外层语句不再执行查询.  NOT EXISTS 子查询 EXISTS 子查询和NOT EXISTS 子查询的结果只取决于是否有返回记录,不取决于这些记录的内容,所以EX

MySQL数据库高级(二)——自定义函数

MySQL数据库高级(二)--自定义函数 一.自定义函数简介 自定义函数 (user-defined function UDF)是一种对MySQL扩展的途径,其用法和内置函数相同.自定义函数的两个必要条件:A.参数B.返回值(必须有).函数可以返回任意类型的值. 二.自定义函数的使用 1.自定义函数语法 CREATE?FUNCTION?function_name(parameter_nametype,[parameter_name type,...]) RETURNS?{STRING|INTEG

lua 高级篇(二)

第七章  迭代器与泛型for       迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素,在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素.    一.迭代器与闭包    一个简单的例子: 我们为一个list写一个简单的迭代器,与ipairs()不同的是我们实现的这个迭代器返回元素的值而不是索引下标: function list_iter(t) local i = 0 local n = table.getn(t) return function () i

Spring_总结_04_高级配置(二)之条件注解@Conditional

一.前言 本文承接上一节:Spring_总结_04_高级配置(一)之Profile 在上一节,我们了解到 Profile 为不同环境下使用不同的配置提供了支持,那么Profile到底是如何实现的呢?其实Profile正是通过条件注解来实现的. 条件注解的应用场景举例: (1)希望一个或多个 bean 只有在应用的类路径下包含特定的库时才创建 (2)希望某个bean只有当另外某个特定bean也声明了之后才创建 (3)希望只有某个特定的环境变量设置之后,才会创建某个bean 上述场景能让我们联想到s

MySql学习(六) —— 数据库优化理论(二) —— 查询优化技术

逻辑查询优化包括的技术 1)子查询优化  2)视图重写  3)等价谓词重写  4)条件简化  5)外连接消除  6)嵌套连接消除  7)连接消除  8)语义优化 9)非SPJ优化 一.子查询优化 1. 什么是子查询:当一个查询是另一个查询的子部分时,称之为子查询. 2. 查询的子部分,包含的情况: a) 目标列位置:子查询如果位于目标列,则只能是标量子查询,否则数据库可能返回类似“错误:子查询只能返回一个字段 ( [Err] 1242 - Subquery returns more than 1

HAProxy 高级应用(二)

HAProxy 高级应用 ================================================================================ 概述:   本章将继续介绍haproxy的一些其他应用,具体内容如下: use_backend <backend> 后端主机调用: haproxy中tcp模式的应用: haproxy中listen的应用 =====================================================

iOS开发——高级篇——二维码的生产和读取

一.二维码的生成 从iOS7开始集成了二维码的生成和读取功能此前被广泛使用的zbarsdk目前不支持64位处理器 生成二维码的步骤:导入CoreImage框架通过滤镜CIFilter生成二维码 二维码的内容(传统的条形码只能放数字):纯文本名片URL // 1. 实例化二维码滤镜 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; // 2. 恢复滤镜的默认属性 [filter setDefaults];

JDBC高级特性(二)分布式事和JTA基本原理

在进入主题之前我们首先来了解一下JNDI和连接池~ 一.JNDI 1)是一组在Java应用中访问命名和目录服务的API(Java命名与目录接口) 命名服务将名称和对象联系起来,使得我们可以通过名称访问对象. 目录服务是命名服务的扩展,两者之间的关键差别是目录服务中对象可以有属性(例如:用户有email地址),而命名服务中对象没有属性. 2)JNDI API提供了一种统一的方式,可以在本地或网络上查找和访问服务 各种服务在命名服务器上注册一个名称,需要使用服务的应用程序通过JNDI找到对应服务就可