Created
December 3, 2023 09:49
-
-
Save partylikeits1983/1a23790254edc07a8fd8206a97777786 to your computer and use it in GitHub Desktop.
DelegatedSignature.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.22; | |
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; | |
contract DelegatedSignature { | |
// gameAddress => uint16 moves | |
mapping(address => uint16[]) public userData; // on chain data | |
// AUTHORIZE DELEGATED SIGNER FUNCTIONS | |
function getEthSignedMessageHash(bytes32 _messageHash) internal pure returns (bytes32) { | |
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _messageHash)); | |
} | |
function verifyDelegatedAddress( | |
bytes32 delegatedAddressBytes, | |
bytes memory signature, | |
address delegatorAddress, | |
address delegatedAddress | |
) public pure { | |
bytes32 delegatedAddressHash = hashDelegatedAddress(delegatedAddress); | |
require(delegatedAddressHash == delegatedAddressBytes); | |
bytes32 ethSignedMessageHash = getEthSignedMessageHash(delegatedAddressBytes); | |
require( | |
ECDSA.recover(ethSignedMessageHash, signature) == delegatorAddress, | |
"Delegated signature verification failed" | |
); | |
} | |
function encodeDelegation( | |
bytes32 delegatedAddressBytes, | |
bytes memory signature, | |
address delegatorAddress, | |
address delegatedAddress | |
) public pure returns (bytes memory) { | |
return abi.encode(delegatedAddressBytes, signature, delegatorAddress, delegatedAddress); | |
} | |
function decodeDelegation(bytes memory delegation) internal pure returns (bytes32, bytes memory, address, address) { | |
return abi.decode(delegation, (bytes32, bytes, address, address)); | |
} | |
function hashDelegatedAddress(address delegator) public pure returns (bytes32) { | |
return keccak256(abi.encodePacked(delegator)); | |
} | |
function verifyDelegation(bytes memory delegation) public pure returns (address, address) { | |
( | |
bytes32 delegatedAddressBytes, | |
bytes memory signature, | |
address delegatorAddress, | |
address delegatedAddress | |
) = decodeDelegation(delegation); | |
verifyDelegatedAddress(delegatedAddressBytes, signature, delegatorAddress, delegatedAddress); | |
return (delegatorAddress, delegatedAddress); | |
} | |
// DELEGATED SIGNER FUNCTIONS | |
function writeToStateOnBehalfOfDelegator( | |
bytes memory delegation, | |
bytes memory moveData, | |
bytes memory moveSignature | |
) public { | |
(, address delegatedAddress) = verifyDelegation(delegation); | |
(address gameAddress, uint16 move, uint gameNumber, uint expiration) = decodeMoveData(moveData); | |
bytes32 moveDataHash = hashMoveData(gameAddress, move, gameNumber, expiration); | |
verifyMove(moveDataHash, moveSignature, delegatedAddress); | |
uint moveLength = userData[gameAddress].length; | |
uint16[] memory newMoves = new uint16[](moveLength + 1); | |
newMoves[moveLength] = move; | |
userData[gameAddress] = newMoves; | |
} | |
function encodeMoveData( | |
address gameAddress, | |
uint16 move, | |
uint gameNumber, | |
uint expiration | |
) public pure returns (bytes memory) { | |
return abi.encode(gameAddress, move, gameNumber, expiration); | |
} | |
function decodeMoveData(bytes memory moveData) internal pure returns (address, uint16, uint, uint) { | |
return abi.decode(moveData, (address, uint16, uint, uint)); | |
} | |
function hashMoveData(address wager, uint16 move, uint moveNumber, uint expiration) public pure returns (bytes32) { | |
return keccak256(abi.encodePacked(encodeMoveData(wager, move, moveNumber, expiration))); | |
} | |
function verifyMove(bytes32 moveDataHash, bytes memory moveSignature, address delegatorAddress) internal pure { | |
bytes32 ethSignedMessageHash = getEthSignedMessageHash(moveDataHash); | |
require(ECDSA.recover(ethSignedMessageHash, moveSignature) == delegatorAddress, "invalid sig"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment