0

I have an auction contract, where bidders bid with Ether then me (owner) select which offer is most suitable and thus this bidder is contract winner.

Once the winner is selected, I send him data as a reward. My question here is, is there a way to ensure that I can use the ether until I send him the data?

In other words, what makes the bidder sure that I dont just take him Ether and dont send any data? Thus is there a way to lock the Ether for example till data is send.

Note, I sent him the data off-chain.

3 Answers 3

1

You can implement a (one-way, two-step) escrow that works like * you advertise some data, perhaps a zero-knowledge proof that you have it * buyer pays money into the escrow * you send data off-chain to buyer * buyer examines data and if satisfactory, releases the payment to you

Once the buyer commits their funds, there's no way for them to get it back, but they can withhold payment as leverage to make sure you provide the promised data.

In Solidity pseudo-code, it would look similar to

contract Escrow {

    mapping(address => uint256) public payments;
    mapping(address => uint256) public released;
    mapping(address => uint256) public transferred;
    address public owner;

    constructor() public {
        owner = msg.sender;
    }
    function payInto() payable {
        require(msg.value > 0, 'Sender attempted to pay zero amount.');
        require(payments[msg.sender] == 0, 'Sender previously paid into escrow.');
        payments[msg.sender] = msg.value;
    }

    function release() {
        require(payments[msg.sender] > 0, 'Sender has not paid into escrow.');
        require(released[msg.sender] == 0, 'Sender has already released funds.');
        released[msg.sender] = payments[msg.sender];
    }

    function safeWithdraw(address buyer) {
        require(msg.sender == owner, 'Non-owner tried to withdraw funds.');
        require(released[buyer] > 0, 'No released funds from buyer to withdraw.');
        require(transferred[buyer] == 0, 'Re-entrancy attempt during withdrawal.');
        transferred[buyer] = released[buyer];
        owner.transfer(released[buyer]);
    }
}
9
  • Thank you that really helped, there is something thats confusing me thought. Just to double confirm I understand the business concept. So for example x pays into the contract, I send him data off-chain. If convenient he releases the funds? How about the safe withdraw, why are we using it? So that x can withdraw the funds if data is not received? If so doesn't that leave him (x) here with funds and data received and me as owner sent data and have no funds. Thanks for your help again, and waiting for your feedback.
    – user51821
    Jun 16, 2019 at 18:28
  • I dont get how is Ether locked as well, doesn't the buy x already transfer the funds to the contract via deployment? How is it locked or me as the owner cant access it. May you kindly elaborate on this as well, many thanks again.
    – user51821
    Jun 16, 2019 at 18:45
  • waiting for your feedback
    – user51821
    Jun 17, 2019 at 21:34
  • Yes, the buyer releases the funds if they are satisfied with the data you've sent them. If not, you are incentivized to give them satisfaction / do customer support, otherwise you won't get your funds. They under no circumstances will ever get their funds back, so they have no incentive to lie.
    – Paul Pham
    Jun 19, 2019 at 0:37
  • The incentives are most effective when we have a marketplace with repeated buys/sells, reputation, as described in this cool web game ncase.me/trust Safe withdraw avoids re-entrancy (aka the DAO hack), so that you can't cheat and withdraw more than the buyer's amount. When I say "locked" I mean there are specific rules on who can withdraw the money (you) and when (after the buyer authorizes it.
    – Paul Pham
    Jun 19, 2019 at 0:38
0

I don't see any easy way to accomplish that in a trusted way.

One option is to lock the Ether until the receiver confirms that he has received the data but nothing guarantees that he ever confirms it even if he has received it. In general it is much easier to guarantee things when everything happens on-chain so you may want to consider adding the data on-chain. You could for example encrypt the data, add it on-chain and you get the Ether when you insert a working key to the contract. Although that might not be very easy to accomplish either (how to make sure the key is a correct key?).

You can possible cook up some sort of a scheme with zkSNARKs (https://ethresear.ch/t/zero-knowledge-proofs-starter-pack/4519) or something else complicated but as I said, I don't see any easy way to accomplish this. Maybe someone else has better ideas?

4
  • Thanks for your help, may I ask how can we lock Ether? Didnt try it before honestly.
    – user51821
    Jun 15, 2019 at 11:10
  • Another question please, lets say data is in-sensitive thus sent on chain with no encryption. How can I ensure that me as the owner cant use the Ether till the bidder receives this data. Many many thanks
    – user51821
    Jun 15, 2019 at 11:17
  • "locking" simply means that you can't take out the Ether - the contract has some check in place which only allows withdrawal if certain conditions are met. Jun 15, 2019 at 13:27
  • As for your other question: the moment you put something inside the blockchain everyone can read it. So you can't hide it on-chain until you get your Ether. Jun 15, 2019 at 13:28
0

I agree with Lauri's answer above. There is no easy way to do this because there is no guarantee that either party will perform their last confirmation transaction. Or, can you make them do?

One solution, out of the box, might help you. User needs to pay (lock) more than that he bid, for example say double the ethers he bade. He will get half of the amount if he confirms. The other half will go to you.

Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.