solidity一些内置的常用函数和关键字(含智能合约简单代码示例)

solidity一些内置的常用函数和关键字:

1. msg.sender

  • 描述: msg.sender 是全局变量,代表当前调用者的地址,即谁发起了当前的合约调用。

  • **功能:**用于识别调用者的身份,通常用于权限控制。

  • 示例:

    contract MyContract {
        address public owner;
    
        constructor() {
            owner = msg.sender; // 将合约部署者设置为合约拥有者
        }
    
        function isOwner() public view returns (bool) {
            return msg.sender == owner;
        }
    }
    
  • 详细说明: msg.sender 在合约调用链中非常重要,用于识别调用者的身份,通常用于权限控制。

2. msg.value

  • 描述: msg.value 是全局变量,表示在合约调用中发送的以太币数量(单位为wei)。

  • 示例:

    contract MyContract {
        function deposit() public payable { // 支付函数
            require(msg.value > 0, "Must send some ether");
        }
    }
    
  • 详细说明: 当调用函数时,可以通过 msg.value 获取发送的以太币数量,常用于支付功能或资金转账。

3. block.timestamp

  • 描述: block.timestamp 是当前区块的时间戳,以UNIX时间表示(即自1970年1月1日以来的秒数)。

  • 示例:

    contract MyContract {
        uint public creationTime;  // 区块创建时间
    
        constructor() {
            creationTime = block.timestamp;  // 用时间戳赋值
        }
    
        function timeSinceCreation() public view returns (uint) {  // 计算当前区块的时间戳与区块创建时间的间隔
            return block.timestamp - creationTime;
        }
    }
    
  • 详细说明: block.timestamp 常用于合约中的时间相关操作,例如检查某个操作是否超时。

4. address.balance

  • 描述: address.balance 是一个地址类型的变量,用于获取指定地址的以太币余额(单位为wei)。

  • 示例:

    contract MyContract {
    	// 参数为地址类型变量‘_addr’,函数返回该地址账户的以太坊余额
        function checkBalance(address _addr) public view returns (uint) {
            return _addr.balance;  
        }
    }
    
  • 详细说明: 通过 address.balance 可以轻松检查任何地址的以太币余额,常用于付款前的余额检查。

5. require()

  • 描述: require 用于在合约中执行条件检查,如果条件不满足,将抛出异常并回滚交易

  • 示例:

    contract MyContract {
        uint public data;
    
        function setData(uint _data) public {
            require(_data > 0, "Data must be greater than zero");
            // "Data must be greater than zero"为异常信息
            data = _data;
        }
    }
    
  • 详细说明: require 函数在保证合约安全性和正确性方面起着重要作用,通常用于检查输入条件或权限。

6. assert()

  • 描述: assertrequire 类似,用于条件检查,但通常用于内部错误检测。如果 assert 失败,会消耗掉所有剩余的gas

  • 示例:

    contract MyContract {
        uint public data;
    
        function setData(uint _data) public {
            data = _data;
            assert(data == _data); // 检查数据是否正确设置
        }
    }
    
  • 详细说明: assert 通常用于检测不可预见的错误或不变量,失败时会导致合约中的bug暴露

7. revert()

  • 描述: revert 用于手动触发异常并回滚交易,常用于当满足特定条件时取消操作

  • 示例:

    contract MyContract {
        uint public data;
    
        function setData(uint _data) public {
            if (_data == 0) {
                revert("Data cannot be zero"); // 回滚交易,并附加自定义错误消息
            }
            data = _data;
        }
    }
    
  • 详细说明: revert 提供了一种灵活的方法来处理异常,允许附加自定义错误消息。

8. withdraw()

  • 描述:withdraw() 函数通常用于从合约中提取以太币。
  • 使用场景: 常用于合约的资金管理,比如当用户存款到合约后,可以通过 withdraw() 函数提取这些资金。
关键点
  1. 权限控制: 通常,withdraw() 函数会限制只有合约的拥有者或某些授权用户才能调用,以避免未经授权的提取

  2. 错误处理: 确保函数在提取过程中进行适当的错误处理,防止出现问题,如余额不足或调用者无权提取资金。

    示例代码

contract MyContract {
    address public owner;

    // 合约的构造函数
    constructor() {
        owner = msg.sender; // 设置合约部署者为拥有者
    }

    // 修饰符,确保只有拥有者可以调用
    modifier onlyOwner() {
        require(msg.sender == owner, "Not the contract owner");
        _;
    }

    // 函数允许合约接收以太币
    receive() external payable {}

    // 提取合约中的所有以太币
    function withdraw() public onlyOwner { // onlyOwner ==> 只有合约拥有者才能调用 withdraw() 函数
    
        uint balance = address(this).balance; // 获取合约余额
        require(balance > 0, "No funds available");
        
        // 将合约余额发送到拥有者地址
        payable(owner).transfer(balance);
    }
}
详细说明
  1. receive() 函数

    • 这是一个接收以太币的特殊函数,允许合约接收传入的以太币。
  2. withdraw() 函数

    • 权限控制: 使用 onlyOwner 修饰符,确保只有合约拥有者才能调用 withdraw() 函数。
    • 余额检查: 使用 require(balance > 0, "No funds available") 确保合约中有足够的余额进行提取。
    • 资金转移: 使用 payable(owner).transfer(balance) 将合约余额发送到拥有者地址。
