首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏nft市场

    智能合约安全——delegatecall (1)

    delegatecall函数有个有趣的特点:当使用 delegatecall 函数进行外部调用涉及到 storage 变量的修改时是根据插槽位置来修改的而不是变量名。 图片 漏洞分析 我们可以看到有两个合约,Lib 合约中只有一个 pwn 函数用来修改合约的 owner,在 HackMe 合约中存在 fallback 函数,fallback 函数的内容是使用 delegatecall 我们需要利用 HackMe.fallback() 触发 delegatecall 函数去调用 Lib.pwn() 将 HackMe 合约中的 owner 改成自己。 在使用 delegatecall 时应注意被调用合约的地址不能是可控的; 2. 在较为复杂的合约环境下需要注意变量的声明顺序以及存储位置。 因为使用 delegatecall 进行外部调时会根据被调用合约的数据结构来用修改本合约相应 slot 中存储的数据,在数据结构发生变化时这可能会造成非预期的变量覆盖。

    44830编辑于 2022-08-02
  • 来自专栏code人生

    Solidity:call 和 delegatecall

    delegatecall delegatecall与call类似,也可以调用合约的任何函数。然而,delegatecall不会创建一个新的执行环境,而是在调用合约的上下文中执行函数。 而delegatecall函数则可以改变调用合约的状态,因为它在调用合约的上下文中执行。3.用途:call函数通常用于调用其他合约的函数,而delegatecall函数则常用于实现合约的升级和库函数。 使用delegatecall的情况 delegatecall函数通常用于实现合约的升级和库函数。 不适用场景 在Solidity中,call和delegatecall都是低级函数,虽然它们在某些情况下非常有用,但在以下情况下应该避免直接使用它们: 1.安全性问题:call和delegatecall都可能导致重入攻击 2.异常处理:call和delegatecall不会自动处理被调用函数抛出的异常。如果被调用的函数抛出异常,那么整个交易都会被回滚,除非你在调用call或delegatecall时进行了检查。

    44410编辑于 2024-05-28
  • 来自专栏信且诚心之动

    使用delegatecall扩充合约功能

    如果是,说明你需要了解一下delegatecall了。 在智能合约的开发中,使用 delegatecall 是一种强大的技术手段,它允许一个合约在执行时调用另一个合约的代码。 本文将深入介绍 delegatecall 的概念,以及如何利用它来扩充合约功能。 二、什么是 delegatecall? 升级合约逻辑 通过 delegatecall,我们可以将新版本的合约逻辑部署为一个独立的合约,并通过调用旧合约的 delegatecall 函数来执行新逻辑。 功能模块化 使用 delegatecall 可以将合约的功能拆分为多个独立的模块,每个模块部署为一个独立的合约。主合约通过 delegatecall 调用这些模块,从而实现功能的动态组合和替换。 六、总结 delegatecall 是一项强大的技术,为智能合约提供了灵活性和可升级性。通过合理利用 delegatecall,开发者可以在不破坏原有合约结构的基础上,实现功能的动态扩展和升级。

    40040编辑于 2023-11-14
  • 来自专栏nft市场

    智能合约安全——delegatecall (2)

    本次,我们来讲一讲运用delegatecall函数时更复杂的合约漏洞案例。 HackMe.doSomething() 函数使用 delegatecall 函数带着传入的 Attack 合约的地址调用了 Lib.doSomething() 函数;3. 可以看到 Lib.doSomething() 函数将合约中存储位置为 slot0 的参数改为传入的值,这样当 HackMe 合约使用 delegatecall 调用 Lib.doSomething() 所以 HackMe 合约使用 delegatecall 调用 Attack.doSomething() 函数就会将合约中存储位置为 slot1 的变量 owner 修改为 msg.sender 也就是攻击者的地址 修复建议我们在合约的开发中使用delegatecall要时刻注意其被调用的合约地址要始终在我们设计的逻辑内运行,不能让其有可能超出我们设计时的适用范围,一旦出现了超出我们预期设计的情况,那么合约就有可能被不法之徒利用

    36620编辑于 2022-08-03
  • 来自专栏深入浅出区块链技术

    如何利用delegatecall进行以太坊智能合约升级

    Solidity[4]有三种合约间的调用方式 call、delegatecall 和 callcode。其中,delegatecall可作为智能合约升级的一个较好的途径。 关于合约间的调用方式 call、delegatecall 和 callcode,详见我另一篇文章<<图文并茂详细介绍Solidity的三种合约间的调用方式 call、delegatecall 和 callcode

    92730发布于 2021-10-27
  • 来自专栏FreeBuf

    Parity多重签名合约Delegatecall漏洞回顾

    二、漏洞原理 delegatecall的含义:

    .delegatecall(...) returns (bool):issue low-level DELEGATECALL, returns call与delegatecall的功能类似,区别仅在于后者仅使用给定地址的代码,其它信息则使用当前合约(如存储,余额等等)。注意delegatecall是危险函数,他可以完全操作当前合约的状态。 黑客通过 delegatecall 调用 initWallet 函数, initWallet 没有检查以防止攻击者在合同初始化后调用到 initMultiowned ,漏洞使得黑客能通过 library required, uint _daylimit) { initDaylimit(_daylimit); initMultiowned(_owners, _required); } 2、 代码里使用了 delegatecall msg.value > 0) Deposit(msg.sender, msg.value); else if (msg.data.length > 0) _walletLibrary.delegatecall

    1.6K62发布于 2018-07-31
  • 来自专栏深入浅出区块链技术

    预防委托调用(DELEGATECALL)引起的合约漏洞

    原文:https://betterprogramming.pub/preventing-smart-contract-attacks-on-ethereum-delegatecall-e864d0042188 与call不同,用DELEGATECALL进行函数调用时,其代码是在当前调用函数的环境里执行,因此,构建无漏洞自定义库并不像想象的那么简单。 current withdrawal user- // this sets calculatedFibNumber require(fibonacciLibrary.delegatecall users to call Fibonacci library functions function() public { require(fibonacciLibrary.delegatecall 请注意,在第 21 行,withdraw函数已经执行了fibonacciLibrary.delegatecall(fibSig,withdrawalCounter)。

    1K20编辑于 2022-04-08
  • 来自专栏区块链入门

    链安科技:智能合约call、delegatecall底层函数使用需谨慎

    二、call、callcode、delegatecall函数说明 call、callcode、delegatecall是以太坊智能合约编写语言Solidity提供的底层函数,用来与外部合约或者库进行交互 1、绕过权限检查,调用敏感函数,例如setOwer; 2、窃取合约地址持有的代币; 3、伪装成合约地址与其他合约进行交互; 三、安全建议 为了避免此类漏洞,成都链安科技建议: 1、谨慎使用call、delegatecall 成都链安科技自主研发的VaaS平台对call、delegatecall函数存在的安全问题可一键式自动检查并精确定位,VaaS(Verification as a Service)形式化验证平台,是一套针对多个区块链平台

    46120发布于 2018-08-10
  • 来自专栏Ethereum

    Solidity:代理模式升级合约

    最后,根据 delegatecall 的结果,决定是回滚交易并返回错误数据,还是返回成功的数据。 let result := delegatecall(gas(), implementation, ptr, calldatasize(), 0, 0)delegatecall 是一个 EVM 操作码, returndatasize() 返回上一个调用(即 delegatecall)返回的数据大小。这行指令的作用是将 delegatecall 的返回数据复制到内存中,从 ptr 开始存储。 result 是 delegatecall 的返回值,如果调用成功则为 1,失败则为 0。 使用 delegatecall 将调用转发到逻辑合约,并在当前合约的上下文中执行其代码。根据 delegatecall 的结果,决定是回滚交易并返回错误数据,还是返回成功的数据。

    56010编辑于 2024-08-01
  • 来自专栏深入浅出区块链技术

    合约升级模式分析

    基于delegatecall的代理,逻辑和数据也被保存在不同的合约中,但数据合约(代理)通过 delegatecall调用逻辑合约。 数据分离模式的优点是简单。 它不需要像 delegatecall模式那样的底层的专业知识。不过,最近delegatecall模式受到了广泛的关注。开发人员可能倾向于选择这种解决方案,因为文档和例子更容易找到。 这个解决方案需要掌握delegatecall,以允许一个合约使用另一个合约的代码。 让我们回顾一下delegatecall是如何工作的。 delegatecall背景知识 delegatecall允许一个合约执行另一个合约的代码,同时保持调用者的上下文(包括存储)不会变。 让我们回顾一下基于 delegatecall的不同数据存储策略。

    1.2K30编辑于 2021-12-22
  • 来自专栏YYDS

    以太智能合约丨DAPP去中心化系统开发介绍丨交易所系统开发讲解方案

    string resMes){testMem--;resMes = "try to modify testMem and has constant label";}}内部调用: call,callcode,delegatecall 除了直接调用函数,还可以通过call,callcode,delegatecall的方式调用其他合约的函数,区别如下:CALL:是在 被调用者 的上下文中执行,只能修改被调用者的storage;CALLCODE 和DELEGATECALL: 是在 调用者 的上下文中执行, 可以修改调用者的storage;CALLCODE 阻止msg.sender和msg.value传递; 而DELEGATECALL不阻止;在A 的函数中,B.callcode(c的函数): c看到msg.sender是B;在A的函数中,B.delegatecall(c的函数): c看到msg.sender是A;合约示例如下:contract D uint256)")), _n); } function delegatecallSetN(address _e, uint _n) { // D的storage被修改, E未修改 _e.delegatecall

    35630编辑于 2022-12-29
  • 来自专栏Seebug漏洞平台

    以太坊 Solidity 合约 call 函数簇滥用导致的安全风险

    delegatecall: 调用后内置变量 msg 的值不会修改为调用者,但执行环境为调用者的运行环境。 0x02 delegatecall 「滥用」问题 delegatecall: 调用后内置变量 msg 的值不会修改为调用者,但执行环境为调用者的运行环境。 利用模型 下面的例子中 B 合约是业务逻辑合约,其中存在一个任意地址的 delegatecall 调用。 除了上述 delegatecall 滥用的案例,在分析研究的过程中,发现有部分蜜罐合约利用 delegatecall的特性(拷贝目标到自己的运行空间中执行),在代码中暗藏后门,暗中修改转账地址,导致用户丢失货币 由于 callcode 同时包含了 call 和 delegatecall 的特性,通过上文对 call 和 delegatecall 的安全问题进行了分析和举例,可以得出的结论是 call 和 delegatecall

    1K20发布于 2018-07-26
  • 来自专栏Ethereum

    《纸上谈兵·solidity》第 13 课:Solidity 低级调用 call/delegatecall/staticcall —— 直接和 EVM“对话”

    是否能改状态特点与用途 call ✅ 切换到被调用合约 ✅ 最通用的外部调用,可带 ETH,可调用任意函数delegatecall delegatecall:不切场景、能改状态。staticcall:切场景、不能改状态。2. delegatecall 与 call 的主要区别是:delegatecall 不会更改 msg.sender 和 msg.value。存储上下文(storage slot)不切换,直接写到当前合约。 ( abi.encodeWithSignature("setValue(uint256)", _v) ); require(success, "delegatecall delegatecall:让别人用你的钱包执行代码。staticcall:借别人的计算器算一算,不动任何钱。

    45310编辑于 2025-08-15
  • 来自专栏Seebug漏洞平台

    以太坊 Solidity 合约 call 函数簇滥用导致的安全风险

    在 Solidity 中提供了 call、delegatecall、callcode 三个函数来实现合约之间相互调用及交互。 delegatecall: 调用后内置变量 msg 的值不会修改为调用者,但执行环境为调用者的运行环境。 「滥用」问题 delegatecall: 调用后内置变量 msg 的值不会修改为调用者,但执行环境为调用者的运行环境。 利用模型 下面的例子中 B 合约是业务逻辑合约,其中存在一个任意地址的 delegatecall 调用。 由于 callcode 同时包含了 call 和 delegatecall 的特性,通过上文对 call 和 delegatecall 的安全问题进行了分析和举例,可以得出的结论是 call 和 delegatecall

    1.2K30发布于 2018-07-12
  • 来自专栏Ethereum

    《纸上谈兵·solidity》第 29 课:智能合约安全审计案例复盘 -- Parity Wallet Hack(2017)

    关键点:Parity 多签钱包的逻辑代码存放在一个 库合约(WalletLibrary) 中,所有钱包合约通过 delegatecall 调用它。库合约本身没有正确初始化 owner。 (data); // 调用库合约函数 }}delegatecall 会在 调用者的存储上下文 中执行库合约代码。 delegatecall 必须小心使用,库合约最好是无状态(Stateless)。selfdestruct 是危险函数,应该避免在核心合约中出现。智能合约一旦部署,升级和错误修复极其困难。6. 这里的关键:即使库代码被清空,delegatecall 对不存在的地址 不会立即 revert,而是返回空数据,且在 Solidity >=0.8.0 时默认 success = true。 在旧 EVM 下,delegatecall 到不存在地址会直接 revert;在现代 EVM 下,delegatecall 为空代码仍然返回成功,但 res 为空。

    39210编辑于 2025-09-07
  • 来自专栏Ethereum

    《纸上谈兵·solidity》第 14 课:Solidity 中的可升级合约模式 —— 从代理合约到透明代理、UUPS 与安全陷阱

    关键技术:delegatecall,在代理合约中使用 delegatecall 调用逻辑合约的函数,使得代码在代理的存储上下文中执行。 3、代理模式的工作原理1. delegatecall 复习(bool success, bytes memory data) = implementation.delegatecall(msg.data );delegatecall 会在当前合约的存储和上下文中执行目标合约的代码。 风险调用外部不可信合约可能破坏存储 严格控制升级权限,禁止不可信代码执行 delegatecall 权限丢失 升级过程中可能被替换成恶意逻辑 在 代理合约模式下,逻辑合约通过 delegatecall 操作的是 代理合约的 storage slot,所以逻辑合约和代理合约的变量 slot 不能冲突,否则会覆盖状态。

    50610编辑于 2025-08-16
  • 来自专栏深入浅出区块链技术

    以太坊 - 深入浅出虚拟机

    05 合约调用合约 合约内部调用另外一个合约,有4种调用方式: CALL CALLCODE DELEGATECALL STATICALL 后面会专门写篇文章比较它们的异同,这里先以最简单的CALL为例, 合约调用合约有下面4种方式: CALL CALLCODE DELEGATECALL STATICCALL 8.1 CALL vs. DELEGATECALL 实际上,可以认为DELEGATECALL是CALLCODE的一个bugfix版本,官方已经不建议使用CALLCODE了。 CALLCODE和DELEGATECALL的区别在于:msg.sender不同。 具体来说,DELEGATECALL会一直使用原始调用者的地址,而CALLCODE不会。 ? 我们再调用一下inc_delegatecall(),观察一下log输出: ? 可以发现,msg.sender指向的是交易的发起者。

    1K40发布于 2019-04-28
  • 来自专栏深入浅出区块链技术

    Solidity教程系列2 - 地址类型介绍

    call(), callcode() 和 delegatecall() 函数 为了和非ABI协议的合约进行交互,可以使用call() 函数, 它用来向另一个合约发送原始数据,支持任何类型任意数量的参数, (这句我怕翻译的不准确,引用原文) 同样我们也可以使用delegatecall(),它与call方法的区别在于,仅仅是代码会执行,而其它方面,如(存储,余额等)都是用的当前的合约的数据。 delegatecall()方法的目的是用来执行另一个合约中的库代码。所以开发者需要保证两个合约中的存储变量能兼容,来保证delegatecall()能顺利执行。 上面的这三个方法call(),delegatecall(),callcode()都是底层的消息传递调用,最好仅在万不得已才进行使用,因为他们破坏了Solidity的类型安全。 .gas() 在call(), callcode() 和 delegatecall() 函数下都可以使用, delegatecall()不支持.value() 注解:所有合约都继承了address的成员

    61820发布于 2018-07-23
  • 来自专栏区块链大本营

    偷天换日合约易主,地址变脸移花接木——底层函数误用漏洞 | 漏洞分析连载之四

    可注入call漏洞和delegatecall误用漏洞会导致什么风险? 何为合约外部调用 专业的来说,call与delegatecall 函数让 Ethereum开发者将他们的代码模块化(Modularise)。 误用漏洞 漏洞分析 DELEGATECALL会保持调用环境不变的属性表明,构建无漏洞的定制库并不像人们想象的那么容易。 案例 案例代码来源于Ethernaut第6关[5] 在主合约Delegation的fallback函数中,可通过delegatecall调用Delegate合约的函数,并在主合约环境下执行,如果msg.data 在使用时 DELEGATECALL 时要特别注意库合约和调用合约可能对状态变量进行修改,并且尽可能构建无状态library 。

    43540发布于 2018-08-15
  • 来自专栏深入浅出区块链技术

    UUPSUpgradeable 漏洞分析

    但是其又引入了一个新的问题,即:回滚操作中事实上模拟了一遍新的实现合约地址中的upgradeTo操作,并且是通过delegatecall方式来进行调用。 通过delegatecall调用新合约地址的upgradeTo方法有什么问题呢? 查看黄皮书中关于delegatecall的定义为: Message-call into this account with an alternative accounts' code, but persisting POC 这里不能直接在malicious合约中的upgradeTo方法中写selfdestruct,而是应该利用ForceCall部分的delegatecall,并通过写入rollbackTesting.value 然而在remix中执行时,发现delegatecall之后的require语句还是执行了: 这是不对的,需要进一步理解黄皮书中关于selfdestruct这个opcode的定义: selfdestruct

    1.4K30发布于 2021-10-13
领券