深入理解Solidity 三

Solidity函数声明和类型

  •  函数的值类型有两类:内部(internal)类型和外部(external)类型
  • 内部函数只可以在当前合约内部被调用(即在当前代码块内,包括内部库函数和继承函数),因为他们不能在当前合约的上下文中的外部被执行。调用一个内部函数是通过跳转到它的入口标签来实现的,就像在当前合约的内部调用一个函数
  • 外部函数是由一个地址和一个函数的签名组成,可以通过外部函数调用传递或者返回
  • 调用内部函数,直接使用名字f
  • 调用外部函数:this.f(当前合约),a.f(外部合约)
  • 除了使用外部函数调用外,还可以使用继承机制

例子(外部函数调用)

contract C{uint a;function f() public{}
}
contract D{function g() public{C c = new C();c.f();}
}

例子(继承机制)

  • 可以使用internal函数/public函数,不可以使用private函数
  • D继承C合约,只会把交叉的函数编译上传
contract C{uint a;function f() public{}
}
contract D is C{function g() public{f();}
}

函数的可见性

  • 函数的可见性可以指定为external、public、internal或者private;对于状态变量,不可以设置为external,默认是internal
  • external:外部函数作为合约接口的一部分,意味着我们可以从其他合约和交易中调用。一个外部函数f不可以从内部调用(即f不起作用,但是this.f可以)。当接收到大量的数据的时候,外部函数有时候会更有效率
  • public:public函数是合约接口的一部分,相当于定义了一个view类型的可以返回参数的函数,可以在内部或者通过消息调用。对于public状态变量,会自动生成一个getter函数

例子

uint public a;//将a声明为public,就相当于为a定义了如下的函数形式
function a() public view returns (uint){return a;
}
  • internal:这些函数和状态变量只能是内部访问(即从当前合约内部或者从其他派生的合约访问),不可以使用this
  • private:private函数和状态变量仅在当前定义他们的合约中使用,并且不能被派生合约使用。

函数状态可变性

  • payable:允许从消息调用中接收以太币Ether
  • constant:和view相同,一般只修饰状态变量,不允许赋值(除了初始化之外)
 constructor()public payable{}//创建合约的同时需要往合约上面转钱
  • pure:纯函数,不允许修改或者访问状态
  • view:不允许修改状态

函数状态可变性

  • 修改状态变量
  • 产生事件
  • 创建其他合约
  • 使用selfdestruct(自杀/自毁)
  • 通过调用发送以太币
  • 调用任何没有标记为view或者pure的函数
  • 使用低级调用
  • 使用包含特定操作吗的内联汇编

以下是被认为从状态中进行读取

  • 读取状态变量
  • 访问this.balance或者<address>.balance
  • 访问block、tx、msg中任意成员(除了msg.sig和msg.data之外)
  • 调用任何未标记为pure的函数
  • 使用包含某些操作码的内联汇编

函数修饰器 modifier

  • 使用修饰器modifier可以轻松改变函数的行为。例如,他们可以在执行函数之前自动检查某个条件。修饰器modifier是合约的可继承属性,并可能被派生合约覆盖
  • 如果同一个函数有多个修饰器modifier,他们之间可以使用空格隔开,修饰器modifier会依次检查执行。

代码

contract Purchase{address public seller;constructor() public{seller = msg.sender;}modifier onlySeller(){require(msg.sender == seller,"Only seller");_;}function f() public view onlySeller returns(uint){return 200;}
}

效果展示

  • msg.sender是合约的部署者,只有合约的部署者调用f函数,返回200,剩余的人会返回错误信息,only seller
  • require(msg.sender == seller,"Only seller");逗号之前是检查条件,之后是返回报错信息,检查条件在代码流程之前执行
  • _;将代码流程嵌套到这里,指代检查条件执行之后,执行代码的逻辑。(函数体)

回退函数(fallback)

  • 回退函数(fallback function)是合约中的特殊函数;没有名字,不能有参数也不能有返回值
  • 如果在一个到合约的调用中,没有其他函数与给定的函数标示符匹配(或者没有提供调用函数),你们这个函数(fallbacj函数)会被执行
  • 每当合约收到以太币(没有任何数据),回退函数就会执行。此外,为了接收以太币,fallback函数必须标记为payable。如果不存在这样的函数,则合约不能通过常规交易接收以太币
  • 在上下文中只有很少的gas可以用来完成回退函数的调用,所以使fallback函数的调用尽量廉价很重要

代码

pragma solidity >0.4.99  <0.6.0;
contract Sink{function() external payable{}
}
contract Test{function() external {x=1;}uint x;
}contract Caller{function calllTest(Test test)public returns(bool){(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));require(success);address payable testPayable = address(uint160(address(test)));return testPayable.send(2 ether);}
}

