「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」
前言
智能合约很重要的一个知识点,必然是函数,懂的各种函数的调用、类型的声明,对我们些合约有着很大的帮助,本文大致总结智能合约所拥有的函数类型。
函数类型
function function_name(<param_type> <param_name>) <visibility> <state mutability> [returns(<return_type>)]{ ... }
1.Private(私有)
函数只能在所定义的智能合约内部调用。这个跟其他语言是差不多的,私有函数。
2.Internal(内部)
将函数声明为此类型,则表示该函数只能在内部调用,或者继承该合约的子合约调用。
3.External(外部)
只能从智能合约外部调用,如果要从当前合约内部调用,那么要使用this.形式。
4.Public(公开)
可以从合约的内部和外部都可以调用,权限比较开,要注意使用,一些重要的方法不要随便声明为public。
5.view
用view声明的函数只能读取数据的状态,不能修改数据,用作读取操作。
6.pure
用该类型声明的函数既不能读取也不能修改状态,即常用作于计算函数。
7.payable
用payable声明的函数可以接受发送给合约的以太币,如果未指定,该函数将自动拒绝所有发送给它的以太币。
注意事项:
用view和pure关键字定义的函数不会改变以太坊区块链的状态,这意味着当你调用这些函数时,你不会向区块链发送任何交易,因为交易被定义为从一个状态到另一个状态的状态栏变换。其仅仅是,你连接的节点通过检查其自己的区块链版本在本地执行函数代码,并将结果返回,而无需将任何交易广播到以太坊网络。
接收以太币函数
合约最多可以具有一个receive函数。这个函数不能有参数,不能返回任何参数,并且必须具有receive可见性和 payable状态可变性。
receive() external payable {
...
}
Fallback函数
合约最多可以具有一个fallback函数(一般翻译为回退函数)。这个函数不能有参数,不能返回任何参数,并且必须具有external可见性。如果其他函数均不匹配给定的函数签名,或者根本没有提供任何数据并且没有receive函数,则在调用合约时执行该函数。
fallback() external [payable]{
...
}
函数修饰器
这个也是经常用的一个函数,可以很好的限制别人非法调用我们的函数,设定为只有管理员才能调用。
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;/** * @title Owner * @dev Set & change owner */contract Owner { address private owner; // event for EVM logging event OwnerSet(address indexed oldOwner, address indexed newOwner); // modifier to check if caller is owner modifier isOwner() { // If the first argument of 'require' evaluates to 'false', execution terminates and all // changes to the state and to Ether balances are reverted. // This used to consume all gas in old EVM versions, but not anymore. // It is often a good idea to use 'require' to check if functions are called correctly. // As a second argument, you can also provide an explanation about what went wrong. require(msg.sender == owner, "Caller is not owner"); _; } /** * @dev Set contract deployer as owner */ constructor() { owner = msg.sender; // 'msg.sender' is sender of current call, contract deployer for a constructor emit OwnerSet(address(0), owner); } /** * @dev Change owner * @param newOwner address of new owner */ function changeOwner(address newOwner) public isOwner { emit OwnerSet(owner, newOwner); owner = newOwner; } /** * @dev Return owner address * @return address of owner */ function getOwner() external view returns (address) { return owner; }}
如这个owner合约用的非常多,modifier 关键字就是我们的函数修饰符。合约部署时,把合约部署者设置为我们的owner。在需要限定调用者的函数上 写上isOwner,表示该函数需要合约的部署者才能调用。
总结
掌握各种函数类型,能帮助我们更加顺手的编写各种各类的合约。智能合约函数要注意安全性,毕竟现在各种智能合约安全问题比较多,所以做好智能合约安全审计比较重要。