CTNって?
CTF(Catch The Flag)のsolidity版(Ethernaut)です!(自分が名付けました笑)
Ethernautにある問題が例としてわかりやすいと思います。CTNを通して脆弱性やブロックチェーンの仕組みを学ぶことができます。とはいってもかなりハードルが高いのも事実で、JavascriptやSolidityができることが前提です…まず初めはHardhat tutorialをして環境を整えた後、Ethernautを解いてみることをお勧めします。
CTNラボとは
CTNラボはJPYC開発コミュニティで開催していたCTNを解いてみる会です。JPYC開発コミュニティはJPYCをはじめとするWeb3のエコシステム拡大を目的としていて継続的な勉強会をラボとして開催しています。頻度は基本、週に一回のペースでdisocord上で開催しています。興味がある方はこちらのリンクから参加できます!
ProxyMember
では早速、以下のコントラクトからNFTをゲットしてみてください!正攻法じゃないやり方も待っています!!
RinkebyScanのリンクはこちら
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface CTN_NFT {
function mint(string memory _name, uint256 _level, uint256 _ranking, address _to) external;
}
contract ProxyMember {
struct member {
address addr;
bytes32 key;
}
mapping(uint256 => member) private proxyMember;
address public implementation;
uint8 private ranking;
address[] private memberImplementation;
CTN_NFT nft;
constructor(address _implementation, address _nft) {
implementation = _implementation;
for(uint256 i=1; i<6; i++) {
(bool success, ) = implementation.delegatecall(
abi.encodeWithSignature("setId(uint256)", i)
);
if(!success) revert("fail delegateCall in constructor");
}
nft = CTN_NFT(_nft);
}
modifier onlyProxyMember(uint160 id) {
require(msg.sender == proxyMember[id].addr);
_;
}
function register(uint160 id, bytes32 key) external {
require(proxyMember[id].addr == address(0), "This id is already used");
require(proxyMember[id].key == key, "key is not valid");
proxyMember[id].addr = msg.sender;
}
function setImplementation(uint160 id) onlyProxyMember(id) external {
(bool success, ) = implementation.delegatecall(
abi.encodeWithSignature("setImplementation(uint160)", id)
);
if(!success) revert("fail delegateCall in setImplementation");
}
function getNFT(uint160 id, uint256 index) onlyProxyMember(id) external {
require(address(uint160(memberImplementation[index]) - id) == implementation, "index is valid");
ranking++;
nft.mint("ProxyMember", 5, ++ranking, tx.origin);
}
}