Solidity学习::(16)函数修改器

函数修改器


作用

函数修改器(Function Modifiers)可以方便的控制函数的逻辑,比如可以在某个行为执行前检查某个前置条件,函数修改器还支持继承和重写。

定义格式:

  modifier onlyOwner {
    if (msg.sender != owner) throw;
    _;
  }

在函数修改器代码块内,判断条件不符合就抛出异常,符合则执行占位符_处代码,_代指的是使用函数修改器的函数体。

函数修改器允许return;(中断当前流程)。但不允许明确的return值。

 应用实例1:修改合约所有者

  • 定义一个函数实现修改合约所有者的功能
  • 只有合约的所有者才能调用该函数

 代码:

pragma solidity ^0.4.0;
contract Ownable {
  address public owner = msg.sender; //在合约创建时,这里先被调用一次

  /// 限制只有所有者才能访问
  //修改器
  modifier onlyOwner {
    if (msg.sender != owner) throw;
    _;
  }

  /// 改变合约的所有者 【注意这里的格式,先是修改器的名字,才是大括号】
  //修改器检查调用这个函数的是否合约的所有者
  function changeOwner(address _newOwner)
  onlyOwner
  {
    if(_newOwner == 0x0) throw;
    owner = _newOwner;
  }
}

 


函数修改器可传参

应用实例2:编写一份合约,实现剩余电量Soc交易

  • 创建一个函数修改器,参变量为余额和交易额【那么这个函数修改器则可泛化(可复用性提高),不一定要是Soc交易的检查】
pragma solidity ^0.4.0;

contract Parameter{
  //建立映射,每个账户下有Soc记录
  mapping(address=>uint) public Soc;
  
  //构造函数,初始化合约创建者的Soc
  function Parameter(){
      Soc[msg.sender]=uint(100);
  }
  //函数修改器,用来检查Soc交易方Soc是否足够
  modifier balance_check(uint _balance,uint _transactionAmount){
      if(_balance<=_transactionAmount) throw;
      _;
  }
  //Soc交易函数
  function electricity_transact(address _to,uint _elec_amount) 
  balance_check(Soc[msg.sender],_elec_amount){
      if(_to==0x0) throw;
      Soc[msg.sender]=Soc[msg.sender]-_elec_amount;
      Soc[_to]=Soc[_to]+_elec_amount;
  }
}

 测试操作:

(1)编译、部署合约【部署合约的账户下的在该合约下的Soc会初始化为100】

        这里我们部署的账户地址为:0xca35b7d915458ef540ade6068dfe2f44e8fa733c

       

(2)在electricity_transact函数中,填入其他账户地址和交易的数额

 1、先填一个大于100的

 尝试交易------------------->抛出异常了

 2、再用小于100的交易额

尝试交易------------------>交易成功

再看看对应账户下的Soc

 


 如果函数有返回值

如果函数有返回值,且函数修改器抛出异常,那么将返回对应类型的默认值

 测试代码:

pragma solidity ^0.4.0;

contract Return{
  //函数修改器永远不成功
  modifier A() {
      if(false)
        _;
  }

  //返回默认值
  function uintReturn() A returns(uint){
      uint a = 0;
      return uint(1);
  }
  
  //返回默认值
  function stringReturn() A returns(string){
      return "Hello world";
  }
}

上例中,我们写了一个特殊的函数修改器A,永远判断不成功。故uintReturn(),stringReturn()中的代码都将不会执行。上述函数将分别返回uint,string的默认值0和空串。


 函数修改器执行流程

如果函数修改器 " _; "  后面还有可执行代码,那么在对应函数体return或执行完之后,会继续在函数修改器中往下执行 

 测试代码:

pragma solidity ^0.4.0;

contract ProcessFlow{
  mapping(bool => uint) public mapp;

  modifier A(mapping(bool => uint) mapp){
    if(mapp[true] == 0){
      mapp[true]= 1;
      _;
      mapp[true]= 3;
    }
  }

  function f() A(mapp) returns(uint){
    mapp[true] = 2;
    return mapp[true];
  }
}

 全部代码执行完后,可以看到mapp[true]的值为3


 多个函数修改器

一个函数可使用多个函数修改器,定义时依次填写,并用空格隔开。函数修改器执行时,将按定义顺序依次执行。

测试代码:

 

pragma solidity ^0.4.0;

contract MultiModifier{
  address owner = msg.sender;

  /// 限制只有创建者才能访问
  modifier onlyOwner {
    if (msg.sender != owner) throw;
    _;
  }

  modifier inState(bool state){
    if(!state) throw;
    _;
  }

  //多个函数修改器
  function f(bool state) onlyOwner inState(state) returns(uint){
    return 1;
  }

}

重写(overwrite)

可以重写父类的函数修改器。来改变父类的修改器行为。

测试代码:

pragma solidity ^0.4.0;

contract bank{
  modifier transferLimit(uint _withdraw){
    if(_withdraw > 100) throw;
    _;
  }
}

contract ModifierOverride is bank{
  //覆盖了父类的修改器
  modifier transferLimit(uint _withdraw){
    if(_withdraw > 10) throw;
    _;
  }

  function f(uint withdraw) transferLimit(withdraw) returns(uint){
    return withdraw;
  }
}


参考文章:http://me.tryblockchain.org/blockchain-solidity-functionModifier.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值