aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/examples/safe-remote.rst107
-rw-r--r--docs/solidity-by-example.rst108
2 files changed, 108 insertions, 107 deletions
diff --git a/docs/examples/safe-remote.rst b/docs/examples/safe-remote.rst
new file mode 100644
index 00000000..cfc63a24
--- /dev/null
+++ b/docs/examples/safe-remote.rst
@@ -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);
+ }
+ } \ No newline at end of file
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index ddead4d5..933b0765 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -5,113 +5,7 @@ Solidity by Example
.. include:: examples/voting.rst
.. include:: examples/blind-auction.rst
-.. 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);
- }
- }
+.. include:: examples/safe-remote.rst
********************
Micropayment Channel