mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			104 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
pragma solidity >=0.0;
 | 
						|
import "../Oracles/Oracle.sol";
 | 
						|
 | 
						|
 | 
						|
/// @title Signed message oracle contract - Allows to set an outcome with a signed message
 | 
						|
/// @author Stefan George - <stefan@gnosis.pm>
 | 
						|
contract SignedMessageOracle is Oracle {
 | 
						|
 | 
						|
    /*
 | 
						|
     *  Events
 | 
						|
     */
 | 
						|
    event SignerReplacement(address indexed newSigner);
 | 
						|
    event OutcomeAssignment(int outcome);
 | 
						|
 | 
						|
    /*
 | 
						|
     *  Storage
 | 
						|
     */
 | 
						|
    address public signer;
 | 
						|
    bytes32 public descriptionHash;
 | 
						|
    uint nonce;
 | 
						|
    bool public isSet;
 | 
						|
    int public outcome;
 | 
						|
 | 
						|
    /*
 | 
						|
     *  Modifiers
 | 
						|
     */
 | 
						|
    modifier isSigner () {
 | 
						|
        // Only signer is allowed to proceed
 | 
						|
        require(msg.sender == signer);
 | 
						|
        _;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     *  Public functions
 | 
						|
     */
 | 
						|
    /// @dev Constructor sets signer address based on signature
 | 
						|
    /// @param _descriptionHash Hash identifying off chain event description
 | 
						|
    /// @param v Signature parameter
 | 
						|
    /// @param r Signature parameter
 | 
						|
    /// @param s Signature parameter
 | 
						|
    constructor(bytes32 _descriptionHash, uint8 v, bytes32 r, bytes32 s)
 | 
						|
    {
 | 
						|
        signer = ecrecover(_descriptionHash, v, r, s);
 | 
						|
        descriptionHash = _descriptionHash;
 | 
						|
    }
 | 
						|
 | 
						|
    /// @dev Replaces signer
 | 
						|
    /// @param newSigner New signer
 | 
						|
    /// @param _nonce Unique nonce to prevent replay attacks
 | 
						|
    /// @param v Signature parameter
 | 
						|
    /// @param r Signature parameter
 | 
						|
    /// @param s Signature parameter
 | 
						|
    function replaceSigner(address newSigner, uint _nonce, uint8 v, bytes32 r, bytes32 s)
 | 
						|
        public
 | 
						|
        isSigner
 | 
						|
    {
 | 
						|
        // Result is not set yet and nonce and signer are valid
 | 
						|
        require(   !isSet
 | 
						|
                && _nonce > nonce
 | 
						|
                && signer == ecrecover(keccak256(abi.encodePacked(descriptionHash, newSigner, _nonce)), v, r, s));
 | 
						|
        nonce = _nonce;
 | 
						|
        signer = newSigner;
 | 
						|
        emit SignerReplacement(newSigner);
 | 
						|
    }
 | 
						|
 | 
						|
    /// @dev Sets outcome based on signed message
 | 
						|
    /// @param _outcome Signed event outcome
 | 
						|
    /// @param v Signature parameter
 | 
						|
    /// @param r Signature parameter
 | 
						|
    /// @param s Signature parameter
 | 
						|
    function setOutcome(int _outcome, uint8 v, bytes32 r, bytes32 s)
 | 
						|
        public
 | 
						|
    {
 | 
						|
        // Result is not set yet and signer is valid
 | 
						|
        require(   !isSet
 | 
						|
                && signer == ecrecover(keccak256(abi.encodePacked(descriptionHash, _outcome)), v, r, s));
 | 
						|
        isSet = true;
 | 
						|
        outcome = _outcome;
 | 
						|
        emit OutcomeAssignment(_outcome);
 | 
						|
    }
 | 
						|
 | 
						|
    /// @dev Returns if winning outcome
 | 
						|
    /// @return Is outcome set?
 | 
						|
    function isOutcomeSet()
 | 
						|
        public
 | 
						|
        override
 | 
						|
        view
 | 
						|
        returns (bool)
 | 
						|
    {
 | 
						|
        return isSet;
 | 
						|
    }
 | 
						|
 | 
						|
    /// @dev Returns winning outcome
 | 
						|
    /// @return Outcome
 | 
						|
    function getOutcome()
 | 
						|
        public
 | 
						|
        override
 | 
						|
        view
 | 
						|
        returns (int)
 | 
						|
    {
 | 
						|
        return outcome;
 | 
						|
    }
 | 
						|
}
 |