Solidity之修饰符

本节主要介绍修饰符的用法及其区别。
函数的可见性修饰符包括:internal、public、private、external
还有一些修饰符,主要对状态变量的修改能力进行规定:constant、payable、view、pure。

1.修饰符说明

1.1 internal修饰符

internal声明的函数和状态变量只能通过内部访问,如在当前合约中调用或在继承的合约中调用。internal为默认的修饰符,如果大家有学过java或者C++的话,internal类似于其中的protected。另外,要注意的是,internal声明的函数是不能从外部访问的。

  • 实操:
pragma solidity ^0.8.0;
contract MyContract {
    uint public publicVariable;
    uint internal internalVariable;
    //constructor用于初始化类的对象。它是在创建对象时自动调用的
    constructor(uint _publicVariable, uint _internalVariable) public {
        publicVariable = _publicVariable;
        internalVariable = _internalVariable;
    }
    
    function getInternalVariable() internal view returns (uint) {
        return internalVariable;
    }
}

1.2 external修饰符

外部函数是合约接口的一部分,所以可以从其他合约或通过交易来发起调用。比如,外部函数a()不能通过内部方法发起调用,那么怎么解决这个问题呢,我们可以通过this.a来调用。

  • 实操
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MyContract {
    function myFunction() external returns (uint) {
        // function code here
    }
}

1.3 public修饰符

可以通过内部或者外部函数来调用,public类型的状态变量会自动创建一个访问器。

  • 实操:
pragma solidity ^0.8.0;

contract MyContract {
    uint public myNumber;

    function setNumber(uint _number) public {
        myNumber = _number;
    }
}

1.4 private修饰符

私有函数和状态变量仅在当前合约中可以访问,在继承的合约中不可以访问。私有函数不是合约接口的一部分。

  • 实操
pragma solidity ^0.8.0;
contract MyContract {
    uint private myPrivateVariable;

    function setMyPrivateVariable(uint newValue) public {
        myPrivateVariable = newValue;
    }

    function getMyPrivateVariable() public view returns (uint) {
        return myPrivateVariable;
    }
}

1.5 constant修饰符

constant可以读取状态变量并返回给调用者。但是不能进行以下操作:改变事件,创建另一个合约,调用其他可能改变状态的函数。
实操:

function getNumber() public constant returns (uint) {
    return 42;
}

1.6 payable 修饰符

简单来说。三个字讲清楚。转账用

  • 实操:
function buySomething() public payable {
  // function code here
}

1.7 view关键字

等同于constant生命的函数,只读取,不改变状态

1.8 pure 修饰符

为函数增加了很多限制,不能当问当前的状态和交易变量,不能读写状态变量

2 修饰符的区别

2.1 external和public修饰符的区别

internal和public是两个访问修饰符,用于控制函数和变量的可见性。public表示该函数或变量可以被任何人访问,而internal表示只有合约内部的函数可以访问该函数或变量。

  • 实操:
    public 表示函数或状态变量可以从合约内外任何地方访问
pragma solidity ^0.8.0;
contract MyContract {
    uint256 public a;
  
    function setA(uint256 _a) public {
        a = _a;
    }
}

在这个例子中,状态变量 a 和函数 setA 都使用了 public 关键字。这意味着我们可以从合约内外的任何地方读取和修改 a 的值,并且可以调用 setA 函数来设置 a 的值。

  • 实操
    internal 表示函数或状态变量只能在当前合约以及继承它的合约中访问。
pragma solidity ^0.8.0;
contract MyContract {
    uint256 internal y;
  
    function getY() internal view returns (uint256) {
        return y;
    }
}

contract AnotherContract is MyContract {
    function test() public {
        uint256 value = getY();
        // do something with value
    }
}

2.2 internal和external修饰符

internal 和 external 都是访问控制关键字,用于控制函数的可见性。

  • 实操
    internal 表示函数只能在合约内部或者继承自合约的合约中被访问。
contract MyContract {
    uint256 internal x;

    function foo() internal view returns (uint256) {
        return x;
    }
}

contract AnotherContract is MyContract {
    function bar() public view returns (uint256) {
        return foo();
    }
}

在这个例子中,foo 函数使用了 internal 关键字,意味着它只能在 MyContract 合约内部或者继承自 MyContract 的合约(例如 AnotherContract)中被调用。

  • 实操
    external 表示函数只能在合约外部被调用,不能在合约内部调用
contract MyContract {
    function foo() external pure returns (uint256) {
        return 42;
    }
}

在这个例子中,foo 函数使用了 external 关键字,意味着它只能在合约外部被调用。我们可以通过调用合约的地址和函数的签名来调用它,但不能在合约内部直接调用。

3.自定义修饰符

修饰符(Modifier)是一种可重用的代码块,可以被用于修改函数的行为。通过自定义修饰符,我们可以在不改变函数逻辑的情况下,对函数进行额外的检查或操作,从而提高合约的安全性和可读性。

  • 实操
    自定义修饰符的语法如下:
modifier <modifier_name>(<modifier_params>) {
    // 额外的检查或操作
    _;  // 表示将流程交还给原来的函数体
}

其中,<modifier_name> 是修饰符的名称,<modifier_params> 是修饰符的参数,可以是任何类型。在修饰符中,我们可以添加额外的检查或操作,例如:检查调用者是否满足某些条件、记录日志、修改状态变量等等。

  • 实操
    修饰符可以用在函数定义时,用来对函数进行修饰。以下是一个使用自定义修饰符的示例:
contract MyContract {
    address public owner;

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this function.");
        _;
    }

    function setOwner(address newOwner) public onlyOwner {
        owner = newOwner;
    }
}

在这个例子中,我们定义了一个名为 onlyOwner 的修饰符,它要求调用者必须是合约的 owner 地址。当调用 setOwner 函数时,只有合约的 owner 地址才能成功调用该函数,其他地址将会被拒绝。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员大凯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值