区块链每日必学:智能合约如何接收以太
目前来看,智能合约接受以太共有五种可能性;
1. receive()
一个合约最多有一个 receive
函数, 声明函数为: receive() external payable {}
无需 function
关键字,也没有参数和返回值并且必须是external
可见性和payable
修饰。 它可以是 virtual
的,可以被重载也可以有修改器modifier 。
在对合约没有任何附加数据调用(通常是对合约转账)是会执行 receive
函数。
例如通过 .send()
or .transfer()
如果 receive
函数不存在,但是有payable的 fallback 回退函数 那么在进行纯以太转账时,fallback 函数会被调用。
如果两个函数都没有,这个合约就没法通过常规的转账交易接收以太,会抛出异常。
并且,receive
函数只有 2300 gas 可以使用, 除了基础的日志输出之外,进行其他操作的余地很小。下面的操作消耗会操作 2300 gas :
- 写入存储
- 创建合约
- 调用消耗大量 gas 的外部函数
- 发送以太币
不过,与任何其他函数一样,只要有足够的 gas 传递给它,回退函数就可以执行复杂的操作。
pragma solidity ^0.6.0;// 这个合约会保留所有发送给它的以太币,没有办法取回。
contract Sink {event Received(address, uint);receive() external payable {emit Received(msg.sender, msg.value);}
}
2. 实现payable的fallback()
合约可以最多有一个回退函数。函数声明为: fallback() external [payable]
或 fallback() (bytes calldata input) external [payable] returns (bytes memory output)
没有function
关键字。必须是external
可见性,它可以是 virtual
的,可以被重载也可以有 修改器modifier 。
fallback 函数始终会接收数据,但为了同时接收以太时,必须标记为payable
。
如果使用了带参数的版本, input
将包含发送到合约的完整数据(等于 msg.data
),并且通过 output
返回数据。 返回数据不是 ABI 编码过的数据,相反,它返回不经过修改的数据。
如果回退函数在接收以太时调用,只有 2300 gas 可以使用。
不过,与任何其他函数一样,只要有足够的 gas 传递给它,回退函数就可以执行复杂的操作。
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.2 <0.9.0;contract Test {// 发送到这个合约的所有消息都会调用此函数(因为该合约没有其它函数)。// 向这个合约发送以太币会导致异常,因为 fallback 函数没有 `payable` 修饰符fallback() external { x = 1; }uint x;
}// 这个合约会保留所有发送给它的以太币,没有办法返还。
contract TestPayable {uint x;uint y;// 除了纯转账外,所有的调用都会调用这个函数.// (因为除了 receive 函数外,没有其他的函数).// 任何对合约非空calldata 调用会执行回退函数(即使是调用函数附加以太).fallback() external payable { x = 1; y = msg.value; }// 纯转账调用这个函数,例如对每个空empty calldata的调用receive() external payable { x = 2; y = msg.value; }
}contract Caller {function callTest(Test test) public returns (bool) {(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));require(success);// test.x 结果变成 == 1。// address(test) 不允许直接调用 ``send`` , 因为 ``test`` 没有 payable 回退函数// 转化为 ``address payable`` 类型 , 然后才可以调用 ``send``address payable testPayable = payable(address(test));// 以下将不会编译,但如果有人向该合约发送以太币,交易将失败并拒绝以太币。// test.send(2 ether);}function callTestPayable(TestPayable test) public returns (bool) {(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));require(success);// 结果 test.x 为 1 test.y 为 0.(success,) = address(test).call{value: 1}(abi.encodeWithSignature("nonExistingFunction()"));require(success);// 结果test.x 为1 而 test.y 为 1.// 发送以太币, TestPayable 的 receive 函数被调用.// 因为函数有存储写入, 会比简单的使用 ``send`` or ``transfer``消耗更多的 gas。// 因此使用底层的call调用(success,) = address(test).call{value: 2 ether}("");require(success);// 结果 test.x 为 2 而 test.y 为 2 ether.return true;}}
注:实现payable的fallback() 和receive() 的区别
- receive()优先接受纯以太的交易
- 实现payable的fallback()优先接受附带msg.data的交易
3. 实现payable的函数
这种方式无需多言,加个payable关键词就可以了!
4. selfdestruct()
自毁函数是具有攻击性的一种让其它合约被迫接受以太的方式
contract Attack{address private owner;constructor(){owner = msg.sender;}event Received(address, uint);receive() external payable {emit Received(msg.sender, msg.value);}//自毁转账function selfdestructAttack(address _to) external public{require(msg.sender == this.owner,"you are not the owner");selfdestruct(_to);}}
如上例所示,当调用合约的selfdestructAttack
函数时,此合约将会自毁,并且将合约内的余额强制发送到 _ to这个合约地址上,无论_ to合约是否实现接受以太的函数,都不得不接受这笔转账。
5. miner区块奖励
我们常说的挖矿奖励,当挖出了一个新区块时,以太奖励将会达到挖出人指定的地址上,无论这个地址是什么,它都会多出这笔奖励余额;
如今以太坊转型为PoS权益证明机制,miner区块奖励将会逐渐销声匿迹。
更多区块链技术干货请关注
岚链技术论坛
77Brother的技术小栈(个人博客)
区块链每日必学:智能合约如何接收以太相关推荐
- 区块链研习 | 区块链里所说的“智能合约”是什么? 本文作者:敖萌 编辑:温晓桦 2017-10-11 20:31 导语:谈到区块链,必然离不开“智能合约”这个词。我们在本系列的第一篇文章中提到“智能
区块链研习 | 区块链里所说的"智能合约"是什么? 本文作者:敖萌 编辑:温晓桦 2017-10-11 20:31 导语:谈到区块链,必然离不开"智能合约"这个 ...
- 尚硅谷以太坊区块链学习之NFT智能合约(6)
尚硅谷以太坊区块链学习之NFT智能合约(6) 前言 一.NFT智能合约 1.智能合约代码 2.智能合约推送 3.具体调用 二.具体使用 三.NFT商家智能合约 前言 提示:服务外包区块链学习 5被ba ...
- 区块链(七)智能合约(Smart Contract)
1. 智能合约(Smart Contract) 智能合约(Smart Contract),是一种旨在以信息化方式传播.验证或执行合同的计算机协议.智能合约允许在没有第三方的情况下进行可信交易,这些交易 ...
- 区块链2.0:智能合约
想知道更多关于区块链技术知识,请百度[链客区块链技术问答社区] 链客,有问必答!! 区块链2.0是对整个市场的去中心化,利用区块链技术来转换许多不同的资产而不仅仅是比特币,通过转让来创建不同资产单元的 ...
- 区块链学习笔记21——智能合约
二十一.智能合约 智能合约是以太坊的精髓,也是以太坊和比特币一个最大的区别. 什么是智能合约? 智能合约的本质是运行在区块链上的一段代码,代码的逻辑定义了智能合约的内容 智能合约的账户保存了合约当前的 ...
- 一步一步学区块链(5)智能合约
想知道更多关于区块链技术知识,请百度[链客区块链技术问答社区] 链客,有问必答! 以太坊区块链技术2.0版本对于行业应用的开发最主要特性就是实现了智能合约,本质上讲智能合约是由事件驱动的. 具有状态的 ...
- 区块链100讲:智能合约审计指南
智能合约代码的审计,目前还不是技术社区内经常会讨论的主题.今年3月6日,发表在博客网站[Schneier on Security]上的一篇博客(原文链接:[https://www.schneier.c ...
- 区块链学习5:智能合约Smart contract原理及发展历程科普知识
☞ ░ 前往老猿Python博文目录 ░ 一.智能合约的定义 通俗来说,智能合约就是一种在计算机系统上,当一定条件满足的情况下可被自动执行的合约,智能合约体现为一段代码及其运行环境.例如银行信用卡的自 ...
- 石墨烯区块链(5)智能合约
1. 定义 没有通常意义上的智能合约.所有业务逻辑都嵌入在网络中.换句话说,为了创建智能合约,需要修改石墨烯源代码.石墨烯区块链实现使我们能够轻松地向网络添加自定义操作. 2. Graphene 中的 ...
最新文章
- linux pytorch环境配置,linux下使用conda安装pytorch,并配置pytorch
- VTK:Snippets之ViewportBorders
- ubuntu16.04搭建ftp服务器
- ospf-cost-FR选路实验
- 重新安装SCCM 2012 client,解决Windows10 1909在线更新问题
- java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?
- .Net 1.1下WEB引用Win控件的两个Bug
- 目标检测——域适应的学习笔记
- 知乎披露会员业务未来布局,融合社区内容深耕垂直领域
- seo关键词互点软件报价_舟山seo关键词优化软件
- 字节跳动杯2018中国大学生程序设计竞赛-女生专场题解
- taobao淘宝 开源的项目tair 简介
- 何宾 单片机原理及应用_STC单片机原理及应用何宾答案
- 已知棱长求三棱锥的表面积和体积
- cocosCreator关闭多点触摸的问题
- 使用python转换微信dat格式文件为png文件
- 图形图像基础 之 gif介绍
- oom killer理解和日志分析
- 《LeGO-LOAM: Lightweight and Ground-OptimizedLidar Odometry and Mapping on Variable Terrain》论文精读
- android 屏幕旋转
热门文章
- 【邢不行|量化小讲堂系列09-Python量化入门】通过逐笔数据计算主力资金流数据
- c语言生成随机数再升序
- 2位专家耗时2年打造,西瓜书机器学习公式详解,都在这里了!(文末留言赠书)...
- Word输入空心字母|ℂ ℕ ℝ ℚ ℤ黑板粗体LaTex
- 佳能c3020维修模式 白电平调整_佳能相机拍摄人脸偏红,怎么设置?
- Linux系统的目录树
- css水平垂直居中方法(全网最全)
- 2007-2008 火箭赛事时间
- 川崎机器人signal_揭阳市Kawasaki焊接机器人保养中心
- 虚拟化学习笔记四——硬件辅助CPU虚拟化技术VT-x