bibatn / distributed_systems

0 stars 0 forks source link

lab3 #3

Open bibatn opened 1 year ago

bibatn commented 1 year ago

https://remix.ethereum.org/#lang=en&optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.18+commit.87f61d96.js

bibatn commented 1 year ago

// SPDX-License-Identifier: MIT pragma solidity ^0.8.18;

contract Manager { bool public have_marker; // Изначально маркер у менеджера. mapping (address => bool) public requestedWorkers; // Менеджер сохраняет в отображении адреса всех контрактов, которые запрашивали у него маркер.

constructor() 
{
    have_marker = true;
}

function getBalance() public view returns (uint) 
{
    return address(this).balance;
}

// Function to receive Ether. msg.data must be empty
receive() external payable 
{
    if (!requestedWorkers[msg.sender]) 
    {
        requestedWorkers[msg.sender] = false;
    }

    if (msg.value >=5 wei && have_marker) 
    { // если денег достаточно — менеджер передаёт маркер, иначе возвращает деньги
        have_marker = false;
        requestedWorkers[msg.sender] = true;
    } 
    else if (msg.value < 5 wei) 
    {
        (bool sent,) = payable(msg.sender).call{value: msg.value}("");
        assert(1==0 && sent);
    }
}

// Fallback function is called when msg.data is not empty
fallback() external payable {}

modifier checkForWorker 
{
    require(requestedWorkers[msg.sender], "");
    _;
}

function returnMarker() external checkForWorker returns (bool) 
{
    if (!have_marker) 
    {
        have_marker = true;
        requestedWorkers[msg.sender] = false;
        return true;
    }

    return false; // Если рабочий, держащий у себя маркер, посылает запрос на получение маркера — он получает отказ
}

}

contract Worker { Manager manager; string public last_op_status; bool public have_marker;

constructor(address _manager) 
{
    have_marker = false; // Изначально маркер у менеджера.
    manager = Manager(payable(_manager));
    last_op_status = "Init"; // Значение после развертывания
}

function getBalance() public view returns (uint) 
{
    return address(this).balance;
}

// Function to receive Ether. msg.data must be empty
receive() external payable {}

// Fallback function is called when msg.data is not empty
fallback() external payable {}

function requestMarker() public payable 
{ //рабочий запрашивает маркер
    if (have_marker) { //если маркер есть — рабочий переводит деньги
        last_op_status = "Repeat request";
        return;
    }

    if (!manager.have_marker()) {
        last_op_status = "Already taken";
        return;
    }

    last_op_status = "Marker available";

    (bool sent,) = payable(address(manager)).call{value: msg.value}("");

    if (sent) {
        have_marker = true;
        last_op_status = "Got marker";
    } else {
        last_op_status = "Low fund";
    }
}

function returnMarkerToManager() public 
{
    require(have_marker, "Don't have marker to return");

    require(manager.returnMarker(), "Was not able to return the marker");

    have_marker = false;
    last_op_status = "Released";
}

}