sodility 문서 --modifier 함수 수정기

modifier 즉 함수의 수정기로 함수의 행동을 바꾸고 함수의 논리를 제어할 수 있다.수정기는 계약 속성으로 계승되고 다시 쓸 수 있다.다음은 코드를 예로 들어 소개합니다(코드는 CryptoKitties 프로젝트KittyAccessControl.sol 계약에서 유래한 것으로 상세한 코드는 볼 수 있습니다.https://github.com/dapperlabs/cryptokitties-bounty)
modifier onlyCLevel() {
        require(
            msg.sender == cooAddress ||
            msg.sender == ceoAddress ||
            msg.sender == cfoAddress
        );
        _;
    }

앞의 코드는 수정기로서 제약을 설명합니다. 현재 주소가ceoAddress 또는 cfoAddress 또는cooAddress일 때만 후속 코드를 실행할 수 있습니다.밑줄실행 함수 다음 코드를 대표하는 자리 차지 문자입니다.때때로 당신은 위의 코드가 다음과 같은 형식으로 쓰여 있는 것을 볼 수 있다.
modifier onlyCLevel() {
        if(
            msg.sender != cooAddress &&
            msg.sender != ceoAddress &&
            msg.sender != cfoAddress
        ) throw;
        _;
    }

사실 두 단락의 코드는 등가이다.if()throw의 작법은 비교적 구식의 작법이고 현재는 리퀘어()를 사용하는 작법이 비교적 많다.
function pause() external onlyCLevel whenNotPaused {
        paused = true;
    }

다음 코드는 계약을 정지하는 데 사용되는 함수pause () 를 설명합니다. 이 함수의 실행이 onlyClevel 조건을 충족시켜야 한다는 것을 보여 줍니다.또한 함수 수정자는 다음과 같은 함수와 유사한 입력 매개변수를 지원합니다.
pragma solidity ^0.4.0;

contract parameter{
    uint balance = 10;

    modifier lowerLimit(uint _balance, uint __withdraw){
        if( _withdraw < 0 || _withdraw > _balance) throw;
        _;
    }

    function f(uint withdraw) lowerLimit(balance, withdraw) returns (uint){
        return balance;
    }
}

위의 코드에서 수정기 lower Limit은 두 개의 인자를 전송하여 수정기의 논리를 실행합니다.함수의 실행 여부는 두 매개변수에 따라 다릅니다.withdraw 및balance. 함수의 수정자 매개변수는 다음과 같은 표현식을 지원합니다.
pragma solidity ^0.4.0;

contract parameterExpression{
    modifier m(uint a){
        if(a > 0)
            _;
    }

    function add(uint a, uint b) private returns(uint){
        return a + b;
    }

    function f() m(add(1, 1)) returns(uint){
        return 1;
    }
}

위의 코드에 대해 수정기 m의 매개 변수가 표현식을 전송했습니다:dd(a+b),dd() 표현식이 계약에 정의되었습니다.Return은 함수에 반환 값을 표시하는데 함수에 반환 값 표지return이 있지만 수정기 제한으로 판단이 실패하여 함수 내의 코드를 실행할 수 없으면 반환 값 형식의 기본값을 되돌려줍니다. 예를 들어:
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는 영원히 성공하지 못할 것으로 판단되기 때문에 uint Return과string Return 두 함수의 함수체는 영원히 실행할 수 없습니다. 그러면 되돌아오는 값은 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];
    }
}

위의 함수 f()에 대해 먼저 수정기를 실행하고 권한을 판단하며 권한을 통과하면 수정기를 실행하여 문장 뒤의 코드를 판단한다. 맵[true]=1;밑줄로 실행하기;이 줄에서 함수 체내로 뛰어들어 맵 [true] = 2를 실행한다.그리고 retrun map [true]의 값입니다.함수체를 실행한 코드는 함수 수정기 밑줄로 돌아갑니다.이 줄 뒤에 있는 코드, 여기에 코드가 있습니다. 이어서 맵 [true] = 3을 실행합니다.그래서 최종 맵 [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;
    }
}

위의 코드에서 두 개의 수정기 only Owner와 inState는 함수 f()에 동시에 작용하고 두 개의 수정기의 권한이 동시에 충족될 때만 함수 내의 코드,retrun 1을 실행할 수 있다.우리는 계약이 상속될 수 있다는 것을 알고 있으며, 하위 계약에서 우리는 아버지 계약의 수정기를 다시 쓸 수 있다. 예를 들어:
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;
    }
}

위의 코드에서 하위 계약인 Modifier Override는 부모 계약 뱅크를 계승했다. 그러면 똑같이 부모 계약 중의transfer Limit 수정기가 있다. 그 다음에 하위 계약에서transfer Limit 수정기를 다시 정의하면 이 수정기를 다시 쓰고 원래 수정기를 덮어쓴다. 하위 계약에서transfer Limit의 제한 조건은 하위 계약에서 다시 쓰는 조건에 의해 결정된다.

좋은 웹페이지 즐겨찾기