Solidity入门1: 3. 函数类型

Solidity中的函数

solidity官方文档里把函数归到数值类型

函数结构
function <function name>(<parameter types>) {internal|external|public|private} [pure|view|payable] [returns (<return types>)]

看着些复杂,咱们从前往后一个一个看(方括号中的是可写可不写的关键字):

  1. function声明函数时的固定用法,想写函数,就要以function关键字开头。

  2. <function name>函数名。

  3. (<parameter types>)圆括号里写函数的参数,也就是要输入到函数的变量类型和名字。

  4. {internal|external|public|private}函数可见性说明符,一共4种。没标明函数类型的,默认public。合约之外的函数,即"自由函数",始终具有隐含internal可见性。

    • public: 内部外部均可见。
    • private: 只能从本合约内部访问,继承的合约也不能用。
    • external: 只能从合约外部访问(但是可以用this.f()来调用,f是函数名)。
    • internal: 只能从合约内部访问,继承的合约可以用。
  5. Note 1: 没有标明可见性类型的函数,默认为public

    Note 2public|private|internal 也可用于修饰状态变量。 public变量会自动生成同名的getter函数,用于查询数值。

    Note 3: 没有标明可见性类型的状态变量,默认为internal

  6. [pure|view|payable]决定函数权限/功能的关键字。payable(可支付的)很好理解,带着它的函数,运行的时候可以给合约转入ETH

  7. [returns ()]函数返回的变量类型和名称。

 

到底什么是PureView?​

        我刚开始学solidity的时候,一直不理解pureview关键字,因为别的语言没有类似的关键字。solidity加入这两个关键字,我认为是因为gas fee。合约的状态变量存储在链上,gas fee很贵,如果不改变链上状态,就不用付gas。包含pureview关键字的函数是不改写链上状态的,因此用户直接调用他们是不需要付gas的(合约中非pure/view函数调用它们则会改写链上状态,需要付gas)。

在以太坊中,以下语句被视为修改链上状态:

  1. 写入状态变量。
  2. 释放事件。
  3. 创建其他合约。
  4. 使用selfdestruct.
  5. 通过调用发送以太币。
  6. 调用任何未标记viewpure的函数。
  7. 使用低级调用(low-level calls)。
  8. 使用包含某些操作码的内联汇编。

        我画了一个马里奥插画,帮助大家理解。在插画里,我把合约中的状态变量(存储在链上)比作碧池公主,三种不同的角色代表不同的关键字。

  • pure,中文意思是“纯”,在solidity里理解为“纯纯牛马”。包含pure关键字的函数,不能读取也不能写入存储在链上的状态变量。就像小怪一样,看不到也摸不到碧池公主。

  • view,“看”,在solidity里理解为“看客”。包含view关键字的函数,能读取但也不能写入状态变量。类似马里奥,能看到碧池,但终究是看客,不能入洞房。

  • 不写pure也不写view,函数既可以读取也可以写入状态变量。类似马里奥里的boss,可以对碧池公主为所欲为🐶。

代码​

1. pure 与 view的对比 ​

        我们在合约里定义一个状态变量 number = 5

// SPDX-License-Identifier: MITpragma solidity ^0.8.4;contract FunctionTypes{uint256 public number = 5;
}

        定义一个add()函数,每次调用,每次给number + 1

    // 默认function add() external{number = number + 1;}

        如果add()包含了pure关键字,例如 function add() external pure就会报错。因为pure(纯纯牛马)是不配读取合约里的状态变量的,更不配改写。那pure函数能做些什么?

举个例子,你可以给函数传递一个参数 _number,然后让他返回 _number+1

    // pure: 纯纯牛马function addPure(uint256 _number) external pure returns(uint256 new_number){new_number = _number + 1;}

        如果add()包含view,比如function add() external view也会报错。因为view能读取,但不能够改写状态变量。可以稍微改写下方程,让他不改写number,而是返回一个新的变量。

    // view: 看客function addView() external view returns(uint256 new_number) {new_number = number + 1;}

2. internal v.s. external​

    // internal: 内部function minus() internal {number = number - 1;}// 合约内的函数可以调用内部函数function minusCall() external {minus();}

我们定义一个internalminus()函数,每次调用使得number变量减1。由于是internal,只能由合约内部调用,而外部不能。因此,我们必须再定义一个externalminusCall()函数,来间接调用内部的minus()。 

Example:

3、payable

    // payable: 递钱,能给合约支付eth的函数function minusPayable() external payable returns(uint256 balance) {minus();    balance = address(this).balance;}

        我们定义一个external payableminusPayable()函数,间接的调用minus(),并且返回合约里的ETH余额(this关键字可以让我们引用合约地址)。 我们可以在调用minusPayable()时,往合约里转入1个ETH

