第16行使ID无效,因此其他查询不能再次利用它。
第19-22行发出了leaseDepositCollected事件。第8行provable_getPrice(“ URL”)要求Provable计较并返回从Web URL检索外部资源所需的gas量。我们利用require来确保智能合约中有足够的余额来付出该用度。
7function fetchUsdRate() internal {
第13至28行是我们对Provable的_callback()的实现。第一个参数是查询发生的ID。第二个是string的查询实际功效。要害字memory用于在函数运行期间将字符串存储在内存中,而不是将其写入存储区,这样更节减了gas。
它是果真的,因此可以从外部以太坊帐户和onlylandord执行,因此只有房东的地点可以挪用它。
63 );
22 uint monthsPaid = uint256(lease.monthsPaid).add(amountSentUsd.add(10).div(uint256(lease.monthlyAmountUsd)));
28}
15 require(msg.sender == provable_cbAddress(), “Calling address does match usingProvable contract address “);
1. numberOfMonths:租约的期限,以月为单元
54 “Deposit payment must equal to the deposit amount with a maximum offset of $5”);
第51–54行确保以美元发送的金额与租赁的leaseDepositUsd相匹配。我们通过添加5美元的抵消额来办理ETH价值的快速颠簸。譬喻假如leaseDepositUsd是$500,则amountSendUsd的可接管值范畴是$495–$505。
第47行将状态重置为idle状态。
第9行provable_query汇报Provable用给定的端点执行查询,在我们的例子中,这是Coinbase的ETH/USD价值报价器。这将返回一个新的查询ID,我们将其添加到第10行的validIds中。
33}
43}
26 if (monthsPaid == lease.numberOfMonths) {
22 );
“Lease deposit payment must fit into payment window”);
50
24 leaseBalanceWei = leaseBalanceWei.add(tenantPayment);
15 Lease storage lease = tenantLease[tenantAddress];
61 tenantAddress,
7 address payable tenantAddr
40 tenantAddress = msg.sender;
第19–27行是一系列依赖于workState值的条件语句,该值由名为fetchUsdRate()的给定函数配置。我们还没有实施这些法子。
11
12 tenantLease[tenantAddr] = Lease(
30 false,
第56行将租约的押金付出标志为已付出。
47 workingState = State.idle;
46function _payLeaseDeposit() internal {
第57行重置存款的付款窗口竣事,因为它已经付出。
27 monthlyAmountUsd,
“Lease payment must fit into payment window”);
5}
第58行划定了实际每月租赁付款的付款期限,该期限当即生效。同样,留意uint64范例转换,这样我们就可以获取附加值并将其正确地存储在Lease工具中。
14 workingState = State.idle;
45
25 numberOfMonths,
第2-5行反复了前面的逻辑。
34
39
第15行声明白leaseDeposit并将其分派给lease.leaseDepositUsd。目标是在下一行(16)将其重置为0之前捕捉该值。然后,在第17行,我们将捕捉的leaseDeposit除以ETHUSD汇率乘以1e18以从wei转换为房东。在将原始存储位置配置为0之前捕捉值的这种模式是为了防备众所周知的智能合约裂痕(称为重入进攻)。
24 _collectLeaseDeposit();
1constructor () public payable {
第35-42行简朴地重置下一次租赁付款的截至日期,并发出一个leasePaid事件。
20 false,
51 require(
26 _reclaimLeaseDeposit();
24 emit leaseCreated(
52 amountSentUsd >= lease.leaseDepositUsd – 5 &&
第2行将房东的地点配置为msg.sender,这是陈设智能合约的地点。
16 leaseDepositUsd,
18
第12–33行正在建设一个新的Lease实例,利用一些数据对其举办初始化,并将其分派给tenantLease映射存储中的要害tenantAddr的值。请参考前面有关“Lease”工具的说明以增强领略。
第17行阐明字符串result,将其转换为uint范例,并将其分派给我们的全局变量ETHUSD。
19 emit leaseDepositCollected(
64}
41 );
55
我们利用uint8,uint16,uint32和uint64是因为有一个称为“布局打包”的观念。一旦我们从Lease布局建设了租赁实例,利用较小的uint范例就可以稍微淘汰gas本钱。
42 workingState = State.payingLeaseDeposit;
第60–63行发出了leaseDepositPaid事件。
21 } else if (workingState == State.payingLease) {
第38行确认租赁担保金的付款期限尚未高出。
collect lease deposit”);
第1至5行配置告终构函数,该结构函数是在陈设智能合约时执行的函数。它被标志为payable,以便可以吸收以太币。我们但愿在初始化时发送一些以,以付出可证明的查询的用度。
27 }
49 uint amountSentUsd = tenantPayment.mul(ETHUSD).div(1e18);
23 lease.monthsPaid = uint8(monthsPaid);
5 require(lease.leasePaymentWindowEnd >= now,
20 tenantAddress,
第1-10行声明白我们收集(收回)租赁押金的public函数。它接管有关租户的地点作为独一参数,并标志为“onlyLandlord”,以确保没有其他人可以窃取租赁押金。
6
第7-11行是认真奉告Provable提取ETH的美元汇率的函数。
15 uint leaseDeposit = lease.leaseDepositUsd;
38 require(lease.depositPaymentWindowEnd >= now,
13 numberOfMonths,
35 } else {
36 Lease storage lease = tenantLease[msg.sender];
第18–20行确保以美元发送的金额至少为所需的每月金额,并带有负的$5抵销。假如lease.monthlyAmountUsd为$500,则最低amountSentUsd必需为$495。没有上限,因为发送的金额抉择了付出的月数。租户可以一次付出多个月的用度。
5. depositPaymentWindowSeconds:租户必需付出的时间(以秒为单元)。建设租约后当即生效
第3行为Provable的__callback()函数配置了自界说gas价值。我们配置了一个很高的金额,以确保我们可以包围——_callback()中的操纵本钱。
4 OAR = OracleAddrResolverI(0xB7D2d92e74447535088A32AD65d459E97f692222);
“Lease payment must be overdue past payment window to
37
3 require(!lease.leaseFullyPaid,
1function payLease() public payable {
38 emit leasePaymentPaid(
57 lease.depositPaymentWindowEnd = 0;
4 require(lease.leasePaymentWindowEnd <= now,
60 emit leaseDepositPaid(
第35至44行认真付出租赁押金。它应该由租户挪用。
第23行将上述操纵的功效值转换为uint8,以便可以将其存储在lease.monthsPaid中。
8 tenantPayment = msg.value;
40 amountSentUsd
14 Lease storage lease = tenantLease[tenantAddress];
18 0,
39 tenantAddress,
2 Lease storage lease = tenantLease[tenantAddr];
第40行将全局变量tenant address配置为租户的地点。
27 lease.leaseFullyPaid = true;
20 _payLeaseDeposit();
25 } else if (workingState == State.reclaimingLeaseDeposit) {
22 _payLease();
第1行是我们付出租金的果真函数。
第7-9行反复了前面的逻辑。
3 require(lease.leaseDepositPaid,
为了建设更短的代码段,剩下的代码将继承显示为从第1行开始的新GitHub gist。
2. monthAmountUsd:每月要付出的总金额(美元)
31 tenantAddress,
31 false
36 lease.leasePaymentWindowEnd = lease.leasePaymentWindowEnd + lease.leasePaymentWindowSeconds;
第24行将全局变量leaseBalanceWei配置为leaseBalanceWei的原始值加上也以wei暗示的tenantPayment的值。假如房东但愿提取租赁付款,则此值为将要发送的金额。
3. leaseDepositUsd:应付出的租赁押金的总额
11}
第14-16行与payLeaseDeposit()沟通。
42 }
9 workingState = State.payingLease;
21 leaseDeposit
3 provable_setCustomGasPrice(100000000000);
21 false
33 monthsPaid
17 leasePaymentWindowSeconds,
10 fetchUsdRate();
48 Lease storage lease = tenantLease[tenantAddress];
10 validIds[queryId] = true;
第48行通过挪用payLeaseDeposit()来按照tenantAddress配置检索Lease。
37 require(!lease.leaseDepositPaid,
20 “Lease payment must be greater than or equal to the monthly amount with a maximum offset of $5”);
9
第12-23行界说了我们完成收取租赁押金进程的internal成果
19 amountSentUsd >= lease.monthlyAmountUsd – 5,
第2-5行应该是不问可知的。我们像往常一样获取Lease工具并执行一些查抄。
17 landlordAddress.transfer(leaseDeposit.div(ETHUSD).mul(1e18));
9 fetchUsdRate();
19 if (workingState == State.payingLeaseDeposit) {
“Lease has already been fully paid”);
10 uint64 depositPaymentWindowEnd = uint64(now.add(
32 lease.numberOfMonths,
29 leasePaymentWindowSeconds,
第14行查抄该ID是否已被查询利用。假如它还没有被利用,将抛出一个错误,执行将失败。
第24-33行发出带有一些信息的事件leaseCreated。
7 tenantAddress = msg.sender;
53 amountSentUsd <= lease.leaseDepositUsd + 5,
2 Lease storage lease = tenantLease[msg.sender];
4 uint16 leaseDepositUsd,
第37行确认尚未付出租赁押金。
29
3 uint16 monthlyAmountUsd,
41 tenantPayment = msg.value;
43 fetchUsdRate();
第13-43行声明白付出租约的internal函数。
5 require(lease.leaseDepositUsd > 0,
19 depositPaymentWindowEnd,
8 ) public onlyLandlord {
34 );
6. tenantAddr:租户的以太坊地点,通过外部通信提供应房东
56 lease.leaseDepositPaid = true;
第13-14行反复了前面的逻辑。
第26-35行指出,假如因当前举办中的付款而付出的月数已到达租约中商定的月数,则将租约声明为已全额付出并发出leaseFullyPaid事件。租户已全额付出了租金。
2 uint8 numberOfMonths,
6
第10行将实际的unix时间戳配置为now的值,即now的当前值加上depositPaymentWindowSeconds。我们利用uint64()对附加功效举办“范例转换”(留意.add),,并将其从uint256转换为uint64,因为Safemath仅合用于uint256。
25
16 uint amountSentUsd = tenantPayment.mul(ETHUSD).div(1e18);
23
17
11}
17 ETHUSD = parseInt(result);
28 leaseDepositUsd,
44}
62 amountSentUsd
21
12function _collectLeaseDeposit() internal {
12
第7-10行与payLeaseDeposit()沟通,除了我们将状态配置为payingLease。
2 landlordAddress = msg.sender;
6 uint32 depositPaymentWindowSeconds,
“Lease deposit is already paid.”);
14 require(validIds[myId], “Provable query IDs do not match, no valid call was made to provable_query()”);
28 lease.leasePaymentWindowEnd = 0;
第4行是可证明的地点理会器。当我们启动ethereum-bridge时,它会陈设一个智能合约,以利便我们的智能合约与互联网外部世界的通信。该智能合约的地点已经果真出来,因此我们可以将其包括在本智能合约中。此刻Provable可以利用此智能合约执行其操纵。筹备将地点修改为最终运行的npm run bridge的输出。
8 workingState = State.collectingLeaseDeposit;
10}
第42行将workingState配置为payingLeaseDeposit。这样一来,挪用fetchUsdRate()给出功效后触发的回调(第45行)领略为挪用_payLeaseDeposit()继承执行流程。
第49行通过挪用payLeaseDeposit()来获取tenantPayment配置,将其乘以ETHUSD汇率,最后将其除以1e18。该除法是将乘法的wei值转换为以太坊暗示。这时租户发送的金额为美元。
第41行将全局变量tenantPayment配置为租户发送的wei中ETH的数量msg.value。
13function _payLease() internal {
26 0,
4. leasePaymentWindowSeconds:租户每月付出的时间(以秒为单元),在租户付出了租赁押金后生效
1function createNewLease(
15 monthlyAmountUsd,
第22行的lease.monthsPaid和lease.monthlyAmountUsd都强制转换为uint256,以确保利用正确的范例来生成安详的.add。在这里,我们将付出的现有月数和当前付出的月数相乘,这是通过将每月租赁本钱除以10 +美元数得出的。配置这10美元的脱期期是为了确保在amountSentUsd的值略低于lease.monthlyAmountUsd的环境下记录正确的月份数。
22 );
12
8 require(provable_getPrice(“URL”) < address(this).balance, “Not enough Ether in contract, please add more”);
16 lease.leaseDepositUsd = 0;
7 tenantAddress = tenantAddr;
23}
58 lease.leasePaymentWindowEnd = uint64(now + lease.leasePaymentWindowSeconds);
13 workingState = State.idle;
30 emit leaseFullyPaid(
18 require(
6
4 require(!lease.leaseFullyPaid,
第36行按照租户的地点(msg.sender)从存储器中获取租约。
59
“Cannot collect lease deposit if lease is already paid”);
18
14 0,
第15行确保_callback()的挪用方是已陈设可证明智能合约的地点,作为附加的安详成果。任何随机参加者都不能执行_callback()。
35function payLeaseDeposit() public payable {
第1–33行是认真建设新租约的成果。它具有六个参数:
5 uint32 leasePaymentWindowSeconds,
1function collectLeaseDeposit(address payable tenantAddr)
public onlyLandlord {
32 );
16 validIds[myId] = false;
第46-64行代表internal函数,认真在收到USD/ETH汇率后继承付出租赁押金。它是internal的,因此只有_callback()才气在吸收速率后执行它。
13function __callback(bytes32 myId, string memory result) public {
“Lease deposit must be paid before making lease payments”);
“Lease deposit has already been removed”);
depositPaymentWindowSeconds));
11
9 bytes32 queryId = provable_query(“URL”, “json(https://api.pro.coinbase.com/products/ETH-USD/ticker).price”);
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。