Skip to content

Instantly share code, notes, and snippets.

@Austin-Williams
Last active August 29, 2015 14:23
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 Austin-Williams/ab782edda07d7d7f909f to your computer and use it in GitHub Desktop.
Save Austin-Williams/ab782edda07d7d7f909f to your computer and use it in GitHub Desktop.
A possible approach to storing reviews for completed OB transactions.
The approach of storing hashes of reviews in the btc BC and having Sellers (and possibly notaries) held accountable for hosting the reviews (and verifying that they are doing so honestly) has at least two difficulties.
The first is, 'how do we find all the review hashes for reviews of a given seller in the btc BC'?
The second is, How do we verify that the reviews are legitimate (came from the buyer listed in a completed OB Ricardian contract)? I hope to address both of these problems below.
The following approach to storing reviews is intended to (a) make it easy to find (hashes of) legitimate OB reviews in the btc BC and (b) impossible to inject (hashes of) false OB reviews directly into the BTC blockchain. A malicious seller could still create a bunch of notary/buyer sybils, create false trades, and leave reviews for himself that way. That's a separate problem.
The approach below requires each seller to have a dedicated btc address, SELLER_REVIEW_ADDRESS, that will be used for the review process. This address should be attached to the seller's pseudonymous identity permanently (perhaps, but not necessarily, generated deterministically from his GUID/OBprivKey).
BROAD STROKES:
The idea is that all buyer reviews of a seller will be OP_RETURNed in a transaction that contains SELLER_REVIEW_ADDRESS as one of its outputs.
This way any node can find a seller on OB, look up that seller's SELLER_REVIEW_ADDRESS on OB, and search the btc BC for all transactions that contain SELLER_REVIEW_ADDRESS as an output. Let's call this set of transactions 'SellerReviewDump'.
SellerReviewDump will contain (hashes of) all of that sellers' reviews. Note that SellerReviewDump could also contain a lot of other things (examples: hashes of *fake* reviews OP_RETURNed in transactions with SELLER_REVIEW_ADDRESS as one of it's outputs, meaningless transactions with no OP_RETURNED data, etc etc). SellerReviewDump will definitely contain *all* the transactions containing valid review hashes for the seller... we need only a way to determine which of these transactions was generated from an OB trade, and which ones were not.
When I say a transaction was "generated from an OB trade" I mean that there exists a completed Ricardian contract (signed by buyer, seller, and notary) that corresponds to that transaction.
FINER DETAILS:
I believe the following protocol would make the task of identifying which transactions in SellerReviewDump were generated from an OB trade, and which ones to ignore.
(1) Buyer, Seller, and Notary create a 2-of-3 multisig address, TRADE_ADDRESS.
(2) Seller sends a small payment (dust) from SELLER_REVIEW_ADDRESS to TRADE_ADDRESS. (explanation for why later)
(3) Buyer sends payment for goods to TRADE_ADDRESS.
(4) Physical goods are sent/received. At this point in protocol the Ricardian contract should be 'complete' -- in the sense that it's been signed with all required signatures and contains the complete transaction history. No further alterations/signatures should be added to the contract beyond this point. We'll call this completed contract the TRADERECEIPT.
(5) Buyer writes review, let's call it REVIEW and passes review to Seller.
(6) Seller checks review for appropriateness (doesn't contain spammy links, isn't 10TB, etc etc).
(7) If the review is appropriate, Seller creates and signs a transaction that consists of the single input TRADE_ADDRESS, and three outputs:
(Output 0) a small payment (dust) to SELLER_REVIEW_ADDRESS
(Output 1) the rest of the coins (less miner's fee) to sellers payout address as specified in the Ricardian contract
(Output 2) OP_RETURN the value sha256(TRADERECEIPT) XOR sha256(REVIEW)
(8) Seller passes this signed transaction to Buyer. Buyer verifies the outputs are correct and then signs and broadcasts the transaction to the btc network.
(9) Seller hosts both TRADERECEIPT and REVIEW indefinitely.
Now when a user discovers Seller's node, she looks up Seller's SELLER_REVIEW_ADDRESS, and scans the blockchain for all transactions with SELLER_REVIEW_ADDRESS as output. She calls this set of transactions SellerReviewDump. She removes from SellerReviewDump all transactions that do not contain any OP_RETURNed data, and removes all transactions with more than one input.
The remaining transactions in SellerReviewDump have only one input. For each of the remaining transactions, she checks the parent transaction of the single input to see whether it has SELLER_REVIEW_ADDRESS as an input (genuine OB transactions would because of Step (2) above), and throws out the transaction if it doesn't.
[You may think of Step (2) as the Seller saying "I agree to be held accountable for whatever review ends up coming out of this TRADE_ADDRESS I'm paying into." This prevents malicious players from attacking the Seller by creating btc transactions with SELLER_REVIEW_ADDRESS as an output, along with an OP_RETURN of uniform random bits, for which Seller could never provide the sha256 preimage]
What remains is a list of transactions which we'll call SellersBurden. It contains all the transactions with OP_RETURNed hashes for which the Seller must provide preimages. We know for sure that all reviews that resulted from *genuine* OB trades (that is, trades which correspond to completed OB Ricardian contracts) will be represented by hashes in SellersBurden. But there may also be other transactions that did not come from genuine OB trades (like if Seller tried to sneak in fake reviews), so we need to verify as follows.
For every OP_RETURNed hash in SellersBurden, Seller must provide both the TRADERECEIPT and the REVIEW. The challenging node computes sha256(TRADERECEIPT) XOR sha256(REVIEW) to make sure the hash matches (if not, penalize Seller with a lower trust/reputation). The challenger gets to see the TRADERECEIPT, and can thus verify everything (that the transaction was the result of a genuine OB trade, that the btc payout addresses/amounts match those in the contract, who the Notary was, that all signatures are correct, etc etc).
FINAL THOUGHTS:
This approach requires every OB trade involving a review to have it's contract become public -- so it's imperative that PID/sensitive info be blinded by default for all contracts.
If so desired, notaries can be also be held accountable for storing trade receipts and reviews by tying to every notary a NOTARY_REVIEW_ADDRESS and requiring the same behavior from notaries that we do from sellers w.r.t. Step (2) (and of course adding a 4th output in Step (7) that sends dust to NOTARY_REVIEW_ADDRESS).
If we want to rate sellers and notaries and buyers and products, we can do so all at once. Just OP_RETURN:
sha256(TRADERECEIPT) XOR sha256(BuyerReview) XOR sha256(SellerReview) XOR sha256(NotaryReveiw) XOR sha256(ProductReview)
and have the seller (and any other burden-bearing party) host the plaintext reviews.
This is a rough first-approach. We could fine tune something of this nature or take a completely different tack. I just thought it'd be good to get a few ideas out there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment