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

在这里插入图片描述

前言

【区块链安全 | 第三十七篇】合约审计之获取私有数据(一)中,介绍了私有数据、访问私有数据实例、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)));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋说

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值