Skip to content

Instantly share code, notes, and snippets.

@bl4ck5un
Created April 17, 2017 01:24
Show Gist options
  • Select an option

  • Save bl4ck5un/baea47b478218e5cc8d643a1b3fd74a0 to your computer and use it in GitHub Desktop.

Select an option

Save bl4ck5un/baea47b478218e5cc8d643a1b3fd74a0 to your computer and use it in GitHub Desktop.

Revisions

  1. fanz created this gist Apr 17, 2017.
    84 changes: 84 additions & 0 deletions Application.sol
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    contract Application {
    event Request(int64 requestId, address requester, uint dataLength, bytes32[] data);
    event Response(int64 requestId, address requester, uint64 error, uint data);
    event Cancel(uint64 requestId, address requester, bool success);

    uint constant MIN_GAS = 30000 + 20000;
    uint constant GAS_PRICE = 5 * 10 ** 10;
    uint constant TC_FEE = MIN_GAS * GAS_PRICE;
    uint constant CANCELLATION_FEE = 25000 * GAS_PRICE;

    bytes4 constant TC_CALLBACK_FID = bytes4(sha3("response(uint64,uint64,bytes32)"));

    TownCrier public TC_CONTRACT;
    address owner;
    address[2**64] requesters;
    uint[2**64] fee;

    function() public payable {} // must be payable

    function Application(TownCrier tcCont) public {
    TC_CONTRACT = tcCont;
    owner = msg.sender;
    }

    function request(uint8 requestType, bytes32[] requestData) public payable {
    if (msg.value < TC_FEE) {
    if (!msg.sender.send(msg.value)) {
    throw;
    }
    Request(-1, msg.sender, requestData.length, requestData);
    return;
    }

    uint64 requestId = TC_CONTRACT.request.value(msg.value)(requestType, this, TC_CALLBACK_FID, 0, requestData);
    if (requestId == 0) {
    if (!msg.sender.send(msg.value)) {
    throw;
    }
    Request(-2, msg.sender, requestData.length, requestData);
    return;
    }

    requesters[requestId] = msg.sender;
    fee[requestId] = msg.value;
    Request(int64(requestId), msg.sender, requestData.length, requestData);
    }

    function response(uint64 requestId, uint64 error, bytes32 respData) public {
    if (msg.sender != address(TC_CONTRACT)) {
    Response(-1, msg.sender, 0, 0);
    return;
    }

    address requester = requesters[requestId];
    requesters[requestId] = 0;

    if (error < 2) {
    Response(int64(requestId), requester, error, uint(respData));
    } else {
    requester.send(fee[requestId]);
    Response(int64(requestId), msg.sender, error, 0);
    }
    }

    function cancel(uint64 requestId) public {
    if (requestId == 0 || requesters[requestId] != msg.sender) {
    Cancel(requestId, msg.sender, false);
    return;
    }

    bool tcCancel = TC_CONTRACT.cancel(requestId);
    if (tcCancel) {
    requesters[requestId] = 0;
    if (!msg.sender.send(fee[requestId] - CANCELLATION_FEE)) {
    Cancel(requestId, msg.sender, false);
    throw;
    }
    Cancel(requestId, msg.sender, true);
    } else {
    Cancel (requestId, msg.sender, false);
    }
    }
    }