Skip to content

Instantly share code, notes, and snippets.

@p3c-bot
Last active February 11, 2019 15:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save p3c-bot/b533413550da179c5e89da410aca3dd7 to your computer and use it in GitHub Desktop.
Save p3c-bot/b533413550da179c5e89da410aca3dd7 to your computer and use it in GitHub Desktop.
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