注解

  • 调用合约中不存在的函数和转钱的时候会调用回退函数
  • 回退函数适用在合约5.0版本以上

事件(event)

  • 事件是以太坊EVM提供的一种日志基础设施。事件可以用来做操作记录,存储为日志。也可以用来实现一些交互功能,比如通知UI,返回函数的调用结果
  • 当定义的事件被触发时,可以将事件存储到EVM的交易日志中,日志是区块链中的一种特殊的数据结构;日志和合约相互关联,与合约的存储合并存入到区块链条中,只要某个区块可以访问,其相关的日志就可以访问,但是在合约中是不可以之间访问日志和事件数据
  • 可以通过日志实现简单支付验证SPV,如果一个外部实体提供了一个带有这种证明的合约,它可以检查日志是否真实存在于区块链中

异常处理

  • 适用状态恢复异常来处理异常。这样的异常将会撤销对于当前的调用(及其所有的子调用)中的状态所做的所有的更改,并且向调用者返回错误
  • 函数的assert和require用于判断条件,并且在不满足条件的时候抛出异常
  • assert()一般只应用于测试内部的错误,并且检查异常
  • require()应用于确保满足有效的条件(如输入或合约的状态变量),或者验证调用外部合约的返回值
  • revert()用于抛出异常,它可以标记一个错误并且将当前调用回退

单位

  • 以太币单位之间的换算就是在数字后边加上wei、finney、szabo或者ether来实现,如果没有单位,缺省为wei

时间

  • 秒是缺省单位,在时间单位之间,数字后面带有seconds、minutes、hours、days、weeks和years的可以进行换算 但是这些后缀不可以直接用在变量的后边,如果需要使用到时间单位(例如days)来将输入变量转换为时间,可以使用如下方式
function f(uint start,uint daysAfter)public{if (now >= start + daysAfter * 1 days)
}

 

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

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

相关文章

安装solc模块4.25版本

使用国产阿里云的cnpm 如果不知道cnpm 参考链接 安装solc模块4.25版本 npm i solc0.4.25 --save -g查看安装是否成功 可以配置软连接使用solc&#xff0c;我的没有配置 solcjs --version

在pycharm中使用conda虚拟环境(conda虚拟环境是已经创建好的),解决python安装包文件很费劲的问题

查看conda的虚拟环境 使用PyCharm连接conda创建的虚拟环境&#xff0c;需要一个前提就是虚拟环境必须存在&#xff0c;使用conda env list命令查看虚拟环境列表打开PyCharm软件 打开pycharm&#xff0c;选择File->setting->Project:****->Project Interperter&#…

完成一个H.265/HEVC码流分析工具

经过大约一个月左右的业余时间&#xff0c;终于初步完成一个H.265/HEVC码流分析工具。时间包括平时的周末、晚上&#xff0c;以及调休的集中时间。当然&#xff0c;中秋回家过节不写代码。截至今天&#xff0c;经过多种H.265序列测试&#xff0c;也有各种工具对比&#xff0c;基…

Golomb及指数哥伦布编码原理介绍及实现

文章来源&#xff1a; https://www.cnblogs.com/wangguchangqing/p/6297792.html &#xff0c; 写的不错&#xff0c;转发出来。 2017年的第一篇博文。 本文主要有以下三部分内容&#xff1a; 介绍了Golomb编码&#xff0c;及其两个变种&#xff1a;Golomb-Rice和Exp-Golo…

解决ipfs 出现Error: can‘t publish while offline: pass `--allow-offline` to override的问题

原因 出现这个问题的原因是因为&#xff0c;ipfs未与公网上的节点相互连接&#xff0c;因此此时处于离线状态 使用场景 部署自己的博客&#xff0c;后期的改动&#xff0c;累计追加在同一个地址&#xff0c;这个地址是唯一的&#xff0c;也就是创建ipfs生成的ID号 步骤 1&…

安装ipfs-http-client出现constants@0.1.2 install: node build.js > index.browser.js错误的解决办法

错误截图 原先的命令 npm install --save-dev ipfs-http-client 修改后的命令 npm install --save-dev ipfs-http-client --unsafe-permtrue --allow-root

安装ipfs-api的命令变了,最新版的命令如下

原先使用的命令安装ipfs-api npm install --save-dev ipfs-api 现在使用的命令安装ipfs-api npm install --save-dev ipfs-http-client 官方文档 参考教程 官方文档

区块链相关问题 理解

本博客针对区块链的部分问题进行详解&#xff0c;希望帮助大家对于区块链有一个更好的理解 1&#xff0c;如果散布虚假交易&#xff0c;怎么整&#xff1f;&#xff08;谁欠我XXX比特币&#xff09; 1&#xff0c;可以发起虚假交易&#xff0c;但是很难被全网的节点接收并写入…

