当前位置: 首页 > news >正文

Solidity 小白教程:22. Call

Solidity 小白教程:22. Call

这一讲我们将介绍如何利用 Call 调用合约。

Call

calladdress类型的低级成员函数,它用来与其他合约交互。它的返回值为**(bool, data),分别对应call**是否成功以及目标函数的返回值。

  • callsolidity官方推荐的通过触发fallbackreceive函数发送ETH的方法。
  • 不推荐用call来调用另一个合约,因为当你调用不安全合约的函数时,你就把主动权交给了它。推荐的方法仍是声明合约变量后调用函数,见第 21 讲:调用其他合约
  • 当我们不知道对方合约的源代码或ABI,就没法生成合约变量;这时,我们仍可以通过call调用对方合约的函数。

call的使用规则

call的使用规则如下:

目标合约地址.call(二进制编码);

其中二进制编码利用结构化编码函数abi.encodeWithSignature获得:

abi.encodeWithSignature("函数签名", 逗号分隔的具体参数)

函数签名为**“函数名(逗号分隔的参数类型)”。例如abi.encodeWithSignature(“f(uint256,address)”, _x, _addr)
另外
call在调用合约时可以指定交易发送的ETH数额和gas**:

目标合约地址.call{value:发送数额, gas:gas数额}(二进制编码);

看起来有点复杂,下面我们举个call应用的例子。

目标合约

我们先写一个简单的目标合约OtherContract并部署,代码与第 19 讲中基本相同,只是多了fallback函数。

contract OtherContract {uint256 private _x = 0; // 状态变量x// 收到eth的事件,记录amount和gasevent Log(uint amount, uint gas);fallback() external payable{}// 返回合约ETH余额function getBalance() view public returns(uint) {return address(this).balance;}// 可以调整状态变量_x的函数,并且可以往合约转ETH (payable)function setX(uint256 x) external payable{_x = x;// 如果转入ETH,则释放Log事件if(msg.value > 0){emit Log(msg.value, gasleft());}}// 读取xfunction getX() external view returns(uint x){x = _x;}
}

这个合约包含一个状态变量x,一个在收到ETH时触发的事件Log,三个函数:

  • getBalance(): 返回合约ETH余额。
  • setX(): external payable函数,可以设置x的值,并向合约发送ETH
  • getX(): 读取x的值。

利用call调用目标合约

1. Response 事件
我们写一个Call合约来调用目标合约函数。首先定义一个Response事件,输出call返回的successdata,方便我们观察返回值。

// 定义Response事件,输出call返回的结果success和data
event Response(bool success, bytes data);

2. 调用 setX 函数
我们定义callSetX函数来调用目标合约的setX(),转入msg.value数额的ETH,并释放Response事件输出successdata

function callSetX(address payable _addr, uint256 x) public payable {// call setX(),同时可以发送ETH(bool success, bytes memory data) = _addr.call{value: msg.value}(abi.encodeWithSignature("setX(uint256)", x));emit Response(success, data); //释放事件
}

接下来我们调用callSetX把状态变量**_x改为 5,参数为OtherContract地址和5**,由于目标函数setX()没有返回值,因此Response事件输出的data0x,也就是空。
image.png
3. 调用 getX 函数
下面我们调用getX()函数,它将返回目标合约_x的值,类型为uint256。我们可以利用abi.decode来解码call的返回值data,并读出数值。

function callGetX(address _addr) external returns(uint256){// call getX()(bool success, bytes memory data) = _addr.call(abi.encodeWithSignature("getX()"));emit Response(success, data); //释放事件return abi.decode(data, (uint256));
}

Response事件的输出,我们可以看到data0x0000000000000000000000000000000000000000000000000000000000000005。而经过abi.decode,最终返回值为5
image.png
4. 调用不存在的函数
如果我们给call输入的函数不存在于目标合约,那么目标合约的fallback函数会被触发。

function callNonExist(address _addr) external{// call getX()(bool success, bytes memory data) = _addr.call(abi.encodeWithSignature("foo(uint256)"));emit Response(success, data); //释放事件
}

上面例子中,我们call了不存在的foo函数。call仍能执行成功,并返回success,但其实调用的目标合约fallback函数。
image.png