我们可以在返回的信息中看到,合约的余额是1 ETH。

Example:

    本节介绍了solidity中的函数类型,比较难理解的是pureview,在其他语言中没出现过。solidity引入pureview关键字主要是为了节省gas和控制函数权限:如果用户直接调用pure/view方程是不消耗gas的(合约中非pure/view函数调用它们则会改写链上状态,需要付gas)。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/593885.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进程的控制

进程的创建 frok函数添加进程 进程内核的相关管理数据结构&#xff08;task_struct mm_struct页表&#xff09;代码数据 特性&#xff1a; 分配新的内存块和内核数据结构给子进程将父进程部分数据结构内容拷贝至子进程添加子进程到系统进程列表当中fork返回&#xff0c;开始调…

grep无法使用完整的正则表达式

问题描述 grep无法使用完整的正则表达式&#xff0c;比如前置断言、后置断言、\d和\t、\n等 问题原因 使用了扩展正则&#xff0c;而不是perl正则。规则和perl正则不同 从文档上讲得很清楚&#xff1a; -E PATTERN is an extended regular expression 他是扩展表达式&#…

文字超出收起展开功能的实现(vue2)

1.编写展开收起组件 <template><div class"text-clamp"><div class"text" :style"{height}"><span v-if"isVisible" class"btn" click"toggle">{{isExpand ? 收起 : ... 展开}}</spa…

2024/4/5 AT24C02 总线(I²C总线)

存储器的介绍&#xff1a; 一、易失性存储器RAM&#xff1a;存储速度快&#xff0c;掉电丢失 SRAM&#xff08;静态RAM&#xff09;&#xff1a;极快DRAM&#xff08;动态RAM&#xff09;&#xff1a;需要配一个扫描电路&#xff0c;进行“补电”&#xff08;动态刷新&#x…

第20次修改了可删除可持久保存的前端html备忘录:重新布局

第20次修改了可删除可持久保存的前端html备忘录&#xff1a;重新布局 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

易宝OA ExecuteQueryForDataSetBinary SQL注入漏洞复现

0x01 产品简介 易宝OA系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台,具有信息管理、 流程管理 、知识管理(档案和业务管理)、协同办公等多种功能。 0x02 漏洞概述 易宝OA ExecuteQueryForDataSetBinary 接口处存在SQL注入漏洞,未经身份认证的攻击者…

基于SpringBoot+Vue实现前后端分离的房屋租赁系统

一、&#x1f680;选题背景介绍 &#x1f4da;推荐理由&#xff1a; 计进行房屋租赁工作的管理&#xff0c;不仅能够保证各项信息准确无误、快速输出&#xff0c;同时计算机具有手工管理所无法比拟的优点&#xff0c;例如:检索迅速、查找方便、可靠性高、存储量大、保密性好、寿…

实用技巧:如何取消app的截屏禁用

因为我想要在小鹅通App做笔记,但是被小鹅通App禁用截屏了,这真是一个很糟糕的使用体验,虽然可能是为了保护商家权益…… 方法1 可以让商家设置课程可以截屏 方法2 手机root,安装Xposed框架,利用Xposed框架上面的插件我们可以对手机进行高度定制化,而安装Xposed框架的…

【Python基础教程】5. 数

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;python基础教程 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、…

第33关 使用gin开发webhook转发服务,实现prometheus和falco的钉钉、企业微信、飞书报警发送

------> 课程视频同步分享在今日头条和B站 大家好&#xff0c;我是博哥爱运维。 出这期视频&#xff0c;也是为了给第30关的falco公开课补一个坑&#xff0c;关于falco报警这块这期将补上&#xff0c;同时&#xff0c;对于这个gin开发的webhook服务源码这块&#xff0c;计划…

leetcode刷题-代码训练营-第7章-回溯算法1

回溯法模板 void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本层集合中元素&#xff08;树中节点孩子的数量就是集合的大小&#xff09;) {处理节点;backtracking(路径&#xff0c;选择列表); // 递归回溯&#xff0c;撤销处理结果} }理解 从…

力扣108. 将有序数组转换为二叉搜索树

Problem: 108. 将有序数组转换为二叉搜索树 文章目录 题目描述思路复杂度Code 题目描述 思路 根据二叉搜索树中序遍历为一个有序序列的特点得到&#xff1a; 1.定义左右下标left&#xff0c;right分别指向有序序列的头尾&#xff1b; 2.每次取出left和right的中间节点mid&…