ethereum_smartcontract_intro
96 строк · 2.9 Кб
1// SPDX-License-Identifier: UNLICENSED
2
3pragma solidity >=0.8;
4
5import "./Debug.sol";
6
7import "hardhat/console.sol";
8
9import {DebugPrintContract} from "./Debug.sol";
10
11
12contract DepositContract is DebugPrintContract {
13
14address private owner;
15
16mapping (address => uint) private balances;
17mapping (address => uint) private depositsDates;
18
19// Тип генерируемого события.
20event Withdrawal (uint amount, uint when);
21
22constructor () payable {
23
24owner = msg.sender;
25
26}
27
28function GetContractName () internal override pure returns (string memory) {
29return "DepositContract";
30}
31
32modifier OnlyOwner () {
33require(msg.sender == owner, "OnlyOwner");
34_;
35}
36
37// Запрос баланса адреса на контракте.
38function balanceOf (address addr) public view returns (uint){
39return balances[addr];
40}
41
42function deposit () public payable {
43
44// пополнить можно только пустой счёт
45require (balances[msg.sender] == 0, "Second deposit");
46
47balances[msg.sender] = msg.value;
48depositsDates[msg.sender] = block.timestamp;
49
50DebugPrint ("deposit ", msg.sender, msg.value);
51}
52
53// Высчитываем выплачиваемый процент.
54function CalculateInterest (uint amount) private pure returns (uint) {
55return (amount * 10) / 100;
56}
57
58// Запрос денег с депозита (возможно, с процентами).
59function withdraw (uint amount) public {
60
61require (amount > 0, "amount is null");
62require (balances[msg.sender] >= amount, "amount too big");
63balances[msg.sender] -= amount;
64
65uint amountForTranser = amount;
66
67// Если со времени размещения депозита прошло достаточно времени,
68// выплачиваем проценты.
69if (block.timestamp - depositsDates[msg.sender] > 60 seconds) {
70amountForTranser += CalculateInterest (amount);
71}
72
73if (amountForTranser > address(this).balance) {
74amountForTranser = address(this).balance;
75}
76
77// По умолчанию msg.sender имеет тип address.
78// Для перевода денег нужен тип address payable.
79payable(msg.sender).transfer (amountForTranser);
80
81// Генерируем событие.
82emit Withdrawal (amount, block.timestamp);
83
84DebugPrint ("withdraw ", msg.sender, amount);
85}
86
87// Владелец может уничтожить контракт и забрать все деньги.
88function destroy () public OnlyOwner {
89
90payable(owner).transfer (address(this).balance);
91
92// Начиная с cancun, контракт не будет удаляться.
93selfdestruct (payable(owner));
94}
95
96}
97