Solidity
September 5, 2023

АБС на блокчейне финал

Всем привет! В этой статье я заканчиваю свой проект с АБС на блокчейне. Получилось почти все что я хотел сделать и это меня радует. Расскажу про последние модули и доработки. Кто хочет потыкать весь код, то может найти его на гитхабе.

Начну с того, что я не смог реализовать все модули, но те которые я хотел смог. Также я не дописал похожие модули, которые уже существуют, так как там меняется только логика применения, а код по сути тот же.

В данной статье будут модули выдачи кредитов инвестиций и аналог Свифта для переводов между банками.

Статья будет не большой, так сказать завершающей.

Изменений почти нету с прошлой статьи поэтому сразу к новому:

 // SPDX-License-Identifier: MITpragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./clientsInfo.sol";
contract CreditAndInvest{    
    ClientInfo clientInfo;    
    address clientInfoAddress;    
    struct creditClient{        
        address client;        
        mapping(address=>uint) tokenBalanceCredit;    
    }    
    struct investClient{        
        address client;        
        mapping(address=>uint) tokenBalanceInvest;    
    }    
    mapping(address=>creditClient) creditClients;    
    mapping(address=>investClient) investClients;    
    event newCredit(address indexed client, address token, uint amount);    
    event newInvest(address indexed client, uint amount);    
    constructor(address clientInfo_){        
        clientInfo = ClientInfo(clientInfo_);        
        clientInfoAddress = clientInfo_;    
    }        
    function Credit(address sender, address token, uint amount) public{        
        emit newCredit(sender, token, amount);    
    }    
    function getCredit(address sender, address _client, address token, uint amount) public{        
        require(clientInfo.ownersBank(sender) == true, "not owner bank!");        
        clientInfo.getCredit(token, amount);        
        unchecked {            
            creditClients[_client].tokenBalanceCredit[token] += amount;        
        }    
    }    
    function invest(address sender, address token, uint amount) public{        
        //approve frontend        
        IERC20(token).transferFrom(sender, clientInfoAddress, amount);        
        emit newInvest(sender, amount);        
        //invest frontend    
    }
}

Модули кредитов и инвестиций я объединил, также расчет процента я решил оставить на фронт, потому что тупо удобнее.

Создаю две структуры для отслеживания балансов клиентов.

На самом деле тут все тоже самое, что и в аккредитиве: я хочу открыть кредит вызываю событие, которое сотрудник отслеживает и решает выдать мне кредит или нет.

В инвестициях все проще. Я просто делаю депозит в банк и вызываю событие, что я сделал инвестицию и в зависимости от типа инвестиции мне уже считают мой процент прибыли за период.

Аналог Свифта:

Я долго думал как сделать перевод между разными банками, чтоб он был быстрый и при этом мы могли делать перевод между любыми банками любой страны.

В общем, если банк использует мой вендор, то данная технология работает, в другом случае, нужно, чтоб была аналогичная функция для перевода как у моего вендора. В обще реализация не полная.

 function newTransfer(address fromBank, address toBank, address token, address toClient, uint amount) public{            
     updateBalanceInUSD(toClient);        
     (, int256 price, , , ) = AggregatorV3Interface(oracles[token]).latestRoundData();        
     require(price > 0, "Invalid price");        
     uint amountAllowance = IERC20(token).allowance(fromBank, toBank);        
     require(amountAllowance >= amount, "Not approve");        
     IERC20(token).transferFrom(fromBank, toBank, amount);         
     unchecked {            
         clients[toClient].balanceUsdt[token] += amount * uint(price);            
         clients[toClient].tokenBalance[token] += amount;        
     }    
 }    
 function transferBalanceFromBank(address sender, address to, address clientInfoBank, address token, uint amount, string memory inf) public{        
     updateBalanceInUSD(sender);        
     (, int256 price, , , ) = AggregatorV3Interface(oracles[token]).latestRoundData();        
     require(price > 0, "Invalid price");        
     unchecked {            
         clients[sender].balanceUsdt[token] -= amount * uint(price);            
         clients[sender].tokenBalance[token] -= amount;        
     }        
     IERC20(token).approve(clientInfoBank, amount);        
     bytes4 selector = bytes4(keccak256("newTransfer(address,address,address,address,uint256)"));        
     (bool success, ) = clientInfoBank.call(abi.encodeWithSelector(selector, address(this), clientInfoBank, token, to, amount));        
     require(success, "faild");        
     clients[sender].paymentInfo.push(payment(sender, to, inf, token, amount));    
 }

Добавлены функции в контракт clientInfo.

Для того, чтоб перевести деньги на другой банк, я буду использовать низкоуровневый вызов, который будет вызывать функцию, где уже будет происходить перевод. И соответственно я правильно отображаю балансы каждого клиента разных банков. Тема рабочая, при условии что вендоры одинаковые. Можно кончено передавать селектор функции другого вендора, отвечающего за перевод банку или депозит, таким образом обойти данную проблему, но я думаю в данном примере этого достаточно.

На этом я хочу закончить данный проект. Сделали достаточно много всего. Код был объёмным и много раз приходилось все переделывать, но в итоге исход положительный. Данную тему можно очень хорошо развить кому интересно, так что дерзайте. Я же вернусь к изучению solidity и его различным стандартам и особенностям. Всем кто следил спасибо.

Полный проект на гитхабе

Мой тг канал