总结

这一讲,我们介绍了如何用call这一低级函数来调用其他合约。call不是调用合约的推荐方法,因为不安全。但他能让我们在不知道源代码和ABI的情况下调用目标合约,很有用。

相关文章:

Solidity 小白教程:22. Call

Solidity 小白教程:22. Call 这一讲我们将介绍如何利用 Call 调用合约。 Call call 是address类型的低级成员函数,它用来与其他合约交互。它的返回值为**(bool, data),分别对应call**是否成功以及目标函数的返回值。 call是solidity官方推…...

mySQL 安装

一、windows安装包下载 mysql官网提供了两种安装方式,一个是zip安装,另一个是msi安装,这里简绍第一种安装方式,第二种简单,不再简绍 官网下载,根据自己需要选择版本:MySQL :: MySQL Community…...

涛然自得周刊(第 10 期):搬到海岛生活是一种什么体验

作者:何一涛 日期:2023 年 9 月 24 日 涛然自得周刊主要精选作者阅读过的书影音内容,周末发布。历史周刊内容可以看这里。 影音 《德雷尔一家》是一部根据书籍《希腊三部曲》改编的英剧,共 4 季,每一季豆瓣评分都超…...

pycharm中恢复原始界面布局_常用快捷键_常用设置

文章目录 1 恢复默认布局1 .1直接点击file→Manage IDE Settings→Restore Default Settings(如下图所示):1.2 直接点击Restore and Restart, 然后Pycharm就会自动重启,重启之后的界面就是最原始的界面了 2 改变主题2.…...

docker(7):实战--安装nginx并实现反向代理

基本概念 反向代理:客户端向反向代理的命名空间中的内容发送普通请求,接着反向代理将推断向何处(原始服务器)转交请求,并将获得的内容返回给客户端。 负载均衡:当请求过多,单个服务器难以负荷…...

day-61 代码随想录算法训练营(19)一刷完结撒花

短短60天过的很快,但是让我养成了写博客的习惯。在训练营学到了挺多不同的思路,跟录友们的交流也使我受益良多。 我的感觉是,一道题没有思路的时候,要及时去看题解;毕竟是应试,第一次做的时候,没…...

C#中对泛型集合元素使用List.Sort()方法排序

啊&#xff01;终于整明白了&#xff01; 今天拿出一点时间研究了一下C#的List<T>如何排序&#xff0c;基本上整明白了。很多场景下&#xff0c;用这个排序还是很方便的。 //构造一个类 public class mth{//编号private string id;public string Id{get { return id; …...

【项目】在线音乐播放器测试报告

目录 项目背景 项目功能 测试计划 功能测试 登录页面的测试 测试用例 测试结果 注册页面的测试 测试用例 测试结果 音乐列表页面的测试 测试用例 测试结果 出现的bug 搜索功能的bug 问题解决 删除功能的bug 问题解决 喜欢列表页面的测试 测试用例 测试结果…...

[C++ 网络协议] 多线程服务器端

具有代表性的并发服务器端实现模型和方法&#xff1a; 多进程服务器&#xff1a;通过创建多个进程提供服务。 多路复用服务器&#xff1a;通过捆绑并统一管理I/O对象提供服务。 多线程服务器&#xff1a;通过生成与客户端等量的线程提供服务。✔ 目录 1. 线程的概念 1.1 为什…...

宝塔部署node后使用pm2管理上传文件路径失效问题

如何进行文件上传&#xff1f; node上传文件 vue3 elementPlus 组件封装 在本地或者以宝塔终端的形式允许 上传后是没问题的&#xff0c;直接默认对multer直接写入路径就可以了 const multer require(multer) const upload multer({ dest: ./public/avataruploads/ }) …...

postman-pre-request-scripts使用

