【Solidity】开发心得 receive payable 里面尽量避免写代码,以免其他合约调用transfer 不成功

加密社

最近调试一段solidity代码,本来想测试在收款的时候,记录一个receive 和发出一个log,哪个消耗gas更大

我创建了两个智能合约:一个是TestTransfer,另一个是TransferCount。在TestTransfer合约中,我定义了一个叫做sendOut的函数,这个函数的作用是从TestTransferTransferCount合约转账。

我在测试过程中遇到了以下情况:

  1. 当我试图从TestTransfer合约向TransferCount合约转账时,总是失败。
  2. 但是,当我直接向TransferCount合约转账时,却能够成功。
  3. 之后我把TransferCount合约里的receive()函数中的代码注释掉了,再试了一次第一步的操作,这次竟然成功了。

问题出在哪里呢?

实际上,问题可能在于TransferCount合约中的receive()函数。当我从TestTransfer合约调用transfer()TransferCount转账时,如果TransferCountreceive()函数执行了一些消耗gas的操作,并且这些操作超过了transfer()方法内默认提供的2300 gas限制,那么整个转账过程就会失败。

解决这个问题的办法就是简化receive()函数,让它尽可能地少做事情,或者干脆不执行任何操作。这样一来,即使transfer()方法提供的gas有限,也不会因为gas不够而导致转账失败。

总结来说,为了确保transfer()能够成功,应该避免在receive()函数中写入过多的逻辑或操作。

// 指定Solidity版本大于0.8.0
pragma solidity >0.8.0 ;

// 这个合约用来接收Ether,并记录接收次数
contract TransferCount {
    // 公开变量,记录fallback函数被调用的次数
    uint public fallbackCount = 0;
    // 公开变量,记录receive函数被调用的次数
    uint public receiveCount = 0;

    // 可支付的构造函数
    constructor() payable {
        // 构造函数体为空
    }

    // 允许外部向合约发送Ether
    function deposit() payable external {
        // 函数体为空
    }

    // 接收Ether时自动调用此函数(如果交易数据为空)
    receive() external payable {
        // 增加接收次数
        receiveCount ++;
        // 注意:在此处增加代码可能导致其他合约调用address.transfer时由于gas不足而失败
    }

    // 当合约接收到带有数据负载的Ether时调用此函数
    fallback() external payable {
        // 增加fallback函数被调用的次数
        fallbackCount ++;
    }
}

