Solidity语言学习——(五)
控制语句
solidity中所支持的控制语句:
if else , for , while,do while,三目运算符。不支持switch语句。
直接通过案例学:
// for
contract For {// 等差数列求和function getSum(uint n, uint x) public returns(uint sum) {for (uint index = 0; index < n; index+=x) {sum += index;if (index > 50) {break;}}}
}contract While {function getSum (uint n, uint x) view public returns(uint sum) {uint i = 0;while(i < n) {sum += i;i += x;}}
}contract DoWhile {function getSum(uint n, uint x) view public returns (uint sum) {uint i = 0;do {sum += i;i += x;}while(i < n);}
}contract condition {// 条件控制function getT(uint x,uint y) view public returns(string) {return mulmod(x, y, 2) == 0 ? "偶数":"奇数";}
}
结果为:
合约for
合约While
合约do-while
合约condition
全局单位
货币单位:
wei:1wei
kwei:1000wei
gwei:10的6次方wei
mwei:10的9次方位
mircroether:10的12次方位
millierther(finnry):10的15次方位
ether:10的18次方位
案例:
// 货币单位
contract Money {uint a = 1 ether;uint b = 1 finney;function compare() view public returns(bool) {if (a == 1000 * b) {return true;}return false;}}
结果为:
时间单位:
Seconds,minutes,hours,days,weeks,years。
案例:
// 时间单位
contract tm {uint a = 1;uint b = a * 1 seconds;// seconds,minutes,hours,days,weeks, years 时间单位function getTime() view public returns(uint) {return b;}
}
结果为:
内建的全局变量
在solidity中,内建的全局变量,可以在合约脚本的任何地方使用。
- 包含msg的所有 :msg.sender(发送者地址),msg.value(发送给合约的以太币,默认单位时位),msg.gas(剩余gas),msg.data(调用数据)。
- 包含this的Balance(余额)
- 包含Tx的origin(交易发送者地址),gasprice(gas价格)。
- Now,***.now(当前时间)
- Block属性:Number(区块号),Difficulty(难易程度),Coinbase(矿工地址),Timestamp(时间戳),Gaslimt(当前区块的gaslimit),Blockhash(num)(给定区块的hash值,只支持最近256个区块)。
函数
solidity本身呢也是一门函数型语言,函数可以做参数,变量,返回值。
函数属于值类型,支持多返回值。
调用方式:
内部调用:不copy数据,采用EVM跳转调用,所有能够直接使用和更改上下文的数据,所以在数据传递时非常的高效,
对合约内的函数,引入的库函数和从父合约中继承的函数都可以进行内部调用。
外部调用:使用外部调用得方式,进行调用,函数的所有参数都会先拷贝到内存中,使用external。
案例:
pragma solidity ^0.4.18;contract Func {uint x = 100;uint y = 200;function add() returns(uint) {return x + y;}// 内部调用 function display() public view returns(uint) {return add();}// 多返回值mapping(addres => uint) balances;function insert() public {balances[0xDF5EB3d771DACaD2dA5E8Cb5ae4ccc16BF6D514E] = 100;}function get() public view returns(address, uint) {return(0xDF5EB3d771DACaD2dA5E8Cb5ae4ccc16BF6D514E, balances[0xDF5EB3d771DACaD2dA5E8Cb5ae4ccc16BF6D514E]);}
}
结果为:
函数定义类型:
view :只读,不改变合约的内部状态
注: 1.写入状态变量,2.触发事件 3.创建合约,4.使用自毁函数,5.发送以太币,6.调用任何一个没有被view或者pure的函数,7.底层的调用。
pure:不会修改合约的状态,也不会读合约的状态,基本上就是费用。所以用它读取与合约状态无关的数据。
与view相比,pure的限制还包括更多的内容:
1.不能读取状态变量,2.不能访问this.balance或者address.balance,3.不能访问block.msg的大多数成员(可以访问msg.sig,msg.data),4.调用任何一个没有被标记为pure的函数。
注:如果需要更改状态变量,就不要使用view不然会出现不会报错,但会出警告这样的。
特殊函数类型
1.回退函数:在每个合约中都有一个没名字的函数,该函数没有名字,没参数,没有返回值,这个就是回退函数。
作用:给合约发送eth时也会调用,需要注意的是,如果合约没有定义回调函数的话,接收ether会触发异常。
如果回调函数要接受ether,必须payable修改饰符。
2.自毁函数:自会函数可以摧毁当前合约,如果合约中含有以太币,则会将以太币转移到指定的地址。如果合约在被自毁之后还有人向合约中发送eth,则这些以太币就会消失,无法赎回。
3.常函数:不会修改区块链中的任何状态,没有强制的规定,但是会给警告。关键字为:constant
4.访问器:编译器为自动为所有的public状态变量创建访问器。访问函数具有外部可见性,如果通过内部方式访问,可以直接当成一个变量,但如果通过外部方式进行访问,比如通过this,那么必须通过函数的方式调用。注:只要使用this,它就变成了外部的一个东西。
// 访问器
contract C {uint public c = 10;function accessInternal() returns(uint) {return c; // 内部方式访问}// 通过external(外部)的方式访问function accessExternal() returns(uint) {return this.c();}
}// 调用其它合约的访问器
contract D {C c = new C(); // 实例化其它合约对象function getData() returns(uint) {return c.c();}
}
结果为:
- 其它内置函数
- 加密函数
- ecrecover(hash, v, r, s)
- ripemd160(x)
- sha3(x)
- sha256(x)
- keccak256(x)
- Solidity中的加密实际上调用的是以太中的加密函数
- 数据函数
- addmod(x, y, k):x+y对k取余
- mulmod(x, y, k):x * y 对k 取余
- 函数修改器(modifier)
- 修改器的作用是在函数执行前检查某种前置条件是否满足
- 修改器是一种合约的属性,可以被继承也可以被派生的合约重写。
- 一个函数可以有多个修改器,其间采用空格分开,而修改器的生效顺序与定义顺序一样。
- 修改器中的"_",必须有,没有的话就不叫修改器。
回退函数
调用一个不存在的函数
pragma solidity ^0.4.18;// 1. 实现回退函数
// 调用一个不存在的函数
contract ExecuteFallback {// 新建一个事件,把调用的数据打印出来event FallbackCalled(bytes data);// fallback函数function() {// 调用回退事件FallbackCalled(msg.data);}// existFunc事件event ExistFuncCalled(bytes data, uint256 para);// 写一个已经存在的函数function existFunc(uint256 para) {ExistFuncCalled(msg.data, para);}// 调用一个已经存在的函数function callExistFunc() {bytes4 funcIdentifier = bytes4(keccak256("existFunc(uint256)"));this.call(funcIdentifier, uint256(1));}// 调用一个不存在的函数function callNotExistFunc() {bytes4 funcIdentifier = bytes4(keccak256("functionNotExist"));this.call(funcIdentifier)}// 数据验证function getExist() view returns(bytes32) {return keccak256("existFunc(uint256)");}function getNotExist() view returns(bytes32) {return keccak256("functionNotExist");}
}
自毁函数
// 2. 实现自毁合约
contract SelfDestructionContract {// 权限限制modifier ownerRestricted {require(owner == msg.sender);_;}// 一般来说,能够销毁合约的人必须是合约的所有者address public owner; // 所有人string public someValue; // 值的设置// 构造函数function SelfDestructionContract() {owner = msg.sender;}// 设置一个值function setSomeValue(string value) {someValue = value;}// 调用自毁函数function destroyContract() ownerRestricted {// 自毁函数selfdestruct(owner);}
}
函数的可见性与权限:
内部函数:internal:不能够在当前合约的上下文环境之外执行,只能在当前合约内进行调用,比如当前的代码块,内部的库函数,继承的合约中。在外部调用内部函数会报错。
// 内部函数function internalFun() view internal returns(string){return "internal func";}// 在当前合约内进行内部函数的调用function callInternalFunc() view public returns(string) {return internalFun();}
外部函数:external:可以用从外部函数调用的参数,或者有外部函数调用返回,还可以通过其他合约进行调用,如果时this调用,那么都是在通过external的方式进行调用,不能在内部去调用一个外部函数。
公有函数:public:在哪都可以调用,public类型的状态变量或者函数,会自动创建一个访问器。
私有函数:private:只能在当前合约中进行访问,不能通过继承进行访问。
案例:
contract Chmod {// 内部函数function internalFun() view internal returns(string){return "internal func";}// 在当前合约内进行内部函数的调用function callInternalFunc() view public returns(string) {return internalFun();}// 外部函数function externalFunc() view external returns(string) {return "external func";}// 在当前合约中进行外部函数的调用 会报错,只能通过this进行调用 function callExternalFunc() view public returns(string) {return externalFunc();}// 私有函数function privateFunc() view private returns(string) {return "private func";}// 在当前合约内调用私有函数function callPrivateFunc() view public returns(string) {return privateFunc();}// 公有函数function publicFunc() view public returns(string) {return "public func";}// 在内部调用公有函数function callPublicFunc() view public returns(string) {return publicFunc();}
}
// 外部调用 ,相当于在当前合约的上下文之外进行调用
contract externalCall {Chmod ch = new Chmod(); //合约实例// 外部调用内部函数function callInternalFunc() view public returns(string) {//return ch.internalFun(); 在外部调用内部函数直接报错}// 外部调用外部函数function callExternalFunc() view public returns(string) {return ch.externalFunc();}// 在外部调用私有函数function callPrivateFunc() view public returns(string) {// return ch.privateFunc(); 报错,私有函数在外部不可见}// 外部调用公有函数function callPublicFunc() view public returns(string) {return ch.publicFunc();}
}// 通过继承调用
contract child is Chmod {// 在继承中调用内部函数function callInternal() view public returns(string) {return internalFun();}// 在继承中调用外部函数function callExternalFunc() view public returns(string) {return externalFunc(); // 还是需要通过this进行调用}// 在继承中调用私有函数function callPrivateFunc() view public returns(string) {return privateFunc();}// 在继承中调用公有函数function callPublicFunc() view public returns(string) {return publicFunc();}
}
Solidity语言学习——(五)相关推荐
- c语言中 程序各步作用,C语言学习网总结C语言学习五步曲
很多人对C语言的第一感觉就是太难了,很难理解这种语言,也不知道该如何来理解,书也看了,视频也看了,但就是没什么太大的作用,那么C语言究竟该如何来学? C语言作为一门计算机语言,想要真正的掌握并使用需要 ...
- c语言枚举如何当函数返回值,C语言学习五 — 数组与枚举
数组 C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合.数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量. 数组的声明并不是声明一个个单独的变量,比如 numbe ...
- Solidity语言学习笔记————20、函数修饰符
函数修饰符(Function Modifiers) 修饰符可以用来轻松改变函数的行为,比如在执行的函数之前自动检查条件.他们可继承合约的属性,也可被派生的合约重写. pragma solidity ^ ...
- SQL语言学习(五)流程控制函数学习
1. if()函数 SELECT IF(10<5,"正确","错误"); IFNULL(value1, value2) 如果value1不为空,返回val ...
- Go语言学习 五 注释和文档
本文最初发表在我的个人博客,查看原文,获得更好的阅读体验 一 注释 Go提供了两种风格的注释: 一种是C风格的块注释/* */,另一种是C++风格的行注释//,一般情况下使用行注释就可以了:块注释更多 ...
- Solidity语言详解
Solidity语言学习学习总结 文章目录 Solidity语言学习学习总结 一.合约文件剖析 1.1一个合约文件的结构如下: 1.2合约的引入import 1.3引入状态变量.函数.事件.函数修改器 ...
- Python语言学习:基于python五种方法实现使用某函数名【func_01】的字符串格式('func_01')来调用该函数【func_01】执行功能
Python语言学习:基于python五种方法实现使用某函数名[func_01]的字符串格式('func_01')来调用该函数[func_01]执行功能 目录 问题提出 代码五种设计思路 T1方法:e ...
- C语言学习笔记第五天_项目训练
C语言学习笔记第五天_项目训练 添加自定义的一个函数库文件 <getch.h> 步骤: 1.在windows中把getch.h放入共享文件夹(文件我放在文末,自取) 2.在Ubuntu终端 ...
- C语言学习笔记(十五)
C语言学习第十五天 2.7 类型转换 当一个运算符的几个操作 数类型不同时,就需要通过一些规则把它们转换为某种共同的类型.一般来说,自动转换时指把"比较窄的"操作数转换为" ...
最新文章
- C++随时输出到文件-outfile
- python中单个下划线是什么意思
- python支持向量机框架_Netflix 内部 Python 框架 Metaflow 正式开源,可加速机器学习模型部署...
- vue绑定html的class属性的方法
- Netty - 传输
- pillow是python的图像处理标准库_详解Python图像处理库Pillow常用使用方法
- acl 允许同网段访问_ENSP模拟交换环境中调用高级ACL限制不同网段之间互访
- 辨异 —— 机器学习概念辨异、模型理解
- Strategy模式的一点思考
- 在线教育:最常见的直播课程有哪些?
- matlab如何插入“埃”这个符号
- 图解:最短路径之迪杰斯特拉算法
- 教程篇(7.0) 03. FortiClient EMS配置和管理 ❀ FortiClient EMS ❀ Fortinet 网络安全专家 NSE 5
- 智齿客服签约垂直日本的最大旅游服务平台仙贝旅行
- 云边协同的智能制造系统
- 三分钟解决文档编辑难题-【文档编辑命令- cat echo vi/vim tail rmdir 】
- MySQL慢查询配置和使用
- 实验三 算符优先分析算法的设计与实现
- java计算机毕业设计公益诊疗系统源程序+mysql+系统+lw文档+远程调试
- 泰森多边形(Voronoi图)
热门文章
- 1恢复 群晖raid_群晖RAID1在线扩容实验及步骤
- C数据结构之十大排序
- 服务器显示发送时间为送达,拉黑还会显示已送达吗
- Pytorch/Python计算交并比IOU(IU)代码(批量算IOU)
- matlab 牛顿法(Newton)与弦截法的迭代实现 解非线性方程
- AVProVideo动态设置DisplayUGUI的UVRect失效,重新绘制顶点(Graphic.SetVerticesDirty())
- 【数据分析】中介效应的简介、模型、python代码实现以及数据可视化
- 验证用户名与密码的15个正则
- 大型建企招聘,大量岗位可选择
- 「镁客·请讲」Lucia 焦玉龙:用区块链技术切入长租行业,Lucia要做长租领域的变革者...