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

本文主要是介绍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;}
    }
    
  • 详细说明: 修饰符是一种代码复用的方式。通过在函数定义中添加修饰符,开发者可以在函数执行之前或之后插入额外的逻辑,如权限检查。

这篇关于solidity一些内置的常用函数和关键字(含智能合约简单代码示例)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110600

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time