// 这个合约用来测试向TransferCount合约转账的行为
contract TestTransfer{
    // 记录fallback函数被调用的次数
    uint public fallbackCount = 0;
    // 记录receive函数被调用的次数
    uint public receiveCount = 0;
    // 存储可支付地址,用于接收Ether
    address payable public tc;

    // 接收Ether时自动调用此函数(如果交易数据为空)
    receive() external payable {
        // 增加接收次数
        receiveCount ++;
    }

    // 当合约接收到带有数据负载的Ether时调用此函数
    fallback() external payable {
        // 增加fallback函数被调用的次数
        fallbackCount ++;
    }

    // 构造函数,初始化可支付地址
    constructor(address payable addr) payable {
        // 设置可支付地址
        tc = addr;
    }

    // 转账函数,从本合约向指定地址转账
    function sendOut(uint amount ) external{
        // 确保有足够的余额进行转账
        require(amount  <= address(this).balance, "insufficient balance");
        // 向指定地址转账
        payable(tc).transfer(amount);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/875780.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

o1系列亮相!OpenAI的AI新高度,解锁复杂推理能力

OpenAI的——o1系列模型&#xff0c;传说中的「草莓」&#xff0c;终于来与大家见面了&#xff01; 这个新模型可不一般&#xff0c;它可以进行复杂的推理&#xff0c;就像在认真思考一样&#xff0c;不再是简单的回答问题。CEO奥特曼称&#xff0c;这是一个全新的开始。它不仅…

Mysql基础练习题 1407.排名靠前的旅行者(力扣)

编写解决方案&#xff0c;报告每个用户的旅行距离。 # 返回的结果表单&#xff0c;以 travelled_distance 降序排列 &#xff0c;如果有两个或者更多的用户旅行了相同的距离, 那么再以 name 升序排列 。 题目链接&#xff1a; https://leetcode.cn/problems/top-travellers/d…

ROADM(可重构光分插复用器)-介绍

1. 引用 https://zhuanlan.zhihu.com/p/163369296 https://zhuanlan.zhihu.com/p/521352954 https://zhuanlan.zhihu.com/p/91103069 https://zhuanlan.zhihu.com/p/50610236 术语&#xff1a; 英文缩写描述灰光模块彩光模块CWDM&#xff1a;Coarse Wave-Length Division …

【机器学习】使用Numpy实现神经网络训练全流程

文章目录 网络搭建前向传播反向传播损失计算完整代码 曾经在面试一家大模型公司时遇到的面试真题&#xff0c;当时费力写了一个小时才写出来&#xff0c;自然面试也挂了。后来复盘&#xff0c;发现反向传播掌握程度还是太差&#xff0c;甚至连梯度链式传播法则都没有弄明白。 网…

Wophp靶场寻找漏洞练习

1.命令执行漏洞 打开网站划到最下&#xff0c;此处的输入框存在任意命令执行漏洞 输入命令whoami 2.SQL注入 搜索框存在SQL注入&#xff0c;类型为整数型 最终结果可以找到管理员账户和密码 3.任意文件上传漏洞 在进入管理员后台后&#xff0c;上传木马文件 访问该文件&…

element表格合并列数据相同合并单元格

<!-- :span-method"objectSpanMethod"合并列 --><el-table stripe :data"morningdataList" style"width: 100%" :span-method"objectSpanMethod" ><el-table-column align"center" label"" :show…

使用 BentoML快速实现Llama-3推理服务

介绍 近年来&#xff0c;开源大模型如雨后春笋般涌现&#xff0c;为自然语言处理领域带来了革命性的变化。从文本生成到代码编写&#xff0c;从机器翻译到问答系统&#xff0c;开源大模型展现出惊人的能力&#xff0c;吸引了越来越多的开发者和企业投身其中。 然而&#xff0…

LabVIEW环境中等待FPGA模块初始化完成

这个程序使用的是LabVIEW环境中的FPGA模块和I/O模块初始化功能&#xff0c;主要实现等待FAM&#xff08;Field-Programmable Gate Array Module&#xff0c;FPGA模块&#xff09;的初始化完成&#xff0c;并处理初始化过程中的错误。让我们逐步分析各部分的功能&#xff1a; 1.…

DataWind将string类型转化为int类型的报错解决

一、现象&#xff1a; toInt64([kernel_wakeup_top_count_str]) 二、日志&#xff1a; 遇到&#xff1a;错误: 直连查询失败&#xff0c;内部异常:<class aeolus.aeolus.libs.exception.aeolus_base_exception.AeolusBaseException>: aeolus/logicQuery/logicQueryMysq…

.NET 一款在线解密Web.config的脚本

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

攻防世界--->re2-cpp-是-awesome

学习笔记。 下载 查壳。 64ida打开。 直接ctrlX进行跟踪 逆向往前看。 没事&#xff0c;对解题并不影响。 编写脚本&#xff1a; ALEXCTF{W3_L0v3_C_W1th_CL45535}

哈希表简单介绍

概念 在顺序结构以及平衡树中&#xff0c;元素关键字与他们存储的位置并没有直接的映射关系&#xff0c;从而会影响查找关键字的效率&#xff0c;顺序结构中查找关键字的时间复杂度为O&#xff08;N&#xff09;&#xff0c;平衡树查找关键字的时间复杂度为O&#xff08;log2^…

.Net6/.Net8(.Net Core) IIS中部署 使用 IFormFile 上传大文件报错解决方案

描述 最近使用.Net6 WebAPI IFormFile对象接收上传文件时大于30MB(兆)的文件就会报错 原因分析 IIS上传文件有大小默认限制大约28.6MB 解决办法 .无论是Net6还是.Net8写法都一样 方法一&#xff1a;IIS可视化操作 1.打开Internet Information Services (llS)管理器&…

Pandas读取某列、某行数据——loc、iloc区别

loc&#xff1a;通过行、列的名称或标签来索引 iloc&#xff1a;通过行、列的索引位置来寻找数据 首先&#xff0c;我们先创建一个DataFrame生成数据 import pandas as pddata {a:[1,2,3,4,5],b:[6,7,8,9,10],c:[11,12,13,14,15] } data pd.DataFrame(data) print(data) 运行…

关于【禁止new对象时在for循环内定义申明变量】

文章目录 简介代码分析反编译之后对比性能测试内存与垃圾回收情况JDK和常用框架怎么写总结依赖 简介 不知道是谁最先提出了一个不要将变量定义在循环内。 然后我们在代码扫描中有一项是&#xff1a;【禁止new对象时在for循环内定义申明变量】 我也好奇为什么不能&#xff1f…

e冒泡排序---复杂度O(X^2)

排序原理: 1.比较相邻的元素。如果前一个元素比后一个元素大&#xff0c;就交换这两个元素的位置。 2.对每一对相邻元素做同样的工作,从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大值, public class 冒泡排序 {public static void main(String[] args) {I…

学习使用LangGraph x GPT-Researcher构建一个多智能体架构的AI自主研究助理

原文&#xff1a;学习使用LangGraph x GPT-Researcher构建一个多智能体架构的AI自主研究助理 - 百度智能云千帆社区 本文为大家剖析一个通过多智能体协作来完成的AI研究助理&#xff0c;可以用来帮助进行各种综合的在线研究任务并输出报告。该应用基于LangGraph以及开源的GPT-…

electron有关mac构建

针对 Mac M1/2/3 芯片的设备&#xff0c;proces.archarm64. 执行下面命令&#xff0c;检查下按照的 node.js 版本是不是 intel x64 指令集&#xff0c;如果是的话安装下 arm64 指令集的 node.js终端中执行以下命令&#xff1a;node -p process.arch 对应的node版本也是arm版 …

YoloV10 训练自己的数据集(推理,转化,C#部署)

目录 一、下载 三、开始训练 train.py detect.py export.py 超参数都在这个路径下 四、C#读取yolov10模型进行部署推理 如下程序是用来配置openvino 配置好引用后就可以生成dll了 再创建一个控件&#xff0c;作为显示 net framework 4.8版本的 再nuget工具箱里下载 …

春之学习:SpringBoot在线教育平台构建

第三章 系统分析 3.1 系统设计目标 在线视频教育平台主要是为了用户方便对首页、个人中心、用户管理、教师管理、课程信息管理、课程类型管理、我的收藏管理、系统管理、订单管理等信息进行查询&#xff0c;也是为了更好的让管理员进行更好存储所有数据信息及快速方便的检索功能…