-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimplePurchaseAgreement.sol
98 lines (78 loc) · 3.22 KB
/
simplePurchaseAgreement.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
//contact : [email protected]
//crypto wallet : Fettah@crypto
// lets say there is 2 parites (buyer&Seller) that want to make a transaction
// buyer will put the money in the contract and the money will get locked . to make sure that the buyer is serious .
// seller as well will have to put the same amount to make sure he will not keep the buyer hanging.
// then when buyers confirms the transaction . buyer will have the option to release the money.
contract PurchaseAgreement {
// buyer adress , seller adress and the amount they agreed on.
uint public amount;
address payable public seller;
address payable public buyer;
enum State { Created, Locked, Release, Inactive }
State public agreementState;
// arrange permissions . with modifirers
/// Only the buyer can call this function.
error OnlyBuyer();
/// Only the seller can call this function.
error OnlySeller();
modifier onlyBuyer() {
if (msg.sender != buyer)
revert OnlyBuyer();
_;
}
modifier onlySeller() {
if (msg.sender != seller)
revert OnlySeller();
_;
}
// events to emit
event Aborted();
event PurchaseConfirmed();
event ItemReceived();
event SellerRefunded();
constructor() payable {
// seller initiate the contract and we wrote down who the seller is
seller = payable(msg.sender);
//and what the amount of the contract is
amount = msg.value;
}
// seller can cancel the contract before the buyer enters.
function abort() external
onlySeller
{
// in case of the agreementState being at Created only .
require(agreementState == State.Created);
emit Aborted();
agreementState = State.Inactive;
seller.transfer(address(this).balance);
// address(this) : return the adress of this contract.
// SOMEADRESS.balance : total balance for that adress.
// here we transfer all the balance of current contract to the seller because all the coins here came from the seller looking at the state of the contract.
}
// any one can join the fun and make the order by sending the amount needed
function confirmPurchase() external payable {
// the offer still on
require(agreementState == State.Created);
//he sent the right amount
require(msg.value == amount);
emit PurchaseConfirmed();
// save the adress of the new buyer
buyer = payable(msg.sender);
// change the state .
agreementState = State.Locked;
}
// when the buyer get his order he can call this function to close the agreement and send the money,
function confirmReceived() external
onlyBuyer
{
require(agreementState == State.Locked);
// the state of agreement is done
agreementState = State.Release;
// send the coins to the seller ... not this is x2 the amount .
// part seller paid as collateral other is what the buyer paid.
seller.transfer(address(this).balance);
}
}