天天看點

solidity通用模式通路限制通用模式

通用模式

通路限制

通路限制是智能合約的一種通用模式,但你不能限制任何人擷取你的智能合約和交易的狀态。當然,你可以通過加密來增加讀取難度,但是如果你的智能合約需要讀取該資料(指加密的資料),其他人也可以讀取。

你可以通過将合約狀态設定為私有來限制其他合約來讀取你的合約狀态。

此外,你可以限制其他人修改你的合約狀态或者調用你的合約函數,這也是本章将要讨論的。

函數修飾符的使用可以讓這些限制(通路限制)具有較好的可讀性。

contract AccessRestriction {
    // These will be assigned at the construction
    // phase, where `msg.sender` is the account
    // creating this contract.
    //以下變量将在構造函數中指派 
    //msg.sender是你的賬戶
    //建立本合約
    address public owner = msg.sender;
    uint public creationTime = now;

    // Modifiers can be used to change
    // the body of a function.
    // If this modifier is used, it will
    // prepend a check that only passes
    // if the function is called from
    // a certain address.           

//修飾符可以用來修飾函數體,如果使用該修飾符,當該函數被其他位址調用時将會先檢查是否允許調用(譯注:就是說外部要調用本合約有修飾符的函數時會檢查是否允許調用,比如該函數是私有的則外部不能調用。)

modifier onlyBy(address _account)
    {
        if (msg.sender != _account)
            throw;
        // Do not forget the "_"! It will
        // be replaced by the actual function
        // body when the modifier is invoked.
        //account變量不要忘了“_” 
        _
    }

    /// Make `_newOwner` the new owner of this
    /// contract.
   //修改目前合約的宿主
    function changeOwner(address _newOwner)
        onlyBy(owner)
    {
        owner = _newOwner;
    }

    modifier onlyAfter(uint _time) {
        if (now < _time) throw;
        _
    }

    /// Erase ownership information.
    /// May only be called 6 weeks after
    /// the contract has been created.
   //清除宿主資訊。隻能在合約建立6周後調用
    function disown()
        onlyBy(owner)
        onlyAfter(creationTime + 6 weeks)
    {
        delete owner;
    }

    // This modifier requires a certain
    // fee being associated with a function call.
    // If the caller sent too much, he or she is
    // refunded, but only after the function body.
    // This is dangerous, because if the function
    // uses `return` explicitly, this will not be
    // done!
    //該修飾符和函數調用關聯時需要消耗一部分費用。調用者發送的多餘費用會在函數執行完成後返還,但這個是相當危險的,因為如果函數
    modifier costs(uint _amount) {
        if (msg.value < _amount)
            throw;
        _
        if (msg.value > _amount)
            msg.sender.send(_amount - msg.value);
    }

    function forceOwnerChange(address _newOwner)
        costs(200 ether)
    {
        owner = _newOwner;
        // just some example condition
        if (uint(owner) & 0 == 1)
            // in this case, overpaid fees will not
            // be refunded
            return;
        // otherwise, refund overpaid fees
    }}           

A more specialised way in which access to function calls can be restricted will be discussed in the next example.

State Machine

Contracts often act as a state machine, which means that they have certain stages in which they behave differently or in which different functions can be called. A function call often ends a stage and transitions the contract into the next stage (especially if the contract models interaction). It is also common that some stages are automatically reached at a certain point in time.

An example for this is a blind auction contract which starts in the stage “accepting blinded bids”, then transitions to “revealing bids” which is ended by “determine auction autcome”.

Function modifiers can be used in this situation to model the states and guard against incorrect usage of the contract.

Example

In the following example, the modifier atStage ensures that the function can only be called at a certain stage.

Automatic timed transitions are handled by the modifier timeTransitions, which should be used for all functions.

Note

Modifier Order Matters. If atStage is combined with timedTransitions, make sure that you mention it after the latter, so that the new stage is taken into account.

Finally, the modifier transitionNext can be used to automatically go to the next stage when the function finishes.

Modifier May be Skipped. Since modifiers are applied by simply replacing code and not by using a function call, the code in the transitionNext modifier can be skipped if the function itself uses return. If you want to do that, make sure to call nextStage manually from those functions.

contract StateMachine {
    enum Stages {
        AcceptingBlindedBids,
        RevealBids,
        AnotherStage,
        AreWeDoneYet,
        Finished
    }
    // This is the current stage.
    Stages public stage = Stages.AcceptingBlindedBids;

    uint public creationTime = now;

    modifier atStage(Stages _stage) {
        if (stage != _stage) throw;
        _
    }
    function nextStage() internal {
        stage = Stages(uint(stage) + 1);
    }
    // Perform timed transitions. Be sure to mention
    // this modifier first, otherwise the guards
    // will not take the new stage into account.
    modifier timedTransitions() {
        if (stage == Stages.AcceptingBlindedBids &&
                    now >= creationTime + 10 days)
            nextStage();
        if (stage == Stages.RevealBids &&
                now >= creationTime + 12 days)
            nextStage();
        // The other stages transition by transaction
    }

    // Order of the modifiers matters here!
    function bid()
        timedTransitions
        atStage(Stages.AcceptingBlindedBids)
    {
        // We will not implement that here
    }
    function reveal()
        timedTransitions
        atStage(Stages.RevealBids)
    {
    }

    // This modifier goes to the next stage
    // after the function is done.
    // If you use `return` in the function,
    // `nextStage` will not be called
    // automatically.
    modifier transitionNext()
    {
        _
        nextStage();
    }
    function g()
        timedTransitions
        atStage(Stages.AnotherStage)
        transitionNext
    {
        // If you want to use `return` here,
        // you have to call `nextStage()` manually.
    }
    function h()
        timedTransitions
        atStage(Stages.AreWeDoneYet)
        transitionNext
    {
    }
    function i()
        timedTransitions
        atStage(Stages.Finished)
    {
    }}           

Next Previous

轉自:

https://github.com/twq0076262/solidity-zh/edit/master/common-patterns.md
如果你希望高效的學習以太坊DApp開發,可以通路彙智網提供的最熱門線上互動教程:

其他更多内容也可以通路

這個以太坊部落格