区块链的相关知识点

1&#xff0c;密码学原理 密码学原理 1&#xff0c;collision resistance 哈希函数 &#xff0c;目前还是很安全的&#xff0c;没有找到任何不同的内容其哈希是一致的情形。哈希碰撞&#xff08;这个在数学上面是没法证明的&#xff0c;都是日常的实践表明&#xff0c;无法找…

使用MAC 编译合约的时候报错:

编译报错的显示内容如下&#xff1a; Error: EACCES: permission denied, mkdir /Users/chy/Documents/ipfslearn/ipfs_eth_img/client/src/contracts 最简单的解决方法 原因分析&#xff1a;执行的权限不够 解决办法&#xff1a;升级权限 使用命令 chmod 777 项目的文件夹使…

最新,使用truffle框架之后,安装ipfs的api包文件的命令变化

原因 项目文件路径变化了&#xff0c;不是先前直接在项目文件夹里面直接执行安装ipfs的命令了&#xff0c;需要切换到client文件夹下面执行 路径不对&#xff0c;会出现错误&#xff0c;错误提示如下 切换到正确的路径之后&#xff0c;使用命令 npm install --save ipfs-http-…

通过node 完成简单的web3 API调用测试

使用命令查看当前web3的版本 npm list web3输入命令 node&#xff0c;进入终端 引入web3&#xff0c;使用命令 var web3 require(web3) 查看引入web3的版本 web3.version

LInux学习笔记(四)-----实操排雷

参考书籍&#xff1a;linux就该这么学 4 Vim 编辑器与 Shell 命令脚本 4.1 Vim 文本编辑器(在 Vim 中&#xff0c;无法直接从输入模式切换到末行模式) 4.1.1 配置 Yum 软件仓库 注&#xff1a;书中好像有点问题&#xff0c;第一个 . 改成 /&#xff08;我是Ubuntu发现原来不能用…

Web3.js 学习

web3.js Web3 JavaScript app APIweb3.js是一个JavaScript API库&#xff0c;一般使得DApp在以太坊上运行web3.js通过RPC调用与本节点通信&#xff0c;用于任何暴露了RPC层的以太坊节点之间通信web3包含了eth对象&#xff0c;即web3.eth&#xff08;专门和以太坊区块链交互&am…

c语言指针入门

指针的用途非常广泛&#xff0c;比如如果你想通过函数改变一个变量的值&#xff0c;就得用指针而不能用值传递。还有在很多时候变量&#xff0c;特别是对象的数据量实在太大&#xff0c;程序员就会用指针来做形参&#xff0c;只需要传递一个地址就行&#xff0c;大大提高了效率…

搭建基于飞桨的OCR工具库,总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别、竖排文本识别、长文本识别的PaddleOCR

介绍 基于飞桨的OCR工具库&#xff0c;包含总模型仅8.6M的超轻量级中文OCR&#xff0c;单模型支持中英文数字组合识别、竖排文本识别、长文本识别。同时支持多种文本检测、文本识别的训练算法。 相关链接 PaddleOCR项目地址飞桨开源深度学习平台效果展示页面中文OCR在线体验地…

macos 10.15 django2.2+apache2.4+ladon+wsgi写webseverice接口

他的文档不够完善&#xff0c;使用起来可能有坑&#xff0c;因为不知道如何将ladondjangoapache绑定在一起使用&#xff0c;所以放弃了。 提醒&#xff1a;最好用个虚拟环境&#xff0c;防止库冲突我使用的是anaconda 安装apache macos本身自带apache&#xff0c;其他平台百度…

基于HubServing的PaddleOCR部署

前提要求 服务器的部署需要鉴于先前安装配置的docker环境&#xff0c;因此相关步骤查看我之前的博客 参考链接 服务部署 先前介绍 参考链接 官方推荐本博客采用基于HubServing的部署&#xff0c;这种方式已经集成到PaddleOCR里面&#xff0c;在先前的docker镜像里面就可以…

我的职业生涯规划学习日记(软件工程)整理时间线

学习路线 语言只是工具不过学c一直都做不出来东西是为什么呢&#xff0c;下图要第六部才做项目 概述 大一上学期&#xff1a;C&#xff0c;C&#xff0c;数据结构&#xff0c;cstl源码&#xff0c;python爬虫进入物联网实验室python方向&#xff0c;进入算法协会运维部学习算…

PaddleOCR和ChineseOCR的对比

PaddleOCR和ChineseOCR的对比 ChineseOCRPaddleOCR 对比 识别时间 chineseOCR识别的速度相对于PaddleOCR较慢&#xff0c;单纯使用CPU对于单张图片的识别时间可以达到20秒&#xff0c;如果使用GPU识别的时间一般控制在5秒以内&#xff08;图片包含的文字比较少的情形&#x…