美文网首页智能合约开发
智能合约(solidity)进阶

智能合约(solidity)进阶

作者: 张亚伦 | 来源:发表于2021-08-06 15:03 被阅读0次

    1. Using For用法

    • using A for B;
      将类库函数(A)附加到指定的类型(B)。
    • using A for *;
      将类库A中的函数被附加到任何类型。

    注:类库中的这些函数将接收它们被调用的对象作为第一个参数(就像Python中的self变量)。
    示例:

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.6.0 <0.9.0;
    
    
    // This is the same code as before, just without comments
    struct Data { mapping(uint => bool) flags; }
    
    library Set {
        function insert(Data storage self, uint value)
            public
            returns (bool)
        {
            if (self.flags[value])
                return false; // already there
            self.flags[value] = true;
            return true;
        }
    
        function remove(Data storage self, uint value)
            public
            returns (bool)
        {
            if (!self.flags[value])
                return false; // not there
            self.flags[value] = false;
            return true;
        }
    
        function contains(Data storage self, uint value)
            public
            view
            returns (bool)
        {
            return self.flags[value];
        }
    }
    
    
    contract C {
        using Set for Data; // this is the crucial change
        Data knownValues;
    
        function register(uint value) public {
            // Here, all variables of type Data have
            // corresponding member functions.
            // The following function call is identical to
            // `Set.insert(knownValues, value)`
            require(knownValues.insert(value));
        }
    }
    

    2. Checks-Effects-Interactions Pattern

    错误用法:

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.6.2 <0.9.0;
    
    // THIS CONTRACT CONTAINS A BUG - DO NOT USE
    contract Fund {
        /// @dev Mapping of ether shares of the contract.
        mapping(address => uint) shares;
        /// Withdraw your share.
        function withdraw() public {
            (bool success,) = msg.sender.call{value: shares[msg.sender]}("");
            if (success)
                shares[msg.sender] = 0;
        }
    }
    

    正确做法:

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.6.0 <0.9.0;
    
    contract Fund {
        /// @dev Mapping of ether shares of the contract.
        mapping(address => uint) shares;
        /// Withdraw your share.
        function withdraw() public {
            uint share = shares[msg.sender];
            shares[msg.sender] = 0;
            payable(msg.sender).transfer(share);
        }
    }
    

    3. style-guide-

    Order of Layout:
    Layout contract elements in the following order:

    • Pragma statements
    • Import statements
    • Interfaces
    • Libraries
    • Contracts

    Inside each contract, library or interface, use the following order:

    • Type declarations
    • State variables
    • Events
    • Functions

    Order of Functions :
    Functions should be grouped according to their visibility and ordered:

    • constructor
    • receive function (if exists)
    • fallback function (if exists)
    • external
    • public
    • internal
    • private

    Yes:

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.7.0 <0.9.0;
    contract A {
        constructor() {
            // ...
        }
    
        receive() external payable {
            // ...
        }
    
        fallback() external {
            // ...
        }
    
        // External functions
        // ...
    
        // External functions that are view
        // ...
    
        // External functions that are pure
        // ...
    
        // Public functions
        // ...
    
        // Internal functions
        // ...
    
        // Private functions
        // ...
    }
    

    No:

    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.7.0 <0.9.0;
    contract A {
    
        // External functions
        // ...
    
        fallback() external {
            // ...
        }
        receive() external payable {
            // ...
        }
    
        // Private functions
        // ...
    
        // Public functions
        // ...
    
        constructor() {
            // ...
        }
    
        // Internal functions
        // ...
    }
    

    Order of Modifiers:

    The modifier order for a function should be:

    • Visibility
    • Mutability
    • Virtual
    • Override
    • Custom modifiers

    Yes:

    function balance(uint from) public view override returns (uint)  {
        return balanceOf[from];
    }
    
    function shutdown() public onlyOwner {
        selfdestruct(owner);
    }
    

    No:

    function balance(uint from) public override view returns (uint)  {
        return balanceOf[from];
    }
    
    function shutdown() onlyOwner public {
        selfdestruct(owner);
    }
    

    相关文章

      网友评论

        本文标题:智能合约(solidity)进阶

        本文链接:https://www.haomeiwen.com/subject/vdnbvltx.html