一、场景 二、定义模拟接口 using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using SaaS.Framework.DataTransfer; using System.Threading.Tasks;namespace SaaS.KDemo.Api.Controllers {[Route("api/[co…...

uniapp Echart X轴Y轴文字被遮挡怎么办,或未能铺满整个容器

有时候布局太小&#xff0c;使用echarts&#xff0c;x轴y轴文字容易被遮挡&#xff0c;怎么解决这个问题呢&#xff0c;或者是未能铺满整个容器。 方法1&#xff1a; 直接设置 containLabel 字段 options: { grid: { containLabel: true, },} 方法2: 间接设置&#xff0c;但是…...

学习路之PHP--laravel DingoApi

一、安装 1.进入项目目录&#xff0c;执行composer安装命令 composer require dingo/api 如果下载超时&#xff0c;换阿里云源&#xff1a; composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 2.使用以下命令可以发布 API 的配置文件到 confi…...

项目篇——java文档搜索引擎

Java 文档搜索引擎 文章目录 Java 文档搜索引擎一、分词二、完成parser 类2.1、排除非html文件2.2、解析html以下是解析 HTML 标题的方法以下是解析 对应的 URL以下是解析 HTML的正文&#xff1a; 补充&#xff1a;倒序索引 三、实现 index 类3.1、实现索引结构3.2、索引中新增…...

5.2 磁盘CRC32完整性检测

CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法&#xff0c;校验算法可以通过计算应用与数据的循环冗余校验&#xff08;CRC&#xff09;检验值来检测任何数据损坏。通过运用本校验技术我们可以实现对特定内存区域以及磁盘文件进行完整性检测&#xff0c;…...

企业内部安全与风控管理图解

企业内部安全说外部安全&#xff0c;企业领导者都非常关注&#xff0c;由于各方面原因&#xff0c;。。。力不从心&#xff0c;妥协&#xff01; 方向&#xff1a; 1、制度 结合企业实情&#xff0c;编制企业安全管理制度 2、硬件 处理常规硬件外观&#xff0c;加壳与锁定、…...

vscode基于cmake安装opencv库

一、安装相关依赖库 首先更新源 sudo apt update安装相关包 sudo apt-get install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev libjasper若是报错&#xff1a;无法定位到 libjasper软件包 则依次执行以下命令 sud…...

Web 器学习笔记(基础)

Filter 过滤器 概念&#xff1a;表示过滤器&#xff0c;是 JavaWeb 三大组件&#xff08;Servlet、Filter、Listener&#xff09;之一 作用&#xff1a;顾名思义可以过滤资源的请求&#xff0c;并实现特殊的需求 Filter 接口及它核心的 doFilter() 方法&#xff08;执行前就是…...

uniapp中vue3使用uni.createSelectorQuery().in(this)报错

因为VUE3中使用setup没有this作用域&#xff0c;所以报错 解决办法&#xff1a;使用getCurrentInstance()方法获取组件实例 import { getCurrentInstance } from vue;const instance getCurrentInstance(); // 获取组件实例 const DOMArr uni.createSelectorQuery().in(ins…...

k8s-部署

1.k8s 集群与部署 更改所有主机名字和解析 k8s1 192.168.25.11 reg.westos.org,habbor 仓库 k8s2 192.168.25.12 master&#xff0c;k8s 集群控制节点 k8s3 192.168.25.13 node&#xff0c;k8s 集群工作节点 k8s4 192.168.25.14 node&#xff0c;k8s 集群工作节点 所有节…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)

本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢&#xff0c;连接红外测温传感器&#xff0c;可实时精准捕捉宠物体温变化&#xff0c;以便及时发现健康异常&#xff1b;水位检测传感器时刻监测饮用水余量&#xff0c;防止宠物…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...

raid存储技术

1. 存储技术概念 数据存储架构是对数据存储方式、存储设备及相关组件的组织和规划&#xff0c;涵盖存储系统的布局、数据存储策略等&#xff0c;它明确数据如何存储、管理与访问&#xff0c;为数据的安全、高效使用提供支撑。 由计算机中一组存储设备、控制部件和管理信息调度的…...

Git 命令全流程总结

以下是从初始化到版本控制、查看记录、撤回操作的 Git 命令全流程总结&#xff0c;按操作场景分类整理&#xff1a; 一、初始化与基础操作 操作命令初始化仓库git init添加所有文件到暂存区git add .提交到本地仓库git commit -m "提交描述"首次提交需配置身份git c…...