Comments and reorg for hackathon / readability
parent
db60d71f1b
commit
9478c0fc25
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue