詳解如何在以太坊智慧合約中整合可證明的Oracle-part3

買賣虛擬貨幣

1個函式 reclaimLeaseDeposit()  公開  {
2     租賃儲存租賃= tenantLease [msg.sender];
3     要求(lease.leaseFullyPaid,  “必須全額支付租賃費用才能收回租賃押金”);
4     require(lease.leaseDepositUsd>  0,  “租賃押金已被刪除”);
5
6     tenantAddress = msg.sender;
7     workingState = State.reclaimingLeaseDeposit;
8     fetchUsdRate();
9 }
10
11 函式 _reclaimLeaseDeposit()  內部  {
12     workingState = State.idle;
13     租賃儲存租賃= tenantLease [tenantAddress];
14     uint leaseDeposit = lease.leaseDepositUsd;
15     lease.leaseDepositUsd =  0 ;
16     tenantAddress.transfer(leaseDeposit.div(ETHUSD).mul(1E18));
17
18     發出leaseDepositReclaimed(
19         tenantAddress,
20         leaseDeposit
21     );
22 }

第1行例示了我們的public函式,用於替換租賃押金。租戶已全額付清租金,這函式由租戶呼叫。

第2-4行是重複邏輯。

第6-8行是重複邏輯。

第11行開始內部函式,以繼續重置租賃押金的過程。此函式的其餘部分是collectLeaseDeposit的重複邏輯。

1個函式 withdrawFunds()僅  公共 房東  {
2     要求(leaseBalanceWei>  0,  “租賃餘額必須大於0”));
3     uint transferAmount = leaseBalanceWei;
4     leaseBalanceWei =  0 ;
5     房東地址.transfer(transferAmount);
6
7     發出資金提取(
8         轉移        金額,
9租賃餘額魏
10     );
11 }
12
13 函式 getLease(地址租戶)  公共 檢視 返回  (
14     UINT8,
15     UINT8,
16     UINT16,
17     UINT16,
18     UINT32,
19     UINT64,
20     UINT64,
21     布林,
22     布林)  {
23     租賃儲存器租賃= tenantLease [租戶];
24     return  (
25         lease.numberOfMonths,
26         lease.monthsPaid,
27         lease.monthlyAmountUsd,
28         lease.leaseDepositUsd,
29         lease.leasePaymentWindowSeconds,
30        lease.leasePaymentWindowEnd,
31         lease.depositPaymentWindowEnd,
32         lease.leaseDepositPaid,
33         lease.leaseFullyPaid
34     );
35 }
36
37 函式 getRate()  公眾 視野 收益  (uint)  {
38     return  ETHUSD;
39 }
40
41 函式 getContractBalance()  公開 檢視 返回  (uint)  {
42     return  uint(address(this).balance);
43 }
44
45 功能()  外部 應付款項  {}

第1-11行是房東呼叫的用於提取租賃付款的函式。

第2行確保餘額大於0。

第3-5行顯示了與_collectLeaseDeposit和_reclaimLeaseDeposit相同的提款方式。智慧合約將餘額轉移給房東。

第7-10行發出了fundsWithdrawn事件。

第13–35行表示一個實用函式,用於在給定租戶地址的情況下檢索啟用租賃上的所有屬性。

第13-22行告訴函式它必須返回某些型別。

第23行提出了有問題的租約併為其分配給記憶體。不必預先為它準備儲存,只需要讀取它即可。

第24–34行告訴函式返回Lease物件上的所有屬性。

第37–39行是一個實用函式,用於檢索當前的ETHUSD匯率。

第41–43行宣告瞭另一個實用程式功能,以顯示智慧合約的當前餘額。為獲得餘額,我們必須將此(智慧合約例項)轉換為地址型別,然後從中讀取餘額。

最後,第45行是回退函式。中。

以下是完整的智慧合約程式碼:

