云计算百科
云计算领域专业知识百科平台

【区块链安全 | 第三十八篇】合约审计之获取私有数据(二)

文章目录

    • 前言
    • 漏洞代码
    • 代码审计
    • 攻击步骤
    • 修复/开发建议
    • 审计思路

在这里插入图片描述

前言

在【区块链安全 | 第三十七篇】合约审计之获取私有数据(一)中,介绍了私有数据、访问私有数据实例、Solidity 中的数据存储方式等知识,本文通过分析具体合约代码进行案例分析。

漏洞代码

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Vault {
// 公共变量,可以通过 getter 函数读取
// slot 0
uint public count = 123;

// 部署合约的地址会成为 owner
// slot 1
address public owner = msg.sender;

// 示例布尔值和 uint16 类型变量
// slot 1
bool public isTrue = true;
uint16 public u16 = 31;

// 私有密码变量,不能通过合约外部直接访问
// slot 2
bytes32 private password;

// 常量值,在部署时就固定,不可更改
// 编译时嵌入,不占 slot
uint public constant someConst = 123;

// 固定长度的 bytes32 数组,长度为 3
// slot 3、slot 4、slot 5
bytes32[3] public data;

// 用户结构体,包含用户 ID 和密码字段
struct User {
uint id;
bytes32 password;
}

// 用户动态数组,仅限内部访问
// slot 6
User[] private users;

// 映射:通过用户 ID 查找对应的用户结构体
mapping(uint => User) private idToUser;

// 构造函数,在部署时设置初始密码
constructor(bytes32 _password) {
password = _password;
}

// 添加新用户,自动分配 ID,并存储在数组和映射中
function addUser(bytes32 _password) public {
User memory user = User({
id: users.length,
password: _password
});

users.push(user);
idToUser[user.id] = user;
}

// 工具函数:用于计算数组中元素的 storage 位置
function getArrayLocation(
uint slot,
uint index,
uint elementSize
) public pure returns (uint) {
return uint(keccak256(abi.encodePacked(slot))) + (index * elementSize);
}

// 工具函数:用于计算映射中某个键的 storage 位置
function getMapLocation(uint slot, uint key) public pure returns (uint) {
return uint(keccak256(abi.encodePacked(key, slot)));
}
}

赞(0)
未经允许不得转载:网硕互联帮助中心 » 【区块链安全 | 第三十八篇】合约审计之获取私有数据(二)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!