pragma solidity ^0.4.0; library SafeMath { function mul(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a * b; assert(a == 0 || c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } } contract MyStruct { using SafeMath for uint256; struct Home { // создаётся структура дома из входящих в него переменных string ownerName; uint area; uint effectArea; uint price; address adres; bool dostypnost; } modifier onlyAdmin(){ //modifier работает перед и после функции/все функции с данным модификатором доступны только администратору require(admin == msg.sender); _;//заменяет тело функции } address constant admin = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;//адрес админа // ID нового дома uint lastHomeId=1; // Создаем соответствие (массив), где будут храниться дома (вбивая индекс можно посмотреть св-ва дома) mapping(uint => Home) public homes; // Добавление функций для взаимодействия с контрактом // Добавление дома function addHome(string ownerName, uint area, uint effectArea, uint price, address adres, bool dostypnost) public onlyAdmin returns (uint _thisId){ _thisId = lastHomeId++; // увеличиваем счетчик на 1 homes[_thisId] = Home(ownerName, area, effectArea, price, adres, dostypnost);//заполняем по след. критериям } struct HomeArendator { // создаётся структура арендатора из входящих в него переменных uint _days; address addr; uint [MAX_HOMES_PER_PERSON] homesId; } uint8 constant public MAX_HOMES_PER_PERSON = 6;//максимально доступное число квартир на одного uint8 constant internal NULL_HOME = 0;//нулевой дом(нужен для читабельности) uint8 constant internal NOT_HOME_OWNER = 0x0;//не владелец дома uint8 constant internal HOME_ARENDATOR = 0x1;//владелец дома bool constant internal IN_STOCK = true;//в наличии uint _thisId=1; uint homeArendatorID = 1; mapping (uint => HomeArendator) public homeArendators;//нужен для просмотра арендаторов mapping (address => uint) public homeArendator;// нужен для обращения к арендатору по адресу mapping (address => uint8) public isHomeArendator;// нужен для проверки снимает ли человек уже квартиру event NewHomeOwner(uint carOwnerID, address carOwnerAddress); event ArendaHome(uint _thisId, uint homeArendatorID); function arendaHome(uint thisId, uint _days) payable public { require(admin != msg.sender);// администратор не может снять квартиру require(thisId != NULL_HOME);//дом не может быть 0 require(thisId < _thisId);// число машины не должно привышать число существующих Home storage c = homes[thisId];//запись экзэмпляра машины require(c.dostypnost == IN_STOCK);//проверка наличия(свободности жилья) uint _homePrice = c.price.mul(_days);//получение цены машины * кол-во дней uint _homeArendatorID; if (isHomeArendator[msg.sender] == NOT_HOME_OWNER) {//проверка на неименее квартиры require(msg.value >= _homePrice);//проверка корректности отправленной суммы _homeArendatorID = homeArendatorID; isHomeArendator[msg.sender] = HOME_ARENDATOR;//присвоено значение дома и теперь он его арендует HomeArendator storage _newHomeArendator = homeArendators[_homeArendatorID];//просто ячейка памяти в storage по индексу арендатора _newHomeArendator.addr = msg.sender;//адрес нового арендатора _newHomeArendator.homesId = [thisId];//квартира нового арендатора homeArendator[msg.sender] = _homeArendatorID;// человек с адресом имеет следующий индекс emit (NewHomeOwner) (_homeArendatorID, msg.sender);//В NewHomeOwner входят ID арендатора и его адрес homeArendatorID = homeArendatorID.add(0x1);//homeArendatorID = homeArendatorID + 1 } else { _homeArendatorID = homeArendator[msg.sender];//по адресу получаем идентификатор человека, который уже мой клиент HomeArendator storage _homeArendator = homeArendators[_homeArendatorID];//получаем человека из массива арендаторов require(msg.value >= _homePrice);//проверка наличия нужной суммы на балансе арендатора require(_homeArendator.homesId[MAX_HOMES_PER_PERSON-1] == NULL_HOME);//проверка не прывышен ли лимит на квартиры(последняя машина в массиве должна быть NULL_HOME) for (uint i = 0; i < MAX_HOMES_PER_PERSON; i++) {//цикл добавления квартир в массив if (_homeArendator.homesId[i] != NULL_HOME)//если в ячейке i какя-то квартира снята continue;//то продолжаем цикл _homeArendator.homesId[i] = thisId;//в ином случае добавление в цикл значения снаятой квартиры break;//если уже добавлено = разбить } } //сдача uint _remainValue = msg.value.sub(_homePrice);//значение которое чел отправил на контракт - цена машины if (_remainValue > 0)//если это значение больше 0 msg.sender.transfer(_remainValue);//то вернуть человеку сдачу emit (ArendaHome)(thisId, _homeArendatorID); } function getArendatorHomes(uint _homeArendatorID) external view returns (uint[MAX_HOMES_PER_PERSON]) {//_homeArendatorID - чел который снимает, external-ни где больше не вызывается return homeArendators[_homeArendatorID].homesId;//_homeArendatorID - передаю ID и homesId - смотрю массив } }
0.4.18