Safe remote purchase escrow holding a double deposit from both sides
Context
Deployed in November 2015 during the Frontier period, when the Solidity documentation examples were the main source of contract code in circulation.
Key Facts
Description
An escrow for a remote sale. The seller deploys the contract with twice the item price, which the constructor halves and records as the value. A buyer locks the sale by sending the same doubled amount through confirmPurchase. Calling confirmReceived returns the buyer's deposit and pays the seller the rest, and refund lets the seller unwind a locked sale instead. State transitions are guarded by a three-value enum and by modifiers that restrict each call to the buyer or the seller. It is an edited copy of the safe remote purchase example from the Solidity documentation, with a refund path and capitalised events added.
Source Verified
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology and exact bytecode matching.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
contract Purchase {
uint public value;
address public seller;
address public buyer;
enum State { Created, Locked, Inactive }
State public state;
function Purchase() require(msg.value % 2 == 0) {
seller = msg.sender;
value = msg.value / 2;
}
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();
event Refunded();
function abort()
onlySeller
inState(State.Created)
{
seller.send(this.balance);
state = State.Inactive;
Aborted();
}
function confirmPurchase()
inState(State.Created)
require(msg.value == 2 * value)
{
buyer = msg.sender;
state = State.Locked;
PurchaseConfirmed();
}
function confirmReceived()
onlyBuyer
inState(State.Locked)
{
buyer.send(value);
seller.send(this.balance);
state = State.Inactive;
ItemReceived();
}
function refund()
onlySeller
inState(State.Locked)
{
buyer.send(2 * value);
seller.send(this.balance);
state = State.Inactive;
Refunded();
}
function() {
throw;
}
}External Links
Related contracts
MessageStore
Same eraA 6-line contract storing a single public string, deployed Day 9 of Ethereum by a prolific early experimenter who shipped 18 contracts in one week.
0xd2eccd...ff3d6bAugust 8, 2015Contract 0xa85146...9bbf06
Same erago-ethereum's built-in hash registrar, mapping a key to a content hash
0xa85146...9bbf06August 10, 2015Ballot
Same eraDelegated voting with a proposal count fixed at deployment
0x3cf26c...b6a8e1August 18, 2015Ballot
Same eraDelegated voting with a proposal count fixed at deployment
0x56ce77...b44745August 18, 2015Ballot
Same eraDelegated voting over five proposals, with the chairperson handing out voting rights
0x640fa6...b57e8aAugust 25, 2015Democracy
Same eraToken-weighted voting on proposals that execute a call when they pass
0x27fd1c...3f38b1August 25, 2015