智能合约的4种调用方式:call、callcode、delegatecall、staticcall

2024-01-03 20:30

本文主要是介绍智能合约的4种调用方式:call、callcode、delegatecall、staticcall,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

智能合约的4种调用方式:call、callcode、delegatecall、staticcall
资料来源:
以太坊 - 深入浅出虚拟机   以太坊 - 深入浅出虚拟机 | 登链社区 | 区块链技术社区虚拟机用来执行以太坊上的交易,更改以太坊状态。交易分两种:普通交易和智能合约交易。在执行交易时需要支付油费。智能合约之间的调用有四种方式https://learnblockchain.cn/2019/04/09/easy-evm/
1 四种合约调用方式
合约调用合约有下面4种方式:
  • CALL
  • CALLCODE              官方已经废弃CALLCODE了
  • DELEGATECALL
  • STATICCALL
2 CALL vs. CALLCODE
CALL和CALLCODE的区别在于:代码执行的上下文环境不同。
具体来说,CALL修改的是被调用者的storage,而CALLCODE修改的是调用者的storage。

pragma solidity ^0.4.25;
contract A {
  int public x;
  function inc_call(address _contractAddress) public {
      _contractAddress.call(bytes4(keccak256("inc()")));
  }
  function inc_callcode(address _contractAddress) public {
      _contractAddress.callcode(bytes4(keccak256("inc()")));
  }
}
contract B {
  int public x;
  function inc() public {
      x++;
  }
}
CALLCODE vs. DELEGATECALL
实际上,可以认为DELEGATECALL是CALLCODE的一个bugfix版本,官方已经不建议使用CALLCODE了。
CALLCODE和DELEGATECALL的区别在于:msg.sender不同。
具体来说,DELEGATECALL会一直使用原始调用者的地址,而CALLCODE不会。

我们还是写一段代码来验证我们的理解:
pragma solidity ^0.4.25;
contract A {
  int public x;
  function inc_callcode(address _contractAddress) public {
      _contractAddress.callcode(bytes4(keccak256("inc()")));
  }
  function inc_delegatecall(address _contractAddress) public {
      _contractAddress.delegatecall(bytes4(keccak256("inc()")));
  }
}
contract B {
  int public x;
  event senderAddr(address);
  function inc() public {
      x++;
      emit senderAddr(msg.sender);
  }
}
STATICCALL
STATICCALL放在这里似乎有滥竽充数之嫌,因为目前Solidity中并没有一个low level API可以直接调用它,仅仅是计划将来在编译器层面把调用view和pure类型的函数编译成STATICCALL指令。 view类型的函数表明其不能修改状态变量,而pure类型的函数则更加严格,连读取状态变量都不允许。
目前是在编译阶段来检查这一点的,如果不符合规定则会出现编译错误。如果将来换成STATICCALL指令,就可以完全在运行时阶段来保证这一点了,你可能会看到一个执行失败的交易。
话不多说,我们就先看看STATICCALL的实现代码吧:
 
可以看到,解释器增加了一个readOnly属性,STATICCALL会把该属性置为true,如果出现状态变量的写操作,则会返回一个errWriteProtection错误。

这篇关于智能合约的4种调用方式:call、callcode、delegatecall、staticcall的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

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

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

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

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

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

用命令行的方式启动.netcore webapi

用命令行的方式启动.netcore web项目 进入指定的项目文件夹,比如我发布后的代码放在下面文件夹中 在此地址栏中输入“cmd”,打开命令提示符,进入到发布代码目录 命令行启动.netcore项目的命令为:  dotnet 项目启动文件.dll --urls="http://*:对外端口" --ip="本机ip" --port=项目内部端口 例: dotnet Imagine.M

智能交通(二)——Spinger特刊推荐

特刊征稿 01  期刊名称: Autonomous Intelligent Systems  特刊名称: Understanding the Policy Shift  with the Digital Twins in Smart  Transportation and Mobility 截止时间: 开放提交:2024年1月20日 提交截止日

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

【即时通讯】轮询方式实现

技术栈 LayUI、jQuery实现前端效果。django4.2、django-ninja实现后端接口。 代码仓 - 后端 代码仓 - 前端 实现功能 首次访问页面并发送消息时需要设置昵称发送内容为空时要提示用户不能发送空消息前端定时获取消息,然后展示在页面上。 效果展示 首次发送需要设置昵称 发送消息与消息展示 提示用户不能发送空消息 后端接口 发送消息 DB = []@ro

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个