Blockchain简单入门-NewStarCTF
字数 1451 2025-08-06 18:07:49
区块链智能合约入门与CTF实战指南
一、前置准备
1. MetaMask配置
- 安装:从谷歌商店下载MetaMask钱包
- 账户创建:按照步骤生成账户,务必牢记密码
- 测试网络配置:
- 默认不显示测试网络,需手动添加
- 选择Goerli测试网络(题目部署在此网络)
2. 开发工具准备
- Solidity学习资源:https://wtf.academy/solidity-start/HelloWeb3
- Goerli水龙头:https://goerlifaucet.com/(每日可领取0.1测试ETH)
- 合约反编译工具:https://ethervm.io/decompile
- 区块链浏览器:https://goerli.etherscan.io(查看交易和合约详情)
二、Solidity核心知识点
1. 关键语法
- memory:函数参数和临时变量使用,存储在内存中不上链
- address:
- 存储20字节的以太坊地址
- payable地址拥有balance和transfer()成员
- 函数声明:
function <name>(<params>) {visibility} [state] [returns (<types>)] {...}- 可见性:internal(默认)|external|public|private
- 状态修饰:pure|view|payable
2. 变量存储
- storage:合约状态变量,永久存储在链上
- 赋值规则:
- storage→storage:创建引用(修改相互影响)
- storage→memory:创建独立副本
- memory→memory:创建引用
- 其他→storage:创建独立副本
3. 特殊变量与修饰
- constant:声明时必须初始化,不可修改
- immutable:可在声明或构造函数中初始化
- constructor:部署时自动执行一次的特殊函数
- modifier:函数修饰器,常用于权限检查
modifier onlyOwner { require(msg.sender == owner); _; }
4. 事件(Event)
- EVM日志的抽象
- 声明方式:
event EventName(type1 param1, type2 param2); - 触发方式:
emit EventName(value1, value2);
三、CTF实战案例
案例1:Checkin签到题
题目分析
- 合约源码:
contract Checkin { string greeting; constructor(string memory _greeting) public { greeting = _greeting; } function setGreeting(string memory _greeting) public { greeting = _greeting; } function isSolved() public view returns (bool) { string memory key = "HelloNewstarCTF"; return keccak256(abi.encodePacked(key)) == keccak256(abi.encodePacked(greeting)); } }
解题步骤
- 获取部署账户和token
- 向部署账户转账0.001测试ETH
- 编写攻击合约:
contract exp { address transcation = 0x19b0a2c1335cb365696Aa660b4b8fe4c781b5E2B; Checkin target = Checkin(transcation); function hack() public returns (bool) { string memory greeting = "HelloNewstarCTF"; target.setGreeting(greeting); return target.isSolved(); } } - 部署攻击合约并调用hack()
- 提交token和交易哈希获取flag
案例2:Guess Number
题目分析
- 反编译关键代码:
contract guessnumber { mapping(address => uint) private answer; uint number; function guess(uint guess_number) public { answer[msg.sender] = guess_number; if(answer[msg.sender] == number) { emit isSolved(); } } function set_number(uint new_number) public onlyOwner { number = new_number; } }
解题步骤
- 通过区块链浏览器查看成功交易记录
- 获取正确的number值
- 编写攻击合约直接调用guess()传入正确数值
contract exp { address instance = 0x168d2A47c58ae63ea2a2A4c622259c84086f791D; guessnumber target = guessnumber(instance); function hack() public { target.guess(0x0000000000000000000000000000000000000000000675db03dcfd8684be44c6); } }
案例3:The Chosen One
题目分析
- 合约源码:
contract choose { address owner; function chooseone() public { require(uint(msg.sender) & 0xffff == 0xabcd); owner = msg.sender; } function getflag() onlyOwner { emit isSolved(); } }
解题步骤
- 使用地址生成工具创建以0xabcd结尾的地址
- 工具:https://vanity-eth.tk/
- 导入生成的账户到MetaMask
- 在Remix中直接与合约交互:
- 使用"At Address"连接题目合约
- 依次调用chooseone()和getflag()
- 提交token和交易哈希获取flag
四、实战技巧总结
-
合约交互流程:
- 获取题目合约地址
- 编写攻击合约或直接交互
- 支付Gas费用完成交易
-
常用工具链:
- Remix IDE:合约开发与测试
- Etherscan:交易和合约分析
- Ethervm:合约反编译
-
安全要点:
- 严格检查权限修饰符(onlyOwner等)
- 注意storage变量的引用特性
- 验证关键条件(如地址后缀检查)
-
调试技巧:
- 通过区块链浏览器分析成功交易
- 使用测试网络避免真实资金损失
- 利用事件日志追踪合约状态
通过掌握这些基础知识和实战技巧,可以系统性地解决区块链CTF题目,并深入理解智能合约的安全机制。