1語用強度^ 0.5 .17 ;
2匯入  “ ./SafeMath.sol”;
3匯入  “ ./provableAPI.sol”;
4
5合同LeaseGenerator  正在  usingProvable {
6
7     使用  SafeMath  進行 uint ;
8
9     地址應付房東地址;
10個     地址的應付租戶地址;
11
12     UINT  ETHUSD;
13     uint  tenantPayment;
14     uint  leaseBalanceWei;
15
16    列舉  狀態{
17個         付費租賃存款,
18個         付費租賃,
19個         集合租賃存款,
20個         回收租賃存款,
21個         空閒
22     }
23
24     國家工作狀態;
25
26     struct  Lease {
27         uint8 numberOfMonths;
28         uint8個月有償;
29         uint16 monthAmountUsd;
30         uint16 leaseDepositUsd;
31         uint32 leasePaymentWindowSeconds;
32         uint64 leasePaymentWindowEnd;
33         uint64 depositPaymentWindowEnd;
34         bool  leaseDepositPaid;
35         bool  leaseFullyPaid;
36     }
37
38     對映(bytes32 =>  bool)validIds;
39     對映(address => Lease)tenantLease;
40
41     改性劑  onlyLandlord()  {
42         require(msg.sender == landlordAddress,  “必須是建立租賃的房東”));
43         _;
44     }
45
46     event  leaseCreated(
47         uint8 numberOfMonths,
48         uint8 monthsPaid,
49         uint16 monthAmountUsd,
50         uint16 leaseDepositUsd,
51         uint32 leasePaymentWindowSeconds,
52         bool  leaseDepositPaid,
53         bool  leaseFullyPaid
54    );
55
56項    活動 leaseDepositPaid(
57         地址tenantAddress,
58         uint  amountSentUsd
59    ) ;
60
61     event  leasePaymentPaid(
62         地址tenantAddress,
63         uint  amountSentUsd
64    ) ;
65
66     event  leaseDepositCollected(
67         address tenantAddress,
68         uint  amountCollected
69    ) ;
70
71     事件 leaseDepositReclaimed(
72        address tenantAddress,
73         uint  amountReclaimed
74    ) ;
75
76     事件 leaseFullyPaid(
77個         地址tenantAddress,
78個        UINT  NUMBEROFMONTHS,
79         UINT  monthsPaid
80    ) ;
81
82     事件 fundsWithdrawn(
83         UINT  transferAmount,
84         UINT  leaseBalanceWei
85    ) ;
86
87     建設者() 公共  應付款{
88            landlordAddress = msg.sender;
89             provable_setCustomGasPrice(100000000000);
90             OAR = OracleAddrResolverI(0xB7D2d92e74447535088A32AD65d459E97f692222);
91     }
92
93     函式  fetchUsdRate()  內部  {
94         require(provable_getPrice (“ URL”)<address(this).balance,“合同中沒有足夠的以太幣  ,請新增更多”));
95         位元組32 queryId = provable_query(“ URL”,  “ json(https://api.pro.coinbase.com/products/ETH-USD/ticker).price”);
96         validIds [queryId] =  true ;
97     }
98
99     函式__callback(bytes32 myId,  字串  儲存結果)  public  {
100         require(validIds [myId], “可提供的查詢ID不匹配,未對provable_query()進行有效呼叫”);
101         require(msg.sender == provable_cbAddress(),“使用可提供的合同地址,  呼叫地址確實匹配”);
102         validIds [myId] =  false ;
103         ETHUSD = parseInt(結果);
104
105         如果  (workingState == State.payingLeaseDeposit){
106             _payLeaseDeposit();
107         }  else  if  (workingState == State.payingLease){
108             _payLease();
109         }  else  if (workingState == State.collectingLeaseDeposit){
110             _collectLeaseDeposit();
111         }  else  if  (workingState == State.reclaimingLeaseDeposit){
112             _reclaimLeaseDeposit();
113         }
114     }
115
116     功能  createNewLease(
117個             UINT8 NUMBEROFMONTHS,
118             UINT16 monthlyAmountUsd,
119             UINT16 leaseDepositUsd,
120個             UINT32 leasePaymentWindowSeconds,
121個             UINT32 depositPaymentWindowSeconds,
122            地址應付tenantAddr
123        )  公共  onlyLandlord  {
124
125         UINT64 depositPaymentWindowEnd = UINT64(現。新增(depositPaymentWindowSeconds));
126
127         tenantLease [tenantAddr] =契(
128個             NUMBEROFMONTHS,
129             0,
130             monthlyAmountUsd,
131             leaseDepositUsd,
132個             leasePaymentWindowSeconds,
133             0,
134             depositPaymentWindowEnd,
135             假,
136             假,
137             錯誤
138         );
139
140         EMIT  leaseCreated(
141             NUMBEROFMONTHS,
142             0,
143             monthlyAmountUsd,
144             leaseDepositUsd,
145個             leasePaymentWindowSeconds,
146             假,
147             假,
148             虛假
149        ) ;
150     }
151
152     功能  payLeaseDeposit()  公共  應付款  {
153         租賃儲存租賃= tenantLease [msg.sender];
154         require(!lease.leaseDepositPaid,  “已支付租賃押金。”);
155         require(lease.depositPaymentWindowEnd> =現在,  “租賃押金必須適合支付視窗”);
156
157         tenantAddress = msg.sender;
158         tenantPayment =訊息 價值 ;
第159         章
160         fetchUsdRate();
161     }
162
163     功能_payLeaseDeposit() 內部  {
164         workingState = State.idle;
165         租賃儲存租賃= tenantLease [tenantAddress];
166         UINT  amountSentUsd = tenantPayment.mul(ETHUSD).div(1E18);
167
168         要求(
169             amountSentUsd> = lease.leaseDepositUsd -  5  &&
170             amountSentUsd <= lease.leaseDepositUsd +  5,
171             “存款支付必須等於到存款金額,最大的$ 5偏移量”);
172
173         lease.leaseDepositPaid =  真 ;
174        lease.depositPaymentWindowEnd =  0 ;
(175)第175         章
176
177         EMIT  leaseDepositPaid(
178個             tenantAddress,
179             amountSentUsd
180        ) ;
181     }
182個
183     功能  payLease()  公共  應付款  {
184         租賃儲存租賃= tenantLease [msg.sender];
185         require(lease.leaseDepositPaid,  “必須在支付租賃款項之前支付租賃押金”);
186         require(!lease.leaseFullyPaid,  “租賃已經全額支付”);
187         require(lease.leasePaymentWindowEnd> =現在,  “租賃付款必須適合付款視窗”);
188
189         tenantAddress = msg.sender;
190         tenantPayment =訊息 價值 ;
191         workingState = State.payingLease;
192        fetchUsdRate();
193     }
194
195     函式_payLease()  內部  {
196         workingState = State.idle;
197         租賃儲存租賃= tenantLease [tenantAddress];
198         UINT  amountSentUsd = tenantPayment.mul(ETHUSD).div(1E18);
199
200         要求(
201             amountSentUsd> = lease.monthlyAmountUsd -  5,
202             “租賃付款必須大於或等於每月量與最大的$ 5偏移量”);
203
204         UINT monthsPaid = uint256(lease.monthsPaid)。新增(amountSentUsd。新增(10).div(uint256(lease.monthlyAmountUsd)));
205         lease.monthsPaid = uint8(monthsPaid);
206         leaseBalanceWei = leaseBalanceWei。新增(tenantPayment);
207
208         如果  (monthsPaid == lease.numberOfMonths){
209             lease.leaseFullyPaid =  真 ;
210             lease.leasePaymentWindowEnd =  0 ;
211
212             發出  leaseFullyPaid(
213                 租戶地址
214                lease.numberOfMonths,
215個月                 支付
216            ) ;
217         }  else  {
218             lease.leasePaymentWindowEnd = lease.leasePaymentWindowEnd + lease.leasePaymentWindowSeconds;
219
220             EMIT  leasePaymentPaid(
221個                 tenantAddress,
222                 amountSentUsd
223            ) ;
224         }
225     }
226
227     函式  collectLeaseDeposit(應付地址tenantAddr)  公共 onlyLandlord  {
228         租賃儲存租賃= tenantLease [tenantAddr];
229         require(!lease.leaseFullyPaid,  “如果已經支付了租賃費用,則無法收取租賃保證金”);
230         require(lease.leasePaymentWindowEnd <=現在,  “租賃付款必須在付款視窗之後過期才能收取租賃押金”);
231         require(lease.leaseDepositUsd>  0,  “租賃押金已被刪除”);
232
233         tenantAddress = tenantAddr;
234         =狀態.State.collectingLeaseDeposit;
第235         章
236    }
237
238     功能_collectLeaseDeposit()  內部  {
239         workingState = State.idle;
240         租賃儲存租賃= tenantLease [tenantAddress];
241         uint  leaseDeposit = lease.leaseDepositUsd;
242         lease.leaseDepositUsd =  0 ;
243         landlordAddress.transfer(leaseDeposit.div(ETHUSD).mul(1E18));
244
245         EMIT  leaseDepositCollected(
246個             tenantAddress,
247             leaseDeposit
248        ) ;
249    }
250
251     功能  reclaimLeaseDeposit()  公共  {
252         租賃儲存租賃= tenantLease [msg.sender];
253         require(lease.leaseFullyPaid,  “必須全額支付租賃押金才能收回租賃押金”);
254         require(lease.leaseDepositUsd>  0,  “租賃押金已被刪除”);
255
256         tenantAddress = msg.sender;
257         ==== State.reclaimingLeaseDeposit;
258         fetchUsdRate();
259     }
260
261     功能_reclaimLeaseDeposit()  內部  {
262        workingState = State.idle;
263         租賃儲存租賃= tenantLease [tenantAddress];
264         uint  leaseDeposit = lease.leaseDepositUsd;
265         lease.leaseDepositUsd =  0 ;
266         tenantAddress.transfer(leaseDeposit.div(ETHUSD).mul(1E18));
267
268         EMIT  leaseDepositReclaimed(
269個             tenantAddress,
270             leaseDeposit
271        ) ;
272     }
273
274     函式  withdrawFunds()僅  公開  給房東  {
275         require(leaseBalanceWei>  0,  “租賃餘額必須大於0”);
276         uint  transferAmount = leaseBalanceWei;
277         leaseBalanceWei =  0 ;
278         landlordAddress.transfer(transferAmount);
279
280         EMIT  fundsWithdrawn(
281             transferAmount,
282             leaseBalanceWei
283        ) ;
284     }
285
286     功能  getLease(地址租戶)  公共  檢視  返回  (
287         UINT8,
288         UINT8,
289         UINT16,
290         UINT16,
291         UINT32,
292         UINT64,
293         UINT64,
294         布林,
295         布林,
296         布林)  {
297         租賃儲存器租賃= tenantLease [租戶];
298         返回  (
299             lease.NumberOfMonths,
300             lease.monthsPaid,
301            lease.monthlyAmountUsd,
302             lease.leaseDepositUsd,
303             lease.leasePaymentWindowSeconds,
304             lease.leasePaymentWindowEnd,
305             lease.depositPaymentWindowEnd,
306             lease.leaseDepositPaid,
307             lease.leaseFullyPaid,
308     }
309
310     函式  getRate()  公眾  意見  返回  (uint)  {
311         return  ETHUSD;
312     }
313
314     功能  getContractBalance()  公開  檢視  返回  (uint)  {
315         return  uint(address(this).balance);
316     }
317
318     function()外部應付款{}
319 }

現在我們已經完成了智慧合約程式碼編寫,我們可以實操看看它的實際效果。

在本教程的最後一部分中,我們將介紹如何執行測試並檢測它們是否透過。

最初是在終端中執行npm run chain。您會注意到我們將每個帳戶的初始餘額設定為10000 ETH。這是因為在測試中會花費了大量ETH的地址的場景中進行迭代。 cli執行後,執行npm run bridge。當bridge完成啟動後,可以顯示一條訊息。

1請將此行新增  到  您的合同  建構函式中:
2 OAR = OraclizeAddrResolverI(0 x6f485C8BF6fc43eA212E93BBF8ce046C7f1cb475);

複製顯示的地址替換其貼上到LeaseGenerator.sol的建構函式中。

在終端中,執行truffle進行測試。 ,,進入執行bridge的終端視窗。在這裡,我們可以看到所有請求都已傳送,並在測試執行時實時返回結果。ganache視窗還在處理過程中快速顯示交易。

我建議所有讀者檢視/tests/leaseGenerator.test.js中的內容,看看這些測試是如何實現的。它顯示了我們如何處理智慧合約互動中涉及的大量非同步活動。

該應用程式還不是很完美。可能存有很多不足,無法解決某些現實生活中的情況。但是如果區塊鏈技術成為主流的話,那麼將來如何處理房東與租戶的關係是很有趣。最後感謝大家的耐心閱讀,謝謝。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;