注意事项
  • 重入攻击: transfer 方法会限制 gas 的使用,通常足以防止重入攻击,但对于更复杂的场景,可以考虑使用 call 函数并实施防护措施。
  • 余额不足: 确保在转账之前检查余额是否充足。
  • 权限管理: 明确设置权限,防止非授权用户调用提取函数。

9. address.transfer()

  • 描述: transfer 是地址类型的函数,用于将一定数量的以太币转移到指定地址,若转账失败则会抛出异常。

  • 示例:

    contract MyContract {
        address payable public owner;
    	
    	// 构造函数
        constructor() {
            owner = payable(msg.sender); // 设置合约的拥有者
        }
    
    	// 提取函数,提取账户的以太币
        function withdraw(uint _amount) public {
            require(msg.sender == owner, "Not the contract owner");
            owner.transfer(_amount);
        }
    
        // 接收以太币的函数
        receive() external payable {}
    }
    
    **payable **关键字

    用于地址

    当一个地址被声明为 payable 时,它表示这个地址可以接收以太币。通常,在需要向某个地址发送以太币时,必须将该地址声明为 payable,否则编译器会报错。

    用于函数

    当一个函数被声明为 payable 时,它表示这个函数在被调用时,可以接收以太币。这通常用于合约中的支付功能,例如存款函数或众筹合约中的投资函数。

  • 详细说明: transfer 是一个安全的以太币转账方法,能够防止由于接收者合约中的代码问题导致的转账失败或攻击。

10. address.call()

  • 描述: call 是一种低级别的函数调用方式,允许调用者发送以太币并调用目标地址的函数。它不会自动抛出异常,因此需要手动检查调用结果。

  • 基本形式:

    (bool success, bytes memory data) = _to.call{value: msg.value}(callData);
    
    • {value: msg.value}: 传递以太币的方式,msg.value 是调用该函数时发送的以太币数量
    • callData: 是调用目标合约时传递的函数签名和参数数据。通常是用来指定调用哪个函数以及传递给该函数的参数。在不需要调用特定函数时,可以传递一个空字符串 "",这意味着没有特定的函数调用。
    • bytes memory data:是合约调用之后的返回值。
  • 示例:

    contract MyContract {
    
        function sendEther(address payable _to) public payable {  // 转账给地址"_to"
            (bool success, ) = _to.call{value: msg.value}("");  // 不关心调用返回值,不调用合约函数
            require(success, "Transfer failed.");	// 手动异常检查
        }
    }
    
  • 详细说明: call 函数比 transfer 更灵活,可以传递以太币并同时调用目标合约的函数,但由于不会自动抛出异常,因此需要额外的错误处理逻辑。

11. constructor()

  • 描述: 构造函数(constructor)是智能合约的初始化函数,在合约部署时执行一次。用于设置初始状态或赋值给状态变量。

  • 示例:

    contract MyContract {
        address public owner;
    
        // 构造函数
        constructor() {
            owner = msg.sender; // 设置合约的拥有者
        }
    }
    
  • 详细说明: 在部署合约时,这个函数会自动执行,用于初始化一些基本参数,比如合约的所有者(通常是部署者的地址)。

12. fallback()

  • 描述: fallback()函数是一个可选的匿名函数,当合约接收到以太币但没有匹配到任何其他函数时,或者直接调用一个不存在的函数时,它会被触发。

  • 示例:

    contract MyContract {
        // 接收以太币的回退函数
        fallback() external payable {
            // 执行一些操作
        }
    }
    
  • 详细说明: 它通常用于记录发送失败的交易或触发某些默认行为。该函数必须标记为 payable,以允许它接收以太币。

13. receive()

  • 描述: 这是一个特殊函数,当合约接收到纯以太币转账且没有附带数据时调用。

  • 示例:

    contract MyContract {
        // 接收纯以太币的函数
        receive() external payable {
            // 处理收到的以太币
        }
    }
    
  • 详细说明: receive 函数与 fallback 类似,但专门用于处理没有数据的以太币转账。如果未定义此函数,且合约没有定义 fallback 函数,则会拒绝所有纯以太币转账。

14. modifier()

  • 描述: 修饰符(Modifier)用于更改函数的行为,通常用于访问控制或输入校验。它可以在函数执行前后添加逻辑。

  • 示例:

    contract MyContract {
        address public owner;
    
        constructor() {
            owner = msg.sender;
        }
    
        // 修饰符,限制只有合约拥有者可以调用
        modifier onlyOwner() {
            require(msg.sender == owner, "Not the contract owner");
            _;
        }
    
        // 使用修饰符的函数
        function changeOwner(address newOwner) public onlyOwner {
            owner = newOwner;
        }
    }
    
  • 详细说明: 修饰符是一种代码复用的方式。通过在函数定义中添加修饰符,开发者可以在函数执行之前或之后插入额外的逻辑,如权限检查。

你可能感兴趣的:(智能合约,区块链)