Solidity

修飾符在介面中起作用嗎

  • July 10, 2018

介面可以對函式強制修改嗎?

例如,這是否有效:

contract TokenSeller {

 modifer enforceSale(uint256 amount) {
   ERC20 t = token();
   uint256 beforeBalance = t.balanceOf(msg.sender);
   _;
   uint256 afterBalance = t.balanceOf(msg.sender);
   require(afterBalance == beforeBalance + amount);
 }

 function buyToken(uint256 amount) public enforceSale(amount) returns(uint256);

 function token() public returns(ERC20);
}

有沒有其他方法可以實現這種界面?

簡短的回答

不,也許通過抽象合約你可以實現類似的東西

長答案

首先要創建一個介面,interface應該使用關鍵字(我使用了版本 0.4.24 的solidity 和solidity文件。我對您的程式碼進行了一些操作,當您嘗試在帶有修飾符的介面中創建函式時,例如這:

pragma solidity ^0.4.24;

interface A {
   modifier onlyOwner() {
       require(getOwner() == msg.sender);
       _;
   }
   function getOwner() public returns(address);
   function updateState() public onlyOwner();
}

您會收到此警告在此處輸入圖像描述

因此,顯然,您不能在介面中強制使用修飾符。

也許您可以嘗試使用抽象合約和模板方法模式

contract A {

   modifier onlyOwner() {
       require(getOwner() == msg.sender);
       _;
   }
   // The internal keyword let function be visible only to the contract itself and the derivatives
   function getOwner() internal returns(address);  

   function performOperation() internal; // The real operation

   function updateState() public onlyOwner() {
       performOperation();
   }

}

所以當你創建一個具體的分包合約時可以指定“ performOperation”函式:

contract B is A {
   address private owner;
   uint state;
   constructor() public {
       owner = msg.sender;
       state = 0;
   }
   function getOwner() internal returns(address) {
       return owner;
   }
   function performOperation() internal {
       state = state + 1;
   }
}

顯然,對於抽像類,您也可以通過這種方式避免使用 getOwner 函式:

   contract A {
       address internal owner;

       constructor() internal {
          owner = msg.sender;
       }
       modifier onlyOwner() {
           require(owner == msg.sender);
           _;
       }
       function performOperation() internal;
       function updateState() public onlyOwner() {
           performOperation();
       }
   }

所以你可以實例化一個已經擁有所有者變數的分包契約:

contract B is A {
   uint state;
   //Call A's constructor before B's one
   constructor() A() public { state = 0; }
   function performOperation() internal { state = state + 1; }
}

PS 你在 remix https://remix.ethereum.org上試過你的程式碼嗎?

引用自:https://ethereum.stackexchange.com/questions/52960