区块链安全
文章平均质量分 93
本专栏将深入探讨区块链原理、区块链开发、智能合约审计、常见攻击手法、漏洞复现、攻防实战等关键安全议题,帮助读者掌握区块链安全的精髓。无论你是区块链开发者、安全研究员,还是对区块链安全充满兴趣的学习者,这里都有你不可错过的干货内容。
秋说
全栈开发与网安实战导师 | 欢迎订阅优质付费专栏,专注做「新手能看懂、学完能实战」的友好型全栈技术教程。商务合作/项目毕设指导/产品推广/技术支持→私信沟通
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
【区块链安全 | 第一篇】密码学原理
前瞻攻击指的是在某些交易或竞拍环境中,恶意用户通过提前得知即将提交的交易或出价信息,在其之前进行自己的交易或操作,从而获得不公平的优势。例如,在一个去中心化交易所(DEX)中,攻击者可能会提前看到用户的交易订单,然后在交易执行之前先行交易,从而操控市场价格,获取额外利润。提交交易:用户提交的并不是交易的真实内容,而是交易内容的 哈希值。在提交阶段,用户在提交他们的实际交易数据或出价之前,会先提交一个 加密哈希 值(commitment),这个哈希值是通过 哈希函数 对交易数据进行加密处理得到的。原创 2025-03-25 14:55:15 · 1487 阅读 · 0 评论 -
【区块链安全 | 第二篇】区块链概念详解
区块链是一种去中心化(Decentralized) 的分布式账本技术(Distributed Ledger Technology, DLT),它通过密码学、共识算法和点对点网络,实现多个节点之间无信任的存储和共享数据。区块链的核心特性包括去中心化、不可篡改、透明性和安全性。原创 2025-03-25 15:17:22 · 1394 阅读 · 0 评论 -
【区块链安全 | 第三篇】主流公链以太坊运行机制
最常见的代币标准是 ERC-20(同质化代币) 和 ERC-721(非同质化代币),它们分别用于代表可替代代币(如 USDT、DAI) 和NFT(如 BAYC、CryptoPunks)。以太坊虚拟机(Ethereum Virtual Machine,EVM)是以太坊智能合约执行的核心,它提供了一个图灵完备的计算环境,能够在不同的以太坊节点上执行智能合约代码,并保持一致性。例如,Uniswap 智能合约本身不会主动买卖代币,而是等待用户(EOA)发送交易请求,触发合约执行 swap 逻辑。原创 2025-03-25 22:54:15 · 1439 阅读 · 0 评论 -
【区块链安全 | 第四篇】EOS架构
相比以太坊,EOS 采用 DPoS(委托权益证明) 共识机制,提升交易速度,同时使用资源管理代替 Gas 机制。EOS 使用 WebAssembly(WASM) 作为虚拟机(VM),相比以太坊的 EVM(Ethereum Virtual Machine),执行效率更高。dappgame123(DApp 账户)在 EOS 上的智能合约会解析这笔交易,并更新内部数据(例如给 Alice 发放道具)。从上面可以看出:EOS 可以细化权限,提高安全性,而以太坊中,私钥 = 账户所有权。原创 2025-03-26 10:44:22 · 1325 阅读 · 0 评论 -
【区块链安全 | 第五篇】DeFi概念详解
举个例子,比特币(BTC)和以太坊(ETH)等加密货币价格波动剧烈,一天内可能涨跌 10% 以上,因此投资者和商家很难接受高波动的资产,例如:你今天用 1 BTC 买了一辆车,明天 BTC 价格上涨 20%,相当于亏了 20%。用户发布买单(买入某资产的请求)和卖单(卖出某资产的请求),交易所通过撮合买卖双方的订单来完成交易。6.由于你的买单数量是 10 ETH,但市场上只有 5 ETH 的卖单,所以你还剩下 5 ETH 的买单没有被成交,这部分 5 ETH 会继续挂单在订单簿上,等待卖单的出现。原创 2025-03-26 16:48:05 · 1295 阅读 · 0 评论 -
【区块链安全 | 第六篇】NFT概念详解
1.每个 NFT 都是独特的,不可互换,比如一幅数字艺术品、一个游戏装备(你买了一幅 Beeple 的 NFT 画作,编号 #2053,它是独一无二的,不能交换成另一幅不同的 NFT 画作)1.可互换,同一代币的单位彼此相同,如 1 USDT = 1 USDT(你拥有 1 ETH,你可以把它换成任何其2.他人的 1 ETH,它们的价值和属性完全相同。ERC-1155 允许同一个合约管理多种类型的代币,可同时包含可替代代币(FT)(如游戏金币、代币)、非同质化代币(NFT)(如游戏道具、皮肤)原创 2025-03-26 18:13:58 · 1846 阅读 · 0 评论 -
【区块链安全 | 第七篇】EVM概念详解
以太坊虚拟机(Ethereum Virtual Machine,EVM)是以太坊区块链的核心计算环境,负责执行智能合约和处理交易。EVM 让所有以太坊节点能够达成共识,并在去中心化网络中保持一致的计算结果。原创 2025-03-27 20:53:27 · 2148 阅读 · 5 评论 -
【区块链安全 | 第八篇】多签机制及恶意多签
当黑客获取用户的私钥或助记词后,如果该用户未使用多签机制(即钱包仅由用户单独控制),黑客便能直接修改账户权限,将 Owner 或 Active 权限授权给自己的地址,甚至完全转移至自己的控制之下。在下图所示案例中,用户的 Owner/Active 权限未被移除,但黑客在账户权限中添加了自己的地址,并赋予相同的权限。你的权重是 1,但阈值是 2,你单独签名的交易不会生效。另一种更具破坏性的方式是,黑客直接更改账户权限,将 Owner/Active 权限完全转移至自己的地址,并将用户的权限移除。原创 2025-03-29 11:27:25 · 1318 阅读 · 0 评论 -
【区块链安全 | 第九篇】基于Heimdall设计的智能合约反编译项目
代理合约只是一个转发请求的合约,而实际的业务逻辑由实现合约(Implementation Contract)来执行。它不仅支持普通合约的反编译,还能自动解析代理合约(Proxy Contract),并找到对应的实现合约(Implementation Contract)进行反编译,极大地方便了合约分析工作。通过RPC端点和合约地址,我们能够与区块链节点上的合约进行通信,查询该合约的字节码。合约字节码是编译后的 Solidity 代码,包含了合约的执行逻辑,但不以可读的形式展示。原创 2025-03-29 10:46:42 · 1535 阅读 · 0 评论 -
【区块链安全 | 第十篇】智能合约概述
这是因为越多的区块添加到某个区块上时,这个区块被回滚的可能性就越小。所以,可能会出现你的交易被回滚甚至从区块链中移除的情况,但等待的时间越长,这种情况发生的可能性就越小。警告:使用 Unicode 文本时需要小心,因为一些看起来相似甚至完全相同的字符,可能具有不同的代码点(Code Point),因此它们的字节编码可能不同,从而引发安全或兼容性问题。解决方案:监听 Sent 事件,并创建自己的区块链浏览器来跟踪交易记录和余额变化,但你查询合约地址(通过合约内部的查询函数),而不是代币持有人的地址。原创 2025-03-29 18:31:31 · 1277 阅读 · 0 评论 -
【区块链安全 | 第十一篇】Solidity 项目及代码示例
支付通道允许交易双方在不频繁使用链上交易的情况下进行多次支付。这样可以大幅减少延迟和交易成本。我们将在此探索一种简单的单向支付通道,仅涉及两方(Alice 和 Bob)。整个流程分为三个步骤:1.Alice 向智能合约存入以太币,开启支付通道。2.Alice 向 Bob 发送签名消息,声明应支付的金额。这个过程可以多次进行,每次支付都发送一条新签名消息。3.Bob 关闭支付通道,从合约中提取他应得的金额,同时剩余的资金返还给 Alice。原创 2025-03-29 23:24:35 · 781 阅读 · 0 评论 -
【区块链安全 | 第十二篇】安装 Solidity 编译器(npm | docker | Linux | macOS)
除了正式版本发布,Solidity 官方还提供每夜构建版本(nightly builds),开发者可以提前尝试新功能并提供反馈。然而,每夜构建版本包含开发分支的最新代码,并不保证始终可用,可能存在未记录或已损坏的更改,这些更改可能最终不会出现在正式版本中。,在版本号为 0(即 0.x.y)的情况下,补丁级别的发布不会引入破坏性更改。注意:Snap 使用严格封闭(strict confinement)模式,这种模式虽然更安全,但也带来了一些限制,比如只能访问 /home 和 /media 目录。原创 2025-03-30 09:33:36 · 1561 阅读 · 0 评论 -
【区块链安全 | 第十三篇】Solidity 合约结构
Solidity 事件(Events)是 EVM(以太坊虚拟机)提供的日志机制,用于在链上记录特定操作,并供外部应用监听和使用。状态变量是指那些值被永久存储在合约存储中的变量,或者是临时存储在瞬态存储中的变量,后者在每次交易结束时会被清除。3.Solidity 中的枚举本质上是 uint 类型,第一个成员的默认值为 0,第二个成员为 1,以此类推。函数调用可以是内部的或外部的,并且具有不同的可见性级别。函数通常定义在合约内,但也可以在合约外部定义。2.枚举类型的变量只能取其定义的值,从而减少潜在的错误。原创 2025-03-30 10:29:07 · 767 阅读 · 0 评论 -
【区块链安全 | 第十四篇】类型之值类型(一)
Solidity 是一种静态类型语言,这意味着每个变量(无论是状态变量还是局部变量)都需要在声明时指定类型。Solidity 提供了多种基本类型,这些类型可以组合成复杂的数据类型。此外,不同类型可以在包含运算符的表达式中相互作用,并且运算符具有优先级区分。Solidity 没有“未定义”或“空”值的概念,但新声明的变量总会有默认值,且默认值取决于其类型。如果遇到意外的值,应使用 revert 函数回滚交易,或者返回一个布尔值的元组,其中第二个 bool 值表示操作是否成功。原创 2025-03-30 10:52:41 · 938 阅读 · 0 评论 -
【区块链安全 | 第十五篇】类型之值类型(二)
用户定义值类型(User-Defined Value Types)允许开发者在不引入额外运行时开销的前提下,对基础类型(如 uint256、address 等)进行类型封装,实现更强的类型安全。这种机制提供了类似类型别名的功能,但在类型系统中更加严格。其中 C 是新定义的类型名,V 是必须来自内建的值类型(即基础类型)。可以使用以下函数进行类型转换:C.wrap(value):将基础类型值转换为用户定义类型。C.unwrap(value):将用户定义类型值转换为基础类型。原创 2025-03-30 11:12:29 · 1167 阅读 · 0 评论 -
【区块链安全 | 第十六篇】类型之值类型(三)
无论该函数是合约中的 private、internal、public 函数,还是库中的函数,甚至是自由函数,均可被作为内部函数类型的变量进行赋值。虽然被引用的函数可能会发生变化或消失,但直接的外部调用将受到相同的影响,因此在这种使用方式下没有额外的风险。需要注意的是,当前合约中的 public 函数既可以作为内部函数使用(通过函数名直接调用),也可以作为外部函数使用(通过 this.f 的方式调用)。内部函数类型 仅可在当前合约中调用(更准确地说,是在当前代码单元中调用,包括内部的库函数或继承的函数)。原创 2025-03-30 11:33:00 · 1107 阅读 · 0 评论 -
【区块链安全 | 第十七篇】类型之引用类型(一)
如果使用引用类型,必须明确提供数据存储的位置:memory(其生命周期仅限于外部函数调用期间)、storage(存储状态变量的位置,其生命周期与合约的生命周期一致)或 calldata(一个特殊的数据存储区域,其中包含函数参数)。例如,如果有一个变量 uint[][5] memory x,要访问第三个动态数组中的第七个 uint,应使用 x[2][6],而访问第三个动态数组则使用 x[2]。该表示法与某些其他语言相反。这与值类型形成对比,在值类型中,每当使用一个值类型的变量时,都会获得一个独立的副本。原创 2025-03-31 20:26:46 · 1042 阅读 · 0 评论 -
【区块链安全 | 第十八篇】类型之引用类型(二)
它的语法为 x[start:end],其中 start 和 end 是表达式,结果类型为 uint256(或者可以隐式转换为 uint256)。结构体(struct)类型可以被用作映射(mapping)和数组(array)中的元素,而结构体自身也可以包含映射或数组成员。需要注意的是,结构体不能直接包含自身类型的成员,尽管它们可以作为映射的值类型,或者包含自身类型的动态数组。为了避免出现意料之外的行为,推荐使用 storage 引用方式手动赋值各成员字段,尤其是在结构体中包含复杂类型的情况下。原创 2025-03-31 20:34:08 · 552 阅读 · 0 评论 -
【区块链安全 | 第十九篇】类型之映射类型
若 ValueType 是数组或映射,getter 会为每一层的 KeyType 添加一个参数,并递归生成 getter。我们为映射提供了可选的 KeyName 和 ValueName,这不会影响合约功能或字节码,仅用于在 ABI 中为 getter 的输入和输出命名。我们可以将映射视为哈希表:每个可能的键在内部自动初始化,并映射到该值类型的默认值(例如,uint 类型默认值为 0)。KeyName 和 ValueName 是可选的,只用于标识 getter 函数的输入输出名,不能是类型名称。原创 2025-03-31 20:48:23 · 579 阅读 · 0 评论 -
【区块链安全 | 第二十篇】类型之运算符
如果其中一个操作数是字面量数字,它首先会被转换为其“移动类型”,即足以容纳该值的最小类型(同位宽的无符号类型被认为比有符号类型更小)。1 : 0) 的类型是 uint8,导致整个加法操作也在 uint8 类型下执行,而结果 256 超出了该类型的范围。结果类型是根据两个备选表达式的类型共同确定的,并在需要时首先转换为它们的“移动类型”。如果右操作数的类型可以隐式转换为左操作数的类型,则采用左操作数的类型。如果左操作数的类型可以隐式转换为右操作数的类型,则采用右操作数的类型。否则,操作不被允许。原创 2025-03-31 20:56:42 · 1097 阅读 · 0 评论 -
【区块链安全 | 第二十一篇】类型之基础类型之间的转换
例如,y 和 z 是两个加法操作数,它们的类型不同,但由于 uint8 可以隐式转换为 uint16,而 uint16 不能隐式转换为 uint8,所以在运算执行前,y 会被转换为 z 的类型,即 uint16。由于整数与固定大小字节数组在截断和填充行为上的差异,只有在它们的大小相同的情况下,才允许二者之间进行显式转换。例如,uint8 可以转换为 uint16,int128 可以转换为 int256,但 int8 不能转换为 uint256,因为 uint256 无法表示负数(如 -1)。原创 2025-03-31 20:59:54 · 1048 阅读 · 0 评论 -
【区块链安全 | 第二十二篇】类型之字面量和基础类型之间的转换
注意:在 Solidity 0.8.0 版本之前,所有十进制或十六进制字面量都允许显式转换为整数类型。从 0.8.0 开始,显式转换的规则与隐式转换一致,仅当字面量的值在目标类型允许的范围内时,才允许转换。十六进制字面量只有在字节数恰好等于目标类型大小时,才能隐式转换。注意:在 0.8.0 版本之前,允许将任何整数类型(无论符号或大小)显式转换为地址或可支付地址。如“地址字面量”章节所述,符合大小并通过校验和检查的十六进制字面量被视为地址类型。除此之外,任何其他字面量都不能隐式转换为地址类型。原创 2025-03-31 21:03:09 · 313 阅读 · 0 评论 -
【区块链安全 | 第二十三篇】单位和全局可用变量(一)
数值字面量也可以使用时间单位后缀,包括 seconds、minutes、hours、days 和 weeks。这些单位以 seconds 为基础进行定义。这些单位在处理日历相关计算时可能产生误差,例如一年并不总是 365 天,且一天也不一定总是 24 小时(如遇闰秒)。由于闰秒无法预测,如需精确的日历计算,应使用外部预言机(oracle)提供的时间信息。原创 2025-03-31 21:10:34 · 407 阅读 · 0 评论 -
【区块链安全 | 第二十四篇】单位和全局可用变量(二)
然而,当 selfdestruct 在同一交易中被调用,并且创建了调用它的合约时,合约会依旧销毁,包括存储键、代码和合约本身,这一行为与 EVM <= Shanghai 时的行为一致。需要注意的是,该属性不能在合约本身或其任何派生合约中访问,因为这会导致字节码被包含在调用站点的字节码中,从而无法处理循环引用。.call(bytes memory) returns (bool, bytes memory) 进行低级 CALL,带有给定的有效载荷,返回成功状态和返回数据,转发所有可用的 gas,可以调节。原创 2025-03-31 21:37:48 · 1231 阅读 · 2 评论 -
【区块链安全 | 第二十五篇】表达式与控制结构(一)
函数调用时可以使用具名参数(Named Parameters),即将参数包裹在 {} 中,并通过名称传入。此时参数顺序可以任意,但名称必须与函数声明中的一致。函数声明中的参数名和返回值名可以省略。被省略的参数仍存在于栈中,但无法通过名称访问;而被省略名称的返回值仍然可以通过 return 语句返回给调用者。原创 2025-04-07 09:05:29 · 1304 阅读 · 0 评论 -
【区块链安全 | 第二十六篇】表达式与控制结构(二)
如果执行进入 catch 块,外部调用的状态更改效果已经被回滚。如果执行进入成功块,则效果不会回滚。如果效果已被回滚,执行要么继续在 catch 块中,要么整个 try/catch 语句会回滚(例如,由于解码失败或没有提供低级 catch 块)。try 关键字后必须跟一个外部函数调用或合约创建表达式(如 new ContractName())。表达式中的错误不会被捕获,只有外部调用内部发生的 revert 才会被捕获。returns 部分(可选)声明与外部调用返回类型匹配的返回变量。原创 2025-04-07 09:17:28 · 1186 阅读 · 0 评论 -
【区块链安全 | 第二十七篇】合约(一)
与存储不同,临时存储中的数据是短期有效的,仅在当前交易范围内存在,交易结束后,临时存储中的数据会被重置为零。另一个问题是,由于临时存储被设计为相对便宜的键值存储,智能合约开发者可能倾向于将临时存储用作内存映射的替代方案,而不跟踪映射中修改的键,这样就不会在调用结束时清除映射。通过这样的示例,可以看出 Solidity 中不同可见性说明符的作用:private 限制了函数的访问范围为当前合约内部,internal 使得函数在当前合约及其子合约中可访问,而 public 则使得函数可以在任何地方调用。原创 2025-04-07 09:27:09 · 1052 阅读 · 0 评论 -
【区块链安全 | 第二十八篇】合约(二)
合约可以使用布局说明符来定义其存储的任意位置。合约的状态变量,包括从基类继承的变量,将从指定的基础槽(base slot)开始,而不是默认的零槽。uint[3] x;// 占用槽 0xAABB..0xAABD如上例所示,布局说明符使用 layout at 语法,并位于合约定义的头部。布局说明符可以放在继承说明符之前或之后,并且最多只能出现一次。base-slot-expression 必须是一个整数文字表达式,可以在编译时求值,并且生成一个位于 uint256 范围内的值。原创 2025-04-07 09:46:59 · 1371 阅读 · 0 评论 -
【区块链安全 | 第二十九篇】合约(三)
在 Solidity 中,自定义错误提供了一种节省 gas 的方式,能够方便地向用户解释操作失败的原因。错误可以在合约内部或外部(包括接口和库)定义。自定义错误必须与 revert 语句或 require 函数一起使用。当 revert 语句或 require 判断条件为 false 时,当前调用中的所有更改都会被回滚,并且错误数据将被返回给调用者。/// 转账时余额不足。需要 `required`,但只可用 `available`。/// @param available 当前可用余额。原创 2025-04-07 11:16:48 · 1240 阅读 · 0 评论 -
【区块链安全 | 第三十篇】合约(四)
在这种情况下,当另一个合约继承时,继承列表或构造函数必须为所有尚未提供参数的基类提供所需的参数,否则该合约也必须声明为抽象合约。一种简化的方式来理解这一点是,当调用一个在多个合约中多次定义的函数时,Solidity 会从右到左(Python 中是从左到右)深度优先地搜索给定的基合约,直到找到第一个匹配的函数。当多个基合约定义了相同的虚拟函数时,派生合约可以选择性地重写这些函数,提供不同的实现方式。修饰符的重写是通过 override 关键字实现的,允许派生合约修改父合约中的修饰符行为,以适应不同的需求。原创 2025-04-07 11:25:22 · 1161 阅读 · 0 评论 -
【区块链安全 | 第三十一篇】合约(五)
这意味着,当调用库中的函数时,代码将在调用合约的上下文中执行,即 this 指向的是调用合约,特别是调用合约的存储会被访问。为了在 EVM 中实现这一点,所有从合约中调用的内部库函数以及所有从库中调用的函数,都将在编译时包含在调用合约中,并通过常规的 JUMP 调用,而不是 DELEGATECALL。如在介绍中所提到的,如果库的代码使用 CALL 而不是 DELEGATECALL 或 CALLCODE 执行,则除非调用的是 view 或 pure 函数,否则将会回退(revert)。原创 2025-04-07 11:29:47 · 1363 阅读 · 1 评论 -
【区块链安全 | 第三十二篇】内联汇编
此外,我们需要意识到,Solidity 中动态数组的默认值指向内存偏移量 0x60,因此,在暂时改变内存偏移量 0x60 的值时,我们将无法依赖读取动态数组时获得准确的长度值,直到我们恢复了 0x60 的零值。在内联汇编中,我们可以访问这些变量的内存地址,修改它们的值时需要特别小心,因为赋值操作只会更改指针地址,而不会直接改变数据。1.在汇编块结束时,空闲内存指针(偏移量为 0x40)恢复到一个合理的值(即,它要么恢复到原始值,要么因为手动内存分配而有所增加),并且偏移量 0x60 处的内存字恢复为零值。原创 2025-04-07 15:15:19 · 1067 阅读 · 0 评论 -
【区块链安全 | 第三十三篇】备忘单
声明该函数、修饰符或公共状态变量修改了基合约中的行为。返回当前交易中第 index 个 blob 的版本化哈希。该哈希由一个版本字节(当前为 0x01)和 KZG 承诺的 SHA256 哈希的后 31 字节组成(见 EIP-4844)。若该索引不存在对应 blob,则返回 0。原创 2025-04-07 16:02:10 · 1313 阅读 · 0 评论 -
【区块链安全 | 第三十四篇】合约审计之重入漏洞
1.攻击者首先调用 attack(),并向 EtherStore 合约发送 1 ETH。2.然后,Attack 合约将这 1 ETH 存入 EtherStore 合约。由于在 EtherStore 合约提款时,余额需大于0,因此需提前存入 1 ETH 满足提款条件,进而触发下文的第4点。3.紧接着,攻击者调用 Attack 合约中的 withdraw(),从 EtherStore 提取资金。原创 2025-04-07 19:38:49 · 1247 阅读 · 0 评论 -
【区块链安全 | 第三十五篇】溢出漏洞
1.部署 TimeLock 合约2.部署 Attack 合约3.在 Attack 合约的构造函数中传入已部署的 TimeLock 合约地址,完成初始化。4.调用 Attack.attack 函数在attack函数中,首先调用 TimeLock.deposit 向合约中存入 1 个以太币(或任意数量的 ETH)。此时,TimeLock 会将该 ETH 锁定一周,即设置 lockTime[msg.sender] = block.timestamp + 1 weeks。原创 2025-04-07 22:19:16 · 1459 阅读 · 0 评论 -
【区块链安全 | 第三十六篇】合约审计之自毁函数
使用 call 函数进行转账容易发生重入攻击,因为 call 是低级函数,call 在执行后会执行目标地址(msg.sender)的 fallback 或 receive 函数,即将控制权交给目标合约。自毁函数可以帮助他们在这种情况下有序地结束合约,并将合约中的资产转移到合适的地方,如转移到新的合约或项目中,或者返还给相关的用户或投资者。例如,一个记录用户交易历史的智能合约,随着时间的推移,早期的一些交易记录可能对于当前的业务逻辑来说已经不再重要,但它们仍然占据着链上的存储空间。原创 2025-04-08 09:36:53 · 1510 阅读 · 0 评论 -
【区块链安全 | 第三十七篇】合约审计之获取私有数据(一)
尽管地址看起来相同,但由于本地环境与主网并不共享状态,脚本实际读取的是主网上该地址的存储数据,而不是我们本地部署的合约数据。因此返回的是 0x0,而不是我们在本地设置的值。为了解决这一问题,Solidity 选择将长度单独存储在 slotA,而将实际的数据映射到从 keccak256(slotA) 开始的一段存储空间中,以避免与其他变量产生冲突,并实现灵活的数据扩展。需要注意的是,memory 中的数据不会被写入区块链,修改它也不会影响链上的状态,因此它适合用于函数内部的逻辑处理而非持久化存储。原创 2025-04-08 21:42:15 · 1350 阅读 · 0 评论 -
【区块链安全 | 第三十八篇】合约审计之获取私有数据(二)
从上述 Vault 合约代码可以看出,合约将用户的敏感信息(如用户名与密码)直接存储在链上。尽管使用了 private 关键字对变量进行了访问限制,但在区块链中,所有合约数据都是公开可见的。private 仅限制了其他合约或外部账户通过函数调用访问变量的能力,但无法阻止任何人通过读取链上存储数据(storage)来获取这些信息。原创 2025-04-08 22:37:16 · 1386 阅读 · 0 评论 -
【区块链安全 | 第三十九篇】合约审计之delegatecall(一)
1.当合约 B 使用 call 调用合约 A 的外部函数时,调用发生在合约 A 的上下文中,返回的结果来自合约 A 执行后的值,且不会影响合约 B 的存储。调用时,合约 B 的状态不会受到影响。2.当合约 B 使用 delegatecall 调用合约 A 的函数时,执行发生在合约 B 的上下文中,且所有的存储操作都会影响 B 合约的状态而非 A 合约。因此,B 合约的地址被赋值给了 a,而 A 合约的数据保持不变。原创 2025-04-12 18:39:37 · 1206 阅读 · 0 评论 -
【区块链安全 | 第四十篇】合约审计之delegatecall(二)
虽然执行的是库合约中的代码,但由于使用的是 delegatecall,所以代码是在 HackMe 合约的上下文中执行的,也就是说修改的是 HackMe 合约自身的存储槽。假设上面这段代码的 _someUserInput 是用户传进来的地址,此时攻击者可以传一个他部署的恶意合约地址进来,然后通过 delegatecall,在你的合约中执行他的恶意代码,直接改写你合约里的变量,比如 owner、余额等。当涉及 storage 变量的修改时,变量的赋值是基于存储插槽的位置(slot)而不是变量名进行的。原创 2025-04-12 21:27:51 · 1477 阅读 · 2 评论
分享