目前来看,智能合约接受以太共有五种可能性;

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() 的区别

  1. receive()优先接受纯以太的交易
  2. 实现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的技术小栈(个人博客)

区块链每日必学:智能合约如何接收以太相关推荐

  1. 区块链研习 | 区块链里所说的“智能合约”是什么? 本文作者:敖萌 编辑:温晓桦 2017-10-11 20:31 导语:谈到区块链,必然离不开“智能合约”这个词。我们在本系列的第一篇文章中提到“智能

    区块链研习 | 区块链里所说的"智能合约"是什么? 本文作者:敖萌 编辑:温晓桦 2017-10-11 20:31 导语:谈到区块链,必然离不开"智能合约"这个 ...

  2. 尚硅谷以太坊区块链学习之NFT智能合约(6)

    尚硅谷以太坊区块链学习之NFT智能合约(6) 前言 一.NFT智能合约 1.智能合约代码 2.智能合约推送 3.具体调用 二.具体使用 三.NFT商家智能合约 前言 提示:服务外包区块链学习 5被ba ...

  3. 区块链(七)智能合约(Smart Contract)

    1. 智能合约(Smart Contract) 智能合约(Smart Contract),是一种旨在以信息化方式传播.验证或执行合同的计算机协议.智能合约允许在没有第三方的情况下进行可信交易,这些交易 ...

  4. 区块链2.0:智能合约

    想知道更多关于区块链技术知识,请百度[链客区块链技术问答社区] 链客,有问必答!! 区块链2.0是对整个市场的去中心化,利用区块链技术来转换许多不同的资产而不仅仅是比特币,通过转让来创建不同资产单元的 ...

  5. 区块链学习笔记21——智能合约

    二十一.智能合约 智能合约是以太坊的精髓,也是以太坊和比特币一个最大的区别. 什么是智能合约? 智能合约的本质是运行在区块链上的一段代码,代码的逻辑定义了智能合约的内容 智能合约的账户保存了合约当前的 ...

  6. 一步一步学区块链(5)智能合约

    想知道更多关于区块链技术知识,请百度[链客区块链技术问答社区] 链客,有问必答! 以太坊区块链技术2.0版本对于行业应用的开发最主要特性就是实现了智能合约,本质上讲智能合约是由事件驱动的. 具有状态的 ...

  7. 区块链100讲:智能合约审计指南

    智能合约代码的审计,目前还不是技术社区内经常会讨论的主题.今年3月6日,发表在博客网站[Schneier on Security]上的一篇博客(原文链接:[https://www.schneier.c ...

  8. 区块链学习5:智能合约Smart contract原理及发展历程科普知识

    ☞ ░ 前往老猿Python博文目录 ░ 一.智能合约的定义 通俗来说,智能合约就是一种在计算机系统上,当一定条件满足的情况下可被自动执行的合约,智能合约体现为一段代码及其运行环境.例如银行信用卡的自 ...

  9. 石墨烯区块链(5)智能合约

    1. 定义 没有通常意义上的智能合约.所有业务逻辑都嵌入在网络中.换句话说,为了创建智能合约,需要修改石墨烯源代码.石墨烯区块链实现使我们能够轻松地向网络添加自定义操作. 2. Graphene 中的 ...

最新文章

  1. linux pytorch环境配置,linux下使用conda安装pytorch,并配置pytorch
  2. VTK:Snippets之ViewportBorders
  3. ubuntu16.04搭建ftp服务器
  4. ospf-cost-FR选路实验
  5. 重新安装SCCM 2012 client,解决Windows10 1909在线更新问题
  6. java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?
  7. .Net 1.1下WEB引用Win控件的两个Bug
  8. 目标检测——域适应的学习笔记
  9. 知乎披露会员业务未来布局,融合社区内容深耕垂直领域
  10. seo关键词互点软件报价_舟山seo关键词优化软件
  11. 字节跳动杯2018中国大学生程序设计竞赛-女生专场题解
  12. taobao淘宝 开源的项目tair 简介
  13. 何宾 单片机原理及应用_STC单片机原理及应用何宾答案
  14. 已知棱长求三棱锥的表面积和体积
  15. cocosCreator关闭多点触摸的问题
  16. 使用python转换微信dat格式文件为png文件
  17. 图形图像基础 之 gif介绍
  18. oom killer理解和日志分析
  19. 《LeGO-LOAM: Lightweight and Ground-OptimizedLidar Odometry and Mapping on Variable Terrain》论文精读
  20. android 屏幕旋转

热门文章

  1. 【邢不行|量化小讲堂系列09-Python量化入门】通过逐笔数据计算主力资金流数据
  2. c语言生成随机数再升序
  3. 2位专家耗时2年打造,西瓜书机器学习公式详解,都在这里了!(文末留言赠书)...
  4. Word输入空心字母|ℂ ℕ ℝ ℚ ℤ黑板粗体LaTex
  5. 佳能c3020维修模式 白电平调整_佳能相机拍摄人脸偏红,怎么设置?
  6. Linux系统的目录树
  7. css水平垂直居中方法(全网最全)
  8. 2007-2008 火箭赛事时间
  9. 川崎机器人signal_揭阳市Kawasaki焊接机器人保养中心
  10. 虚拟化学习笔记四——硬件辅助CPU虚拟化技术VT-x