forked from CCTF/DCTF
1
0
Fork 0

Comments and reorg for hackathon / readability

main
six 2023-08-24 04:59:43 +00:00
parent db60d71f1b
commit 9478c0fc25
1 changed files with 25 additions and 14 deletions

View File

@ -37,7 +37,7 @@ contract CryptoCTFX {
} }
struct Challenge { struct Challenge {
address obscuredFlag; // essentially the public key of the flag, the flag being a private key address obscuredFlag; // Essentially the public key of the flag, the flag being a private key
uint worth; uint worth;
uint256 descriptionFingerprint; uint256 descriptionFingerprint;
bool onlyFirstSolver; bool onlyFirstSolver;
@ -59,26 +59,38 @@ contract CryptoCTFX {
event ChallengeAddedOrUpdated(uint contestID, uint indexed challengeID); event ChallengeAddedOrUpdated(uint contestID, uint indexed challengeID);
event ChallengeSolved(uint contestID, uint indexed challengeID, address indexed solver); event ChallengeSolved(uint contestID, uint indexed challengeID, address indexed solver);
/* CTF Manager functions */
// 1. Create a contest
function createContest(uint contestID, string memory password) external { function createContest(uint contestID, string memory password) external {
require(contests[contestID].admin == address(0), "This contest ID has already been registered"); require(contests[contestID].admin == address(0), "This contest ID has already been registered");
contests[contestID].admin = msg.sender; contests[contestID].admin = msg.sender;
contests[contestID].password = password; contests[contestID].password = password;
} }
// 2. Set the contest's deadline
function setContestDeadline(uint contestID, uint256 deadline) external onlyExistingContest(contestID) onlyAdmin(contestID) {
contests[contestID].deadline = deadline;
}
// 3. Add the public keys of the challenges and their relevant data
function addOrUpdateChallenge(uint contestID, uint challengeID, address obscuredFlag, uint worth, uint256 descriptionFingerprint, bool onlyFirstSolver, string memory skill) external onlyExistingContest(contestID) onlyAdmin(contestID) {
require(obscuredFlag != address(0), "The obscured flag value must not be 0");
contests[contestID].challenges[challengeID] = Challenge(obscuredFlag, worth, descriptionFingerprint, onlyFirstSolver, skill);
emit ChallengeAddedOrUpdated(contestID, challengeID);
}
function setPlayerStatus(uint contestID, address player, PlayerStatus status) external onlyExistingContest(contestID) onlyAdmin(contestID) {
contests[contestID].players[player].status = status;
}
function setAdmin(uint contestID, address newAdmin) external onlyExistingContest(contestID) onlyAdmin(contestID) { function setAdmin(uint contestID, address newAdmin) external onlyExistingContest(contestID) onlyAdmin(contestID) {
require(newAdmin != address(0)); require(newAdmin != address(0));
contests[contestID].admin = newAdmin; contests[contestID].admin = newAdmin;
} }
function setContestDeadline(uint contestID, uint256 deadline) external onlyExistingContest(contestID) onlyAdmin(contestID) {
contests[contestID].deadline = deadline;
}
function addOrUpdateChallenge(uint contestID, uint challengeID, address obscuredFlag, uint worth, uint256 descriptionFingerprint, bool onlyFirstSolver, string memory skill) external onlyExistingContest(contestID) onlyAdmin(contestID) { /* CTF Player functions */
require(obscuredFlag != address(0), "The obscured flag value must not be 0");
contests[contestID].challenges[challengeID] = Challenge(obscuredFlag, worth, descriptionFingerprint, onlyFirstSolver, skill);
emit ChallengeAddedOrUpdated(contestID, challengeID);
}
function register(uint contestID, string memory password) external onlyExistingContest(contestID) { function register(uint contestID, string memory password) external onlyExistingContest(contestID) {
require(contests[contestID].players[msg.sender].status == PlayerStatus.Unverified, "You are already registered or banned in this contest"); require(contests[contestID].players[msg.sender].status == PlayerStatus.Unverified, "You are already registered or banned in this contest");
@ -86,10 +98,7 @@ contract CryptoCTFX {
contests[contestID].players[msg.sender].status = PlayerStatus.Verified; contests[contestID].players[msg.sender].status = PlayerStatus.Verified;
} }
function setPlayerStatus(uint contestID, address player, PlayerStatus status) external onlyExistingContest(contestID) onlyAdmin(contestID) { // You can use six's eth_keygen to generate the signature
contests[contestID].players[player].status = status;
}
function submitFlag(uint contestID, uint challengeID, bytes memory signature) external onlyExistingContest(contestID) onlyExistingChallenge(contestID, challengeID) onlyOpen(contestID) { function submitFlag(uint contestID, uint challengeID, bytes memory signature) external onlyExistingContest(contestID) onlyExistingChallenge(contestID, challengeID) onlyOpen(contestID) {
require(contests[contestID].players[msg.sender].status == PlayerStatus.Verified, "You are unverified or banned in this contest"); require(contests[contestID].players[msg.sender].status == PlayerStatus.Verified, "You are unverified or banned in this contest");
// the correct signature is an ECDSA signature where (1) the message (hash) is the sender address and (2) the private key is the flag; // the correct signature is an ECDSA signature where (1) the message (hash) is the sender address and (2) the private key is the flag;
@ -108,6 +117,7 @@ contract CryptoCTFX {
emit ChallengeSolved(contestID, challengeID, msg.sender); emit ChallengeSolved(contestID, challengeID, msg.sender);
} }
/* CTF ECDSA related functions */
function recoverSigner(bytes32 messageHash, bytes memory signature) public pure returns (address) { function recoverSigner(bytes32 messageHash, bytes memory signature) public pure returns (address) {
(bytes32 r, bytes32 s, uint8 v) = splitSignature(signature); (bytes32 r, bytes32 s, uint8 v) = splitSignature(signature);
return ecrecover(messageHash, v, r, s); return ecrecover(messageHash, v, r, s);
@ -122,6 +132,7 @@ contract CryptoCTFX {
} }
} }
/* CTF View functions for feedback and FE */
function getContestDeadline(uint contestID) external view onlyExistingContest(contestID) returns (uint256) { function getContestDeadline(uint contestID) external view onlyExistingContest(contestID) returns (uint256) {
return contests[contestID].deadline; return contests[contestID].deadline;
} }
@ -133,4 +144,4 @@ contract CryptoCTFX {
function getPlayerScore(uint contestID, address player) external view onlyExistingContest(contestID) returns (uint) { function getPlayerScore(uint contestID, address player) external view onlyExistingContest(contestID) returns (uint) {
return contests[contestID].players[player].score; return contests[contestID].players[player].score;
} }
} }