Skip to content

Instantly share code, notes, and snippets.

@dconroy
Created December 15, 2015 07:20
Show Gist options
  • Save dconroy/797c5509a608bcb2a575 to your computer and use it in GitHub Desktop.
Save dconroy/797c5509a608bcb2a575 to your computer and use it in GitHub Desktop.
Dual Escrow in Ethereum
contract Purchase
{
uint public value;
address public seller;
address public buyer;
enum State { Created, Locked, Inactive }
State public state;
function Purchase()
{
seller = msg.sender;
value = msg.value / 2;
if (2 * value != msg.value) throw;
}
modifier require(bool _condition)
{
if (!_condition) throw;
_
}
modifier onlyBuyer()
{
if (msg.sender != buyer) throw;
_
}
modifier onlySeller()
{
if (msg.sender != seller) throw;
_
}
modifier inState(State _state)
{
if (state != _state) throw;
_
}
event aborted();
event purchaseConfirmed();
event itemReceived();
/// Abort the purchase and reclaim the ether.
/// Can only be called by the seller before
/// the contract is locked.
function abort()
onlySeller
inState(State.Created)
{
aborted();
seller.send(this.balance);
state = State.Inactive;
}
/// Confirm the purchase as buyer.
/// Transaction has to include `2 * value` ether.
/// The ether will be locked until confirmReceived
/// is called.
function confirmPurchase()
inState(State.Created)
require(msg.value == 2 * value)
{
purchaseConfirmed();
buyer = msg.sender;
state = State.Locked;
}
/// Confirm that you (the buyer) received the item.
/// This will release the locked ether.
function confirmReceived()
onlyBuyer
inState(State.Locked)
{
itemReceived();
buyer.send(value); // We ignore the return value on purpose
seller.send(this.balance);
state = State.Inactive;
}
function() { throw; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment