Last active
February 11, 2019 15:01
-
-
Save p3c-bot/b533413550da179c5e89da410aca3dd7 to your computer and use it in GitHub Desktop.
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
pragma solidity 0.4.21; | |
contract Escrow { | |
struct Job { | |
bool started; | |
bool complete; | |
bytes32 customerPasswordHash; | |
uint256 deadline; | |
uint256 price; | |
address provider; | |
address customer; | |
bytes32 oraclePasswordHash; | |
} | |
mapping(bytes32 => Job) public jobs; | |
event CreatedJob(bytes32 jobId); | |
event EvaluatedJob(bytes32 jobId, uint8 status); | |
// STATUS CODES: | |
// 0: SUCCESS, PROVIDER RETRIEVES FUNDS | |
// 1: TIMEOUT, CUSTOMER TAKES MONEY BACK | |
// 2: ORACLE PAYS PROVIDER, ORACLE CHOOSES TO PAY PROVIDER | |
// 3: ORACLE PAYS CUSTOMER, ORACLE CHOOSES TO REFUND CUSTOMER | |
function createJob(bytes32 jobId, bytes32 customerPasswordHash, uint256 expirationSeconds, address provider, address customer, bytes32 oraclePasswordHash) | |
public | |
payable { | |
require(jobs[jobId].started == false); | |
uint256 deadline = SafeMath.add(now, expirationSeconds); | |
Job memory newJob = Job(true, false, customerPasswordHash, deadline, msg.value, provider, customer, oraclePasswordHash); | |
jobs[jobId] = newJob; | |
emit CreatedJob(jobId); | |
} | |
// given a hash and the password, evaluate whether the job was completed. | |
function evaluateJob(bytes32 jobId, string customerPasswordUnhashed) | |
public | |
returns(uint8) { | |
Job storage currentJob = jobs[jobId]; | |
require(currentJob.started == true); | |
require(currentJob.complete == false); | |
// customer password should never be used again and generated randomly for each new job. | |
require(keccak256(customerPasswordUnhashed) == currentJob.customerPasswordHash); | |
currentJob.complete = true; | |
// job was completed successfully before the time out, and the customer wants to pay the provider | |
if(currentJob.deadline >= now){ | |
(currentJob.provider).transfer(currentJob.price); | |
emit EvaluatedJob(jobId, 0); | |
return 0; | |
// job has timed out and customer wants to get their money back. | |
} else { | |
(currentJob.customer).transfer(currentJob.price); | |
emit EvaluatedJob(jobId, 1); | |
return 1; | |
} | |
} | |
// oracle | |
function oracleEvaluateJob(bytes32 jobId, string oraclePasswordUnhashed, bool payProvider) | |
public | |
returns(uint8) { | |
Job storage currentJob = jobs[jobId]; | |
require(currentJob.started == true); | |
require(currentJob.complete == false); | |
// oracle password should never be used again and generated randomly for each new job. | |
require(keccak256(oraclePasswordUnhashed) == currentJob.oraclePasswordHash); | |
currentJob.complete = true; | |
// oracle wants to pay the provider | |
if(payProvider){ | |
(currentJob.provider).transfer(currentJob.price); | |
emit EvaluatedJob(jobId, 2); | |
return 2; | |
// oracle wants to give money back to customer | |
} else { | |
(currentJob.customer).transfer(currentJob.price); | |
emit EvaluatedJob(jobId, 3); | |
return 3; | |
} | |
} | |
} | |
library SafeMath { | |
/** | |
* @dev Adds two numbers, throws on overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
uint256 c = a + b; | |
assert(c >= a); | |
return c; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment