智能合约函数解析

426 阅读3分钟

「这是我参与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声明的函数可以接受发送给合约的以太币,如果未指定,该函数将自动拒绝所有发送给它的以太币。

注意事项:

viewpure关键字定义的函数不会改变以太坊区块链的状态,这意味着当你调用这些函数时,你不会向区块链发送任何交易,因为交易被定义为从一个状态到另一个状态的状态栏变换。其仅仅是,你连接的节点通过检查其自己的区块链版本在本地执行函数代码,并将结果返回,而无需将任何交易广播到以太坊网络。

接收以太币函数

合约最多可以具有一个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,表示该函数需要合约的部署者才能调用。

总结

掌握各种函数类型,能帮助我们更加顺手的编写各种各类的合约。智能合约函数要注意安全性,毕竟现在各种智能合约安全问题比较多,所以做好智能合约安全审计比较重要。