Skip to content

Instantly share code, notes, and snippets.

@amiller
Created June 19, 2023 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amiller/2c7914959bd41537089256348ff290de to your computer and use it in GitHub Desktop.
Save amiller/2c7914959bd41537089256348ff290de to your computer and use it in GitHub Desktop.
Off-chain linear scan ORAM token
Struct AddrBal = { address addr; uint balance };
enum RequestType = { TRANSFER; DEPOSIT; WITHDRAW };
Struct Request = { RequestType type, address from; address to; uint amt; bytes32 memo }
Struct Response = { uint seqNo, bool status, uint amt, string response };
contract {
// Key for encryption
bytes32 key;
// Checkpoint public state
AddrBal[] checkpoint public;
uint checkpointSeq public;
// List of pending commands (public is only allowed to read the type, sender)
Request[] requests;
function getRequest(uint seqno) returns (RequestType type, from);
// Processed responses (will always be <= size of requests)
Response[] responses public;
////////////// Submitting requests
event RequestSubmitted(RequestType type, address from, uint seqno);
function submitDepositRequest() payable public {
requests.push(Request(DEPOSIT, msg.sender, address(0), “”);
Emit RequestSubmitted(DEPOSIT, msg.sender, requests.length);
}
function submitXferRequest(addr to, uint amount, bytes32 memo) {
requests.push(Request(TRANSFER, msg.sender, to, amount, memo);
emit RequestSubmitted(TRANSFER, msg.sender, requests.length);
}
function submitWdrawRequest(uint amt) {
requests.push(Request(WITHDRAW, msg.sender, address(0), “”);
emit RequestSubmitted(WITHDRAW, msg.sender, requests.length);
}
///////////////////////// Interface between on-chain and off-chain
function getCheckpoint() returns(bytes) view {
ciph = oasis.encrypt( checkpointSeq, checkpoint, tag=”checkpoint”)
return ciph;
}
event ResponseCommitted(Response resp);
function commitResponse(bytes ciph) public {
// This is automatically checking authentication
Response resp = oasis.decrypt(key, ciph, tag=Response);
require(resp.seqNo == responses.length + 1); // Processes strictly in order
responses.push(resp);
Request request = requests[resp.seqNo];
If (request.type == DEPOSIT) {
} else if (request.type == TRANSFER) {
} else if (request.type == WITHDRAW) {
Address addr = request.from;
transfer(addr, resp.amt);
}
emit ResponseCommitted(resp);
}
function writeCheckpoint(bytes ciph) {
// Decryption is automatically checking a MAC, this is authenticated encryption
(newSeq, newCheckpoint) := oasis.decrypt(key, ciph, tag=Checkpoint)
require(newSeq >= checkpointSeq);
checkpointSeq = newSeq;
checkpoint = newCheckpoint;
}
///////////// Off-chain computation
function processNext(bytes ciph) returns(bytes newciph, bytes respciph) public view {
(oldSeq, checkpoint) = oasis.decrypt(key, ciph, tag=”checkpoint”)
seqNo = oldSeq+1;
Request req = requests[seqNo];
Response r;
If (req.type == TRANSFER) {
bool balanceOk = True;
For (uint i = 0; i < checkpoint.length; i++) {
bool b = (checkpoint[i].addr == req.from);
balanceOk &= (!b or checkpoints[i].balance >= req.amt));
checkpoints[i].balance -= (req.amt) * (b * balanceOk);
}
For (uint i = 0; i < checkpoint.length; i++) {
bool b = (checkpoint[i].addr == req.from to);
checkpoints[i].balance += (req.amt) * b * balanceOK;
}
r = Response(seqNo, balanceOk, 0, “xfer ok”);
} else if (req.type == DEPOSIT) {
For (uint i = 0; i < checkpoint.length; i++) {
bool b = (checkpoint[i].addr == req.from);
checkpoints[i].balance += (req.amt) * b
}
r = Response(seqNo, True, 0, “”);
} else if (req.type == WITHDRAW) {
bool balanceOk = True;
For (uint i = 0; i < checkpoint.length; i++) {
bool b = (checkpoint[i].addr == req.from);
balanceOk &= (!b or checkpoints[i].balance >= req.amt));
checkpoints[i].balance -= (req.amt) * (b * balanceOk);
}
r = Response(seqNo, balanceOk, req.amt * balanceOk, “”);
}
newciph = oasis.encrypt(key, checkpointSeq+1, checkpoint, tag=”checkpoint”)
respciph = oasis.encrypt(key, checkpointSeq+1, resp)
return (newciph, respciph)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment