Web3开发学习笔记5----关于GAS和 Solidity语法【5/7】

356 阅读7分钟

“携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情”

本来呢,既然合约部署好了。是不是可以直接撸前端脚本来调用合约了。但我一想,中间跳过的步骤太多。所以一些基础概念还是要补上。 (已经熟悉的效小伙伴可以跳过)

一、了解下GAS

一、什么是Gas

Gas是用于测量在以太坊区块链 上执行特定操作所需的计算工作量的单位。

为什么会存在这种情况?

在运行智能合约时有几个主要限制:

  1. 每个部署的交易、智能合约或智能合约的执行,都必须在以太坊区块链上的每个完整节点上运行,以保证有效性。虽然这非常低效的,但确实是目前最好最公平的机制。(尽管新的区块链正在简化这一点,说白了,新的公链尽量设计的又快又便宜)!
  2. 因为智能合约是图灵完备的,它们有可能永远执行,锁定区块链上的每个节点。

知识点:什么是图灵完备性?

实际上,只要有足够的时间和资源,图灵完备的编程语言就能够解决或表示任何计算问题,无论多么复杂。

这有几个含义:

  1. 理论上,任何图灵完备语言都可以用来表示另一种图灵完备语言的逻辑,尽管实现的时间可能长得不合理。

  2. 图灵完备的程序最终可能会永远循环和执行。

    没有通用的方法可以证明这样的程序不会永远运行(也称为“停机问题”)。

例如,普通计算器不是图灵完备的,因为它只允许几种类型的计算。

但是,计算机或科学计算器是图灵完备的,因为可以在其上执行任何类型的程序。

由于智能合约程序可以永远运行(所以区块链不需要像AWS,Aliyun 这样需要庞大的运维团队),当然这种机制,也肯定要设一些成本,防止那些无休止的机器人,或者各种开发者频繁操作。  所以gas 已成为以太坊中管理区块链程序计算执行的最实用方式(没有之一)!

因此,在区块链上进行的每次计算或交易都会产生一些费用。这些费用就可以防止合约被无休止的执行,同时这样的费用,确保矿工的工作得到公平奖励。 区块链就是这样的机制来优先考虑哪些交易进入区块链。  就是说,如果两个人要抢占同一个目的一样的合约方法去执行,那么在在同一个block里,  gas高的将被优先确认执行。

二、如何计算GAS的成本。

在以太坊区块链上的每一个操作,或者准确地说在以太坊虚拟机(EVM)上的每一个操作都有一个相对应的gas成本。

例如:将两个数字相加要花费3个gas;获取账户余额会花费300个gas;发送一笔交易花费21000个gas。 那么总的gas 就要把这些加起来。

GAS的总成本:=  智能合约使用的GAS ✖️ PRICE (单位为Wei)

如果你的交易设置更高的 gas 价格 ,意味着它更有可能优先在区块链上得到确认,因为以太坊区块链每秒只能确认大约 15 笔交易。  

另一个重要值是 gas 限制(gas ,limit),即你愿意在交易中花费的最大 gas 量。

通过将 gas 价格乘以 gas 限制,您将获得允许以太坊在任何特定交易的 gas 费用上花费的最大以太币数量。

什么是“gwei” 或 wei”,它们与 ETH 有什么关系?

“Wei”是 Ether 的最小单位,其中 10¹⁸ Wei 代表 1 Ether。

1 gwei 是 10⁹ wei,每个 Ether 有 10⁹ gwei。

三、了解GAS执行

当进行智能合约调用时,调用(或交易)将尝试使用程序执行时提供的gas。

  • 如果调用成功,未使用的gas将返还给发送者。

  • 如果调用因 gas 用完而失败,整个交易将恢复,撤消对区块链的所有更改。

    不会返回任何气体,因为它在计算过程中都已用完。

根据新的 EIP-1559 规范,成功交易的一部分 gas 费用将被烧掉(或从总供应量中移除),其余的将发送给将您的交易添加到区块链的矿工。

什么是 EIP-1559,它如何影响 gas 费用?

在 2021 年 8 月 5 日实施以太坊提案 EIP-1559 之前,使用第一价气体拍卖将交易包含在区块链中。

二、了解下智能合约的整体结构

定义以太坊智能合约的许多关键概念不同于 web2 开发范式。

1、类型

在 Solidity 中,合约类型是一种结构,

address 地址类型:是相当于 20 个字节的以太坊地址,以前缀0x开头的十六进制形式表示。

作为开发人员,您会熟悉大多数其他类型 

包括 布尔值、整数、定点数、字节数组和文字等。

更多详细展开 【查阅这里】开发文档。

2、数据存储

在 Solidity 中,参考数据值可以存储为storage、memory或 calldata,具体取决于所存储数据的作用。尤其是:

  • storeage

    将数据永久保存在区块链上,并且非常昂贵。

  • memory

    值仅在智能合约执行的整个生命周期内存储,并且使用成本低廉(仅消耗少量气体)。

  • calldata

    是包含函数参数的特殊数据位置,仅可用于外部函数调用参数。

3、函数修饰符

函数修饰符,是基于外部事务发起的调用来获取/设置信息的功能。这些修饰符决定了除非由外部交易发起,否则智能合约永远无法运行——它们不会在后台静默执行。

访问修饰符包括:

  • public:

    所有函数或调用者都可以访问

  • external:

    只能被外部调用者访问,不能被内部函数访问

  • internal

    只能被这个合约访问,或者从它派生的合约

  • private

    只能从此合约本身访问

其他修饰符包括:

  • view:

    这保证了该函数不会修改合约数据(或存储中的数据)的状态。

  • pure:

    这保证了该函数既不读取也不修改合约数据的状态。

  • payable:
    payable x的函数和地址可以在他们的合约中接收以太币。

4、特殊函数和变量

有许多全局变量和函数将有助于记住您可以访问!

一些特殊的变量是:

  • block.number(uint256): 最近区块的编号。

  • block.timestamp(uint256):最近块的 UNIX 时间戳。

  • block.gaslimit (uint256):当前区块的gas限制。

  • msg.sender(payable address):触发合约的交易的发送者。

  • msg.value (uint256):随消息传输的 wei 数量。

特殊功能包括:

  • receive():

    合约只能声明这些函数之一。它作为合约发送以太币时的默认目的地。

    它不能有参数,不能返回任何东西,并且必须是external和payable。

  • fallback():

    合约只能声明这些函数之一。

    如果对合约的调用不匹配任何函数,或者没有提供数据并且未声明 receive()函数,则它用作后备。它不能有参数,不能返回任何东西,而且必须是外部的。

4、Events

Solidity 在合约执行时发出,永久存储在区块链上,但不能被智能合约修改/读取。

你可以像这样声明并发出一个Event:

event TestEvent (
	uint256 date,
  string value
);

emit TestEvent(block.timestamp,’My first event!”);

可以通过以下几种不同方式访问事件:

  1. 事件存储在交易收据中,可以在那里访问。例如我们要取到代币合约中,所有的转账记录, 过滤出所有的交易事件。

    var transferEvent.watch(function(error, result){
        // handle result.args.from  result.args.to
    });
    
  2. 可以使用myContract.events.TestEvent([options][, callback])订阅事件.

  3. 可以使用myContract.getPastEvents(event[, options][, callback]) 之类的请求来请求过去的事件。

好了,以上这应该让您对智能合约的程序结构以及交易所需要的必要了解!

当然,您也可以通过 Solidity 文档中学到更多的详细信息。

接下去真的要开始写前端程序,开始调用合约了,写一个完整的DApp了。

第五日【完】