mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #5785 from ethereum/docs-split-safe-remote
[DOCS] Split safe remote example into new file
This commit is contained in:
commit
af12697dda
107
docs/examples/safe-remote.rst
Normal file
107
docs/examples/safe-remote.rst
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
.. index:: purchase, remote purchase, escrow
|
||||||
|
|
||||||
|
********************
|
||||||
|
Safe Remote Purchase
|
||||||
|
********************
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
pragma solidity >=0.4.22 <0.6.0;
|
||||||
|
|
||||||
|
contract Purchase {
|
||||||
|
uint public value;
|
||||||
|
address payable public seller;
|
||||||
|
address payable public buyer;
|
||||||
|
enum State { Created, Locked, Inactive }
|
||||||
|
State public state;
|
||||||
|
|
||||||
|
// Ensure that `msg.value` is an even number.
|
||||||
|
// Division will truncate if it is an odd number.
|
||||||
|
// Check via multiplication that it wasn't an odd number.
|
||||||
|
constructor() public payable {
|
||||||
|
seller = msg.sender;
|
||||||
|
value = msg.value / 2;
|
||||||
|
require((2 * value) == msg.value, "Value has to be even.");
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier condition(bool _condition) {
|
||||||
|
require(_condition);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier onlyBuyer() {
|
||||||
|
require(
|
||||||
|
msg.sender == buyer,
|
||||||
|
"Only buyer can call this."
|
||||||
|
);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier onlySeller() {
|
||||||
|
require(
|
||||||
|
msg.sender == seller,
|
||||||
|
"Only seller can call this."
|
||||||
|
);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier inState(State _state) {
|
||||||
|
require(
|
||||||
|
state == _state,
|
||||||
|
"Invalid state."
|
||||||
|
);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
public
|
||||||
|
onlySeller
|
||||||
|
inState(State.Created)
|
||||||
|
{
|
||||||
|
emit Aborted();
|
||||||
|
state = State.Inactive;
|
||||||
|
seller.transfer(address(this).balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Confirm the purchase as buyer.
|
||||||
|
/// Transaction has to include `2 * value` ether.
|
||||||
|
/// The ether will be locked until confirmReceived
|
||||||
|
/// is called.
|
||||||
|
function confirmPurchase()
|
||||||
|
public
|
||||||
|
inState(State.Created)
|
||||||
|
condition(msg.value == (2 * value))
|
||||||
|
payable
|
||||||
|
{
|
||||||
|
emit PurchaseConfirmed();
|
||||||
|
buyer = msg.sender;
|
||||||
|
state = State.Locked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Confirm that you (the buyer) received the item.
|
||||||
|
/// This will release the locked ether.
|
||||||
|
function confirmReceived()
|
||||||
|
public
|
||||||
|
onlyBuyer
|
||||||
|
inState(State.Locked)
|
||||||
|
{
|
||||||
|
emit ItemReceived();
|
||||||
|
// It is important to change the state first because
|
||||||
|
// otherwise, the contracts called using `send` below
|
||||||
|
// can call in again here.
|
||||||
|
state = State.Inactive;
|
||||||
|
|
||||||
|
// NOTE: This actually allows both the buyer and the seller to
|
||||||
|
// block the refund - the withdraw pattern should be used.
|
||||||
|
|
||||||
|
buyer.transfer(value);
|
||||||
|
seller.transfer(address(this).balance);
|
||||||
|
}
|
||||||
|
}
|
@ -5,113 +5,7 @@ Solidity by Example
|
|||||||
.. include:: examples/voting.rst
|
.. include:: examples/voting.rst
|
||||||
.. include:: examples/blind-auction.rst
|
.. include:: examples/blind-auction.rst
|
||||||
|
|
||||||
.. index:: purchase, remote purchase, escrow
|
.. include:: examples/safe-remote.rst
|
||||||
|
|
||||||
********************
|
|
||||||
Safe Remote Purchase
|
|
||||||
********************
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
pragma solidity >=0.4.22 <0.6.0;
|
|
||||||
|
|
||||||
contract Purchase {
|
|
||||||
uint public value;
|
|
||||||
address payable public seller;
|
|
||||||
address payable public buyer;
|
|
||||||
enum State { Created, Locked, Inactive }
|
|
||||||
State public state;
|
|
||||||
|
|
||||||
// Ensure that `msg.value` is an even number.
|
|
||||||
// Division will truncate if it is an odd number.
|
|
||||||
// Check via multiplication that it wasn't an odd number.
|
|
||||||
constructor() public payable {
|
|
||||||
seller = msg.sender;
|
|
||||||
value = msg.value / 2;
|
|
||||||
require((2 * value) == msg.value, "Value has to be even.");
|
|
||||||
}
|
|
||||||
|
|
||||||
modifier condition(bool _condition) {
|
|
||||||
require(_condition);
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
modifier onlyBuyer() {
|
|
||||||
require(
|
|
||||||
msg.sender == buyer,
|
|
||||||
"Only buyer can call this."
|
|
||||||
);
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
modifier onlySeller() {
|
|
||||||
require(
|
|
||||||
msg.sender == seller,
|
|
||||||
"Only seller can call this."
|
|
||||||
);
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
modifier inState(State _state) {
|
|
||||||
require(
|
|
||||||
state == _state,
|
|
||||||
"Invalid state."
|
|
||||||
);
|
|
||||||
_;
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
public
|
|
||||||
onlySeller
|
|
||||||
inState(State.Created)
|
|
||||||
{
|
|
||||||
emit Aborted();
|
|
||||||
state = State.Inactive;
|
|
||||||
seller.transfer(address(this).balance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Confirm the purchase as buyer.
|
|
||||||
/// Transaction has to include `2 * value` ether.
|
|
||||||
/// The ether will be locked until confirmReceived
|
|
||||||
/// is called.
|
|
||||||
function confirmPurchase()
|
|
||||||
public
|
|
||||||
inState(State.Created)
|
|
||||||
condition(msg.value == (2 * value))
|
|
||||||
payable
|
|
||||||
{
|
|
||||||
emit PurchaseConfirmed();
|
|
||||||
buyer = msg.sender;
|
|
||||||
state = State.Locked;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Confirm that you (the buyer) received the item.
|
|
||||||
/// This will release the locked ether.
|
|
||||||
function confirmReceived()
|
|
||||||
public
|
|
||||||
onlyBuyer
|
|
||||||
inState(State.Locked)
|
|
||||||
{
|
|
||||||
emit ItemReceived();
|
|
||||||
// It is important to change the state first because
|
|
||||||
// otherwise, the contracts called using `send` below
|
|
||||||
// can call in again here.
|
|
||||||
state = State.Inactive;
|
|
||||||
|
|
||||||
// NOTE: This actually allows both the buyer and the seller to
|
|
||||||
// block the refund - the withdraw pattern should be used.
|
|
||||||
|
|
||||||
buyer.transfer(value);
|
|
||||||
seller.transfer(address(this).balance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
********************
|
********************
|
||||||
Micropayment Channel
|
Micropayment Channel
|
||||||
|
Loading…
Reference in New Issue
Block a user