# Base Camp +Guild

By [Abramovich](https://paragraph.com/@ryslik) · 2024-08-29

---

[https://docs.base.org/base-learn/docs/deployment-to-testnet/deployment-to-testnet-exercise/](https://docs.base.org/base-learn/docs/deployment-to-testnet/deployment-to-testnet-exercise/)

підлючаємо гаманець

2, ідемо на ремікс

[https://remix.ethereum.org/#lang=en&optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.26+commit.8a97fa7a.js](https://remix.ethereum.org/#lang=en&optimize=false&runs=200&evmVersion=null&version=soljson-v0.8.26+commit.8a97fa7a.js)

![](https://storage.googleapis.com/papyrus_images/e34434943465de7515aaa6695304bf8c8471afc8988b805649c040bc2582bfd2.png)

див,фото

![](https://storage.googleapis.com/papyrus_images/22520420695ed1c8bb49ec127d07604202542625d689d35bc2778c606a705e28.png)

![](https://storage.googleapis.com/papyrus_images/a68f007a9a52cab9886b68d35feaef57598a8ed6a41dbac48b58aeb5d3fcc0e9.png)

BASE SEPOILIA має стоять в ММ задопоіли, тепер далі

Cстворюємо папку

BasicMath

![](https://storage.googleapis.com/papyrus_images/d8807df064b9104b02614309af487f55bc0ac4a30a098c167f9e47c393b4b0dc.png)

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    contract BasicMath {
        uint256 constant MAX_INT = type(uint256).max;    function adder(uint256 _a, uint256 _b) external pure returns (uint256 sum, bool error) {
            if (_b > MAX_INT - _a) {
                return (0, true); // Overflow occurred
            }
            return (_a + _b, false);
        }    function subtractor(uint256 _a, uint256 _b) external pure returns (uint256 difference, bool error) {
            if (_b > _a) {
                return (0, true); // Underflow occurred
            }
            return (_a - _b, false);
        }
    }//CHASE
    

![](https://storage.googleapis.com/papyrus_images/29300d1058ebb9c3cb6770bf42b9337673890728e07bedfa51dc9d54cbab3156.png)

і робимо деплой

![](https://storage.googleapis.com/papyrus_images/fed89f0556703cb5da95ea80dea2076bb87109ef09f9499155becebb06b31c92.png)

копіюємо і перейти до :

[https://docs.base.org/base-learn/docs/deployment-to-testnet/deployment-to-testnet-exercise/](https://docs.base.org/base-learn/docs/deployment-to-testnet/deployment-to-testnet-exercise/)

і вставити

![](https://storage.googleapis.com/papyrus_images/08e66cb81037d368b816531d8172c9430878739439f24d776530bab2c3dc7fe0.png)

має таке получитися,

тепер залишилось ще 13 контрактів

1.  Повертаємось на Реміксстворюємо новий файл
    

ControlStructures.sol

    // SPDX-License-Identifier: MIT
    pragma solidity 0.8.17;
    
    contract ControlStructures {
        // Define custom errors for use within the contract
        error AfterHours(uint256 time);
        error AtLunch();    // Function to determine the response based on the input number
        function fizzBuzz(uint256 _number) public pure returns (string memory response) {
            // Check if the number is divisible by both 3 and 5
            if (_number % 3 == 0 && _number % 5 == 0) {
                return "FizzBuzz"; // Return "FizzBuzz" if divisible by both 3 and 5
            } 
            // Check if the number is divisible by 3
            else if (_number % 3 == 0) {
                return "Fizz"; // Return "Fizz" if divisible by 3
            } 
            // Check if the number is divisible by 5
            else if (_number % 5 == 0) {
                return "Buzz"; // Return "Buzz" if divisible by 5
            } 
            // If none of the above conditions are met
            else {
                return "Splat"; // Return "Splat" if none of the conditions are met
            }
        }    // Function to determine the response based on the input time
        function doNotDisturb(uint256 _time) public pure returns (string memory result) {
            // Ensure the input time is within valid bounds (less than 2400)
            assert(_time < 2400);        // Check different time ranges and return appropriate responses or revert with errors
            if (_time > 2200 || _time < 800) {
                revert AfterHours(_time); // Revert with custom error if it's after 10:00 PM or before 8:00 AM
            } 
            else if (_time >= 1200 && _time <= 1299) {
                revert AtLunch(); // Revert with custom error if it's between 12:00 PM and 1:00 PM
            } 
            else if (_time >= 800 && _time <= 1199) {
                return "Morning!"; // Return "Morning!" if it's between 8:00 AM and 11:59 AM
            } 
            else if (_time >= 1300 && _time <= 1799) {
                return "Afternoon!"; // Return "Afternoon!" if it's between 1:00 PM and 5:59 PM
            } 
            else if (_time >= 1800 && _time <= 2200) {
                return "Evening!"; // Return "Evening!" if it's between 6:00 PM and 10:00 PM
            }
        }
    }//CHASE
    

![](https://storage.googleapis.com/papyrus_images/0b0ab12bbedd419e507d837e1bc45b5858494af9153c8293633827ccaf48fe2f.png)

Далі робимо все теж саме

![](https://storage.googleapis.com/papyrus_images/58e0aa74405cb38999243eacb36d1a3ce966269be2edce9f513ceed92bea4d9f.png)

запускаємо і деполімо

![](https://storage.googleapis.com/papyrus_images/ddbac49a5fdd6bd62ed0867bfbcee7a286319882699f266e9144d2c936e867ee.png)

беремо контракт і і демо на

[https://docs.base.org/base-learn/docs/control-structures/control-structures-exercise/](https://docs.base.org/base-learn/docs/control-structures/control-structures-exercise/)

![](https://storage.googleapis.com/papyrus_images/47af44879ca5e801dd79bfc2d3f4e362944314996f295bd15722855e261e34aa.png)

Готово

Продовжуємо

3, Новий файл

Storage.sol

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.17;
    
    contract EmployeeStorage {
        // Declare private state variables to store employee data
        uint16 private shares; // Number of shares owned by the employee (private to contract)
        uint32 private salary; // Monthly salary of the employee (private to contract)
        uint256 public idNumber; // Unique identification number of the employee (publicly accessible)
        string public name; // Name of the employee (publicly accessible)    // Constructor to initialize employee data when contract is deployed
        constructor(uint16 _shares, string memory _name, uint32 _salary, uint _idNumber) {
            shares = _shares; // Initialize shares
            name = _name; // Initialize name
            salary = _salary; // Initialize salary
            idNumber = _idNumber; // Initialize idNumber
        }    // View function to retrieve the number of shares owned by the employee
        function viewShares() public view returns (uint16) {
            return shares;
        }
        
        // View function to retrieve the monthly salary of the employee
        function viewSalary() public view returns (uint32) {
            return salary;
        }    // Custom error declaration
        error TooManyShares(uint16 _shares);
        
        // Function to grant additional shares to the employee
        function grantShares(uint16 _newShares) public {
            // Check if the requested shares exceed the limit
            if (_newShares > 5000) {
                revert("Too many shares"); // Revert with error message
            } else if (shares + _newShares > 5000) {
                revert TooManyShares(shares + _newShares); // Revert with custom error message
            }
            shares += _newShares; // Grant the new shares
        }    // Function used for testing packing of storage variables (not relevant to main functionality)
        function checkForPacking(uint _slot) public view returns (uint r) {
            assembly {
                r := sload (_slot)
            }
        }    // Function to reset shares for debugging purposes (not relevant to main functionality)
        function debugResetShares() public {
            shares = 1000; // Reset shares to 1000
        }
    }//CHASE
    

Запускаємо і колидеплой то ТУТ УВАГА

*   `shares` - 1000
    
*   `name` - Pat
    
*   `salary` - 50000
    
*   `idNumber` - 112358132134
    
*     
    

![](https://storage.googleapis.com/papyrus_images/74790fad5df2a46541584a82a858064b686c8ffdcbfd27e2933d97814146843e.png)

[https://docs.base.org/base-learn/docs/storage/storage-exercise/](https://docs.base.org/base-learn/docs/storage/storage-exercise/)

копіюємо і втавляєсо сюди

![](https://storage.googleapis.com/papyrus_images/8333aa882c66aa93ca7d55e3e855762a9e7b11f20562a3ea5e78589aca7a7bc9.png)

4, Дальше

Arrays Ствооюємо

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.17;
    
    contract ArraysExercise {
        // Declare state variables to store arrays of numbers, timestamps, and senders
        uint[] numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; // Array of numbers initialized with values
        uint[] timestamps; // Dynamic array to store timestamps
        address[] senders; // Dynamic array to store sender addresses
    
        uint256 constant Y2K = 946702800; // Constant representing the Unix timestamp for the year 2000
    
        // Function to retrieve the array of numbers
        function getNumbers() external view returns (uint[] memory) {
            // Create a memory array to hold the numbers
            uint[] memory results = new uintUnsupported embed;
    
            // Copy the numbers from the state array to the memory array
            for(uint i=0; i<numbers.length; i++) {
                results[i] = numbers[i];
            }
    
            // Return the memory array
            return results;
        }
    
        // Function to reset the numbers array to its initial values
        function resetNumbers() public {
            numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        }
    
        // Function to append new numbers to the numbers array
        function appendToNumbers(uint[] calldata _toAppend) public {
            // Iterate through the array to be appended
            for (uint i = 0; i < _toAppend.length; i++) {
                // Push each element of the array to be appended to the numbers array
                numbers.push(_toAppend[i]);
            }
        }
    
        // Function to save a timestamp along with the sender's address
        function saveTimestamp(uint _unixTimestamp) public {
            // Push the timestamp and sender's address to their respective arrays
            timestamps.push(_unixTimestamp);
            senders.push(msg.sender);
        }
    
        // Function to retrieve timestamps and senders after the year 2000
        function afterY2K() public view returns (uint256[] memory, address[] memory) {
            // Initialize counter for timestamps after Y2K
            uint256 counter = 0;
    
            // Count the number of timestamps after Y2K
            for (uint i = 0; i < timestamps.length; i++) {
                if (timestamps[i] > Y2K) {
                    counter++;
                }
            }
    
            // Initialize memory arrays to hold timestamps and senders after Y2K
            uint256[] memory timestampsAfterY2K = new uint256Unsupported embed;
            address[] memory sendersAfterY2K = new addressUnsupported embed;
    
            // Initialize index for inserting elements into memory arrays
            uint256 index = 0;
    
            // Iterate through timestamps and senders arrays to extract elements after Y2K
            for (uint i = 0; i < timestamps.length; i++) {
                if (timestamps[i] > Y2K) {
                    timestampsAfterY2K[index] = timestamps[i];
                    sendersAfterY2K[index] = senders[i];
                    index++;
                }
            }
    
            // Return timestamps and senders after Y2K
            return (timestampsAfterY2K, sendersAfterY2K);
        }
    
        // Function to reset the senders array
        function resetSenders() public {
            delete senders;
        }
    
        // Function to reset the timestamps array
        function resetTimestamps() public {
            delete timestamps;
        }
    }
    

![](https://storage.googleapis.com/papyrus_images/d2eebdf723fb6088d744a7d20a5dd895ac250ab7740a3378411f3df13ef6a8b6.png)

запускаємо і деплоімо, копіємо новий контракт і ідемо сюди :

[https://docs.base.org/base-learn/docs/arrays/arrays-exercise/](https://docs.base.org/base-learn/docs/arrays/arrays-exercise/)

![](https://storage.googleapis.com/papyrus_images/1fc471c176e5e09d7ebda2838d82aff7db615d583dfef52ff9fb7499231d7520.png)

Готово,далі

5,

Mapping новий файл

$$$ $$$

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.17;
    
    /**
     * @title FavoriteRecords
     * @dev Contract to manage a list of approved music records and allow users to add them to their favorites
     */
    contract FavoriteRecords {
        // Mapping to store whether a record is approved
        mapping(string => bool) private approvedRecords;
        // Array to store the index of approved records
        string[] private approvedRecordsIndex;
    
        // Mapping to store user's favorite records
        mapping(address => mapping(string => bool)) public userFavorites;
        // Mapping to store the index of user's favorite records
        mapping(address => string[]) private userFavoritesIndex;
    
        // Custom error to handle unapproved records
        error NotApproved(string albumName);
    
        /**
         * @dev Constructor that initializes the approved records list
         */
        constructor() {
            // Predefined list of approved records
            approvedRecordsIndex = [
                "Thriller", 
                "Back in Black", 
                "The Bodyguard", 
                "The Dark Side of the Moon", 
                "Their Greatest Hits (1971-1975)", 
                "Hotel California", 
                "Come On Over", 
                "Rumours", 
                "Saturday Night Fever"
            ];
            // Initialize the approved records mapping
            for (uint i = 0; i < approvedRecordsIndex.length; i++) {
                approvedRecords[approvedRecordsIndex[i]] = true;
            }
        }
    
        /**
         * @dev Returns the list of approved records
         * @return An array of approved record names
         */
        function getApprovedRecords() public view returns (string[] memory) {
            return approvedRecordsIndex;
        }
    
        /**
         * @dev Adds an approved record to the user's favorites
         * @param _albumName The name of the album to be added
         */
        function addRecord(string memory _albumName) public {
            // Check if the record is approved
            if (!approvedRecords[_albumName]) {
                revert NotApproved({albumName: _albumName});
            }
            // Check if the record is not already in the user's favorites
            if (!userFavorites[msg.sender][_albumName]) {
                // Add the record to the user's favorites
                userFavorites[msg.sender][_albumName] = true;
                // Add the record to the user's favorites index
                userFavoritesIndex[msg.sender].push(_albumName);
            }
        }
    
        /**
         * @dev Returns the list of a user's favorite records
         * @param _address The address of the user
         * @return An array of user's favorite record names
         */
        function getUserFavorites(address _address) public view returns (string[] memory) {
            return userFavoritesIndex[_address];
        }
    
        /**
         * @dev Resets the caller's list of favorite records
         */
        function resetUserFavorites() public {
            // Iterate through the user's favorite records
            for (uint i = 0; i < userFavoritesIndex[msg.sender].length; i++) {
                // Delete each record from the user's favorites mapping
                delete userFavorites[msg.sender][userFavoritesIndex[msg.sender][i]];
            }
            // Delete the user's favorites index
            delete userFavoritesIndex[msg.sender];
        }
    }
    

далі по сцнарію,запускаємо і деплоімо

[https://docs.base.org/base-learn/docs/mappings/mappings-exercise/](https://docs.base.org/base-learn/docs/mappings/mappings-exercise/)

![](https://storage.googleapis.com/papyrus_images/37ca41c08779d6e2470e6cbe1086615134283b2240b854e1f90229b7de74b1b2.png)

6,

Structs

новий кнтракт

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.17;
    
    /**
     * @title GarageManager
     * @dev Contract to manage a garage of cars for each user
     */
    contract GarageManager {
        // Mapping to store the garage of cars for each user
        mapping(address => Car[]) private garages;
    
        // Struct to represent a car
        struct Car {
            string make; // Make of the car
            string model; // Model of the car
            string color; // Color of the car
            uint numberOfDoors; // Number of doors of the car
        }
    
        // Custom error for handling invalid car index
        error BadCarIndex(uint256 index);
    
        /**
         * @dev Adds a new car to the caller's garage
         * @param _make The make of the car
         * @param _model The model of the car
         * @param _color The color of the car
         * @param _numberOfDoors The number of doors of the car
         */
        function addCar(string memory _make, string memory _model, string memory _color, uint _numberOfDoors) external {
            // Push a new car struct with the provided details to the caller's garage
            garages[msg.sender].push(Car(_make, _model, _color, _numberOfDoors));
        }
    
        /**
         * @dev Retrieves the caller's array of cars
         * @return An array of `Car` structs
         */
        function getMyCars() external view returns (Car[] memory) {
            // Return the array of cars stored in the caller's garage
            return garages[msg.sender];
        }
    
        /**
         * @dev Retrieves a specific user's array of cars
         * @param _user The address of the user
         * @return An array of `Car` structs
         */
        function getUserCars(address _user) external view returns (Car[] memory) {
            // Return the array of cars stored in the garage of the specified user
            return garages[_user];
        }
    
        /**
         * @dev Updates a specific car in the caller's garage
         * @param _index The index of the car in the garage array
         * @param _make The new make of the car
         * @param _model The new model of the car
         * @param _color The new color of the car
         * @param _numberOfDoors The new number of doors of the car
         */
        function updateCar(uint256 _index, string memory _make, string memory _model, string memory _color, uint _numberOfDoors) external {
            // Check if the provided index is valid
            if (_index >= garages[msg.sender].length) {
                revert BadCarIndex({index: _index}); // Revert with custom error if the index is invalid
            }
            // Update the specified car with the new details
            garages[msg.sender][_index] = Car(_make, _model, _color, _numberOfDoors);
        }
    
        /**
         * @dev Deletes all cars in the caller's garage
         */
        function resetMyGarage() external {
            // Delete all cars from the caller's garage
            delete garages[msg.sender];
        }
    }
    

все по сценарію

[https://docs.base.org/base-learn/docs/structs/structs-exercise/](https://docs.base.org/base-learn/docs/structs/structs-exercise/)

![](https://storage.googleapis.com/papyrus_images/0bf702f9963792a29285eed9c6433dc6cc241463b5934abbe3a1097927302604.png)

6,

Inheritance новий файл тут не спішимо

    // SPDX-License-Identifier: MIT
    
    pragma solidity 0.8.17;
    
    /**
     * @title Employee
     * @dev Abstract contract defining common properties and behavior for employees.
     */
    abstract contract Employee {
        uint public idNumber; // Unique identifier for the employee
        uint public managerId; // Identifier of the manager overseeing the employee
    
        /**
         * @dev Constructor to initialize idNumber and managerId.
         * @param _idNumber The unique identifier for the employee.
         * @param _managerId The identifier of the manager overseeing the employee.
         */
        constructor(uint _idNumber, uint _managerId) {
            idNumber = _idNumber;
            managerId = _managerId;
        }
    
        /**
         * @dev Abstract function to be implemented by derived contracts to get the annual cost of the employee.
         * @return The annual cost of the employee.
         */
        function getAnnualCost() public virtual returns (uint);
    }
    
    /**
     * @title Salaried
     * @dev Contract representing employees who are paid an annual salary.
     */
    contract Salaried is Employee {
        uint public annualSalary; // The annual salary of the employee
    
        /**
         * @dev Constructor to initialize the Salaried contract.
         * @param _idNumber The unique identifier for the employee.
         * @param _managerId The identifier of the manager overseeing the employee.
         * @param _annualSalary The annual salary of the employee.
         */
        constructor(uint _idNumber, uint _managerId, uint _annualSalary) Employee(_idNumber, _managerId) {
            annualSalary = _annualSalary;
        }
    
        /**
         * @dev Overrides the getAnnualCost function to return the annual salary of the employee.
         * @return The annual salary of the employee.
         */
        function getAnnualCost() public override view returns (uint) {
            return annualSalary;
        }
    }
    
    /**
     * @title Hourly
     * @dev Contract representing employees who are paid an hourly rate.
     */
    contract Hourly is Employee {
        uint public hourlyRate; // The hourly rate of the employee
    
        /**
         * @dev Constructor to initialize the Hourly contract.
         * @param _idNumber The unique identifier for the employee.
         * @param _managerId The identifier of the manager overseeing the employee.
         * @param _hourlyRate The hourly rate of the employee.
         */
        constructor(uint _idNumber, uint _managerId, uint _hourlyRate) Employee(_idNumber, _managerId) {
            hourlyRate = _hourlyRate;
        }
    
        /**
         * @dev Overrides the getAnnualCost function to calculate the annual cost based on the hourly rate.
         * Assuming a full-time workload of 2080 hours per year.
         * @return The annual cost of the employee.
         */
        function getAnnualCost() public override view returns (uint) {
            return hourlyRate * 2080;
        }
    }
    
    /**
     * @title Manager
     * @dev Contract managing a list of employee IDs.
     */
    contract Manager {
        uint[] public employeeIds; // List of employee IDs
    
        /**
         * @dev Function to add a new employee ID to the list.
         * @param _reportId The ID of the employee to be added.
         */
        function addReport(uint _reportId) public {
            employeeIds.push(_reportId);
        }
    
        /**
         * @dev Function to reset the list of employee IDs.
         */
        function resetReports() public {
            delete employeeIds;
        }
    }
    
    /**
     * @title Salesperson
     * @dev Contract representing salespeople who are paid hourly.
     */
    contract Salesperson is Hourly {
        /**
         * @dev Constructor to initialize the Salesperson contract.
         * @param _idNumber The unique identifier for the employee.
         * @param _managerId The identifier of the manager overseeing the employee.
         * @param _hourlyRate The hourly rate of the employee.
         */
        constructor(uint _idNumber, uint _managerId, uint _hourlyRate) 
            Hourly(_idNumber, _managerId, _hourlyRate) {}
    }
    
    /**
     * @title EngineeringManager
     * @dev Contract representing engineering managers who are paid an annual salary and have managerial responsibilities.
     */
    contract EngineeringManager is Salaried, Manager {
        /**
         * @dev Constructor to initialize the EngineeringManager contract.
         * @param _idNumber The unique identifier for the employee.
         * @param _managerId The identifier of the manager overseeing the employee.
         * @param _annualSalary The annual salary of the employee.
         */
        constructor(uint _idNumber, uint _managerId, uint _annualSalary) 
            Salaried(_idNumber, _managerId, _annualSalary) {}
    }
    
    /**
     * @title InheritanceSubmission
     * @dev Contract for deploying instances of Salesperson and EngineeringManager.
     */
    contract InheritanceSubmission {
        address public salesPerson; // Address of the deployed Salesperson instance
        address public engineeringManager; // Address of the deployed EngineeringManager instance
    
        /**
         * @dev Constructor to initialize the InheritanceSubmission contract.
         * @param _salesPerson Address of the deployed Salesperson instance.
         * @param _engineeringManager Address of the deployed EngineeringManager instance.
         */
        constructor(address _salesPerson, address _engineeringManager) {
            salesPerson = _salesPerson;
            engineeringManager = _engineeringManager;
        }
    }
    

![](https://storage.googleapis.com/papyrus_images/3047e25ee9c6054da1369575aaedfba2ae678d3ccb1e0a03d97404b806b3aa14.png)

Id Number: **55555** Manager id: **12345** Salary: **20робимо транзу і підтвержєумо**

![](https://storage.googleapis.com/papyrus_images/065cd728889aad60aa113da3bbbb01ec83ffa8b324ccdbd7b8a29090a73a941e.png)

дальше Знову

![](https://storage.googleapis.com/papyrus_images/c67237b930b46ee6e591b99fde495a51aaf0b3008ab24246a1d2959e779988e0.png)

Id Number: **54321** Manager id: **11111** Annual salary: \*\*200000тицемо на ТРАНЗАКТ і підтверджуємо транзу \*\*

дальше

![](https://storage.googleapis.com/papyrus_images/41e0c37234dc307314f63f06519db424645e50e5a0f9908094ec612bf0628934.png)

![](https://storage.googleapis.com/papyrus_images/caaf8c2e4ff4a7e85d0c1076728843ec13c63c824d02ee2a1bd00279b50cc26a.png)

копіємо адреси

**Salesperon** EngineeringManager і вставляємо іх робимо транзудалі по сценарію))

[https://docs.base.org/base-learn/docs/inheritance/inheritance-exercise/](https://docs.base.org/base-learn/docs/inheritance/inheritance-exercise/)

![](https://storage.googleapis.com/papyrus_images/84f10a6ace608f7f38bfc04e28045bd6e7b9c5f6d3fa4d2940af243ef26a5600.png)

Готово

6,

SillyStringUtils новий файл

    // SPDX-License-Identifier: MIT
    
    pragma solidity ^0.8.17;
    
    library SillyStringUtils {
    
        struct Haiku {
            string line1;
            string line2;
            string line3;
        }
    
        function shruggie(string memory _input) internal pure returns (string memory) {
            return string.concat(_input, unicode" 🤷");
        }
    }
    

Imports Створюємо новий файл

    // SPDX-License-Identifier: MIT
    
    // Importing the SillyStringUtils library
    import "./SillyStringUtils.sol";
    
    pragma solidity 0.8.17;
    
    contract ImportsExercise {
        // Using the SillyStringUtils library for string manipulation
        using SillyStringUtils for string;
    
        // Declaring a public variable to store a Haiku
        SillyStringUtils.Haiku public haiku;
    
        // Function to save a Haiku
        function saveHaiku(string memory _line1, string memory _line2, string memory _line3) public {
            haiku.line1 = _line1;
            haiku.line2 = _line2;
            haiku.line3 = _line3;
        }
    
        // Function to retrieve the saved Haiku
        function getHaiku() public view returns (SillyStringUtils.Haiku memory) {
            return haiku;
        }
    
        // Function to append a shrugging emoji to the third line of the Haiku
        function shruggieHaiku() public view returns (SillyStringUtils.Haiku memory) {
            // Creating a copy of the Haiku
            SillyStringUtils.Haiku memory newHaiku = haiku;
            // Appending the shrugging emoji to the third line using the shruggie function from the SillyStringUtils library
            newHaiku.line3 = newHaiku.line3.shruggie();
            return newHaiku;
        }
    }
    

далі по сценарію, записуємо, деплоімо, підписуємо і ідемо сюди:

[https://docs.base.org/base-learn/docs/imports/imports-exercise/](https://docs.base.org/base-learn/docs/imports/imports-exercise/)

![](https://storage.googleapis.com/papyrus_images/5e2e0f701c7582d6eafcd3484d0ca6c0758734ceb47e3dbbdd4a3f2285e730ce.png)

гоотово

7,

Errors Новий файл

    // SPDX-License-Identifier: MIT
    
    pragma solidity ^0.8.17;
    
    contract ErrorTriageExercise {
        /**
         * @dev Finds the difference between each uint with its neighbor (a to b, b to c, etc.)
         * and returns a uint array with the absolute integer difference of each pairing.
         * 
         * @param _a The first unsigned integer.
         * @param _b The second unsigned integer.
         * @param _c The third unsigned integer.
         * @param _d The fourth unsigned integer.
         * 
         * @return results An array containing the absolute differences between each pair of integers.
         */
        function diffWithNeighbor(
            uint _a,
            uint _b,
            uint _c,
            uint _d
        ) public pure returns (uint[] memory) {
            // Initialize an array to store the differences
            uint[] memory results = new uintUnsupported embed;
    
            // Calculate the absolute difference between each pair of integers and store it in the results array
            results[0] = _a > _b ? _a - _b : _b - _a;
            results[1] = _b > _c ? _b - _c : _c - _b;
            results[2] = _c > _d ? _c - _d : _d - _c;
    
            // Return the array of differences
            return results;
        }
    
        /**
         * @dev Changes the base by the value of the modifier. Base is always >= 1000. Modifiers can be
         * between positive and negative 100.
         * 
         * @param _base The base value to be modified.
         * @param _modifier The value by which the base should be modified.
         * 
         * @return returnValue The modified value of the base.
         */
        function applyModifier(
            uint _base,
            int _modifier
        ) public pure returns (uint returnValue) {
            // Apply the modifier to the base value
            if(_modifier > 0) {
                return _base + uint(_modifier);
            }
            return _base - uint(-_modifier);
        }
    
    
        uint[] arr;
    
        function popWithReturn() public returns (uint returnNum) {
            if(arr.length > 0) {
                uint result = arr[arr.length - 1];
                arr.pop();
                return result;
            }
        }
    
        // The utility functions below are working as expected
        function addToArr(uint _num) public {
            arr.push(_num);
        }
    
        function getArr() public view returns (uint[] memory) {
            return arr;
        }
    
        function resetArr() public {
            delete arr;
        }
    }
    

далі по сценарію, записуємо, деплоімо, підписуємо і ідемо сюди:

[https://docs.base.org/base-learn/docs/error-triage/error-triage-exercise/](https://docs.base.org/base-learn/docs/error-triage/error-triage-exercise/)

uj

![](https://storage.googleapis.com/papyrus_images/c5d192e347eafadea4424fbc2d48d9f13a4b50e92356f946ad1100063592d8bd.png)

Готово

8,

*   **AddressBook новий файл**
    
    не спішимо
    
        // SPDX-License-Identifier: MIT
        pragma solidity ^0.8.8;
        
        import "@openzeppelin/contracts/access/Ownable.sol";
        
        contract AddressBook is Ownable(msg.sender) {
            // Define a private salt value for internal use
            string private salt = "value"; 
        
            // Define a struct to represent a contact
            struct Contact {
                uint id; // Unique identifier for the contact
                string firstName; // First name of the contact
                string lastName; // Last name of the contact
                uint[] phoneNumbers; // Array to store multiple phone numbers for the contact
            }
        
            // Array to store all contacts
            Contact[] private contacts;
        
            // Mapping to store the index of each contact in the contacts array using its ID
            mapping(uint => uint) private idToIndex;
        
            // Variable to keep track of the ID for the next contact
            uint private nextId = 1;
        
            // Custom error for when a contact is not found
            error ContactNotFound(uint id);
        
            // Function to add a new contact
            function addContact(string calldata firstName, string calldata lastName, uint[] calldata phoneNumbers) external onlyOwner {
                // Create a new contact with the provided details and add it to the contacts array
                contacts.push(Contact(nextId, firstName, lastName, phoneNumbers));
                // Map the ID of the new contact to its index in the array
                idToIndex[nextId] = contacts.length - 1;
                // Increment the nextId for the next contact
                nextId++;
            }
        
            // Function to delete a contact by its ID
            function deleteContact(uint id) external onlyOwner {
                // Get the index of the contact to be deleted
                uint index = idToIndex[id];
                // Check if the index is valid and if the contact with the provided ID exists
                if (index >= contacts.length || contacts[index].id != id) revert ContactNotFound(id);
        
                // Replace the contact to be deleted with the last contact in the array
                contacts[index] = contacts[contacts.length - 1];
                // Update the index mapping for the moved contact
                idToIndex[contacts[index].id] = index;
                // Remove the last contact from the array
                contacts.pop();
                // Delete the mapping entry for the deleted contact ID
                delete idToIndex[id];
            }
        
            // Function to retrieve a contact by its ID
            function getContact(uint id) external view returns (Contact memory) {
                // Get the index of the contact
                uint index = idToIndex[id];
                // Check if the index is valid and if the contact with the provided ID exists
                if (index >= contacts.length || contacts[index].id != id) revert ContactNotFound(id);
                // Return the contact details
                return contacts[index];
            }
        
            // Function to retrieve all contacts
            function getAllContacts() external view returns (Contact[] memory) {
                // Return the array of all contacts
                return contacts;
            }
        }
        
    
    **Other Contracts новий файл**
    

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.8;
    
    // Import the AddressBook contract to interact with it
    import "./AddressBook.sol";
    
    // Contract for creating new instances of AddressBook
    contract AddressBookFactory {
        // Define a private salt value for internal use
        string private salt = "value";
    
        // Function to deploy a new instance of AddressBook
        function deploy() external returns (AddressBook) {
            // Create a new instance of AddressBook
            AddressBook newAddressBook = new AddressBook();
    
            // Transfer ownership of the new AddressBook contract to the caller of this function
            newAddressBook.transferOwnership(msg.sender);
    
            // Return the newly created AddressBook contract
            return newAddressBook;
        }
    }
    

Змінити версію

![](https://storage.googleapis.com/papyrus_images/a3b19c0ad4381b6217c8d775129157c44b2d7791644b1a1a17bcafc03969519e.png)

Деплой і ідемо сюди

[https://docs.base.org/base-learn/docs/new-keyword/new-keyword-exercise/](https://docs.base.org/base-learn/docs/new-keyword/new-keyword-exercise/)

І

![](https://storage.googleapis.com/papyrus_images/6fb679190f215fbad7c087b1e8451e79efc986286c180ff5140cf6273e88e0bd.png)

Готово

9,

Minimal Token Новий файл

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    // Contract for an unburnable token
    contract UnburnableToken {
        string private salt = "123456"; // A private string variable
    
        // Mapping to track token balances of addresses
        mapping(address => uint256) public balances;
    
        uint256 public totalSupply; // Total supply of tokens
        uint256 public totalClaimed; // Total number of tokens claimed
        mapping(address => bool) private claimed; // Mapping to track whether an address has claimed tokens
    
        // Custom errors
        error TokensClaimed(); // Error for attempting to claim tokens again
        error AllTokensClaimed(); // Error for attempting to claim tokens when all are already claimed
        error UnsafeTransfer(address _to); // Error for unsafe token transfer
    
        // Constructor to set the total supply of tokens
        constructor() {
            totalSupply = 100000000; // Set the total supply of tokens
        }
    
        // Public function to claim tokens
        function claim() public {
            // Check if all tokens have been claimed
            if (totalClaimed >= totalSupply) revert AllTokensClaimed();
            
            // Check if the caller has already claimed tokens
            if (claimed[msg.sender]) revert TokensClaimed();
    
            // Update balances and claimed status
            balances[msg.sender] += 1000;
            totalClaimed += 1000;
            claimed[msg.sender] = true;
        }
    
        // Public function for safe token transfer
        function safeTransfer(address _to, uint256 _amount) public {
            // Check for unsafe transfer conditions, including if the target address has a non-zero ether balance
            if (_to == address(0) || _to.balance == 0) revert UnsafeTransfer(_to);
    
            // Ensure the sender has enough balance to transfer
            require(balances[msg.sender] >= _amount, "Insufficient balance");
    
            // Perform the transfer
            balances[msg.sender] -= _amount;
            balances[_to] += _amount;
        }
    }
    

все по сценарію

[https://docs.base.org/base-learn/docs/minimal-tokens/minimal-tokens-exercise/](https://docs.base.org/base-learn/docs/minimal-tokens/minimal-tokens-exercise/)

![](https://storage.googleapis.com/papyrus_images/596062afbe75d09b3028a1e9ed70698fc11a9388f844df70cbc251f85d4b2195.png)

маєбути так, як вибє помилку змініть версію з 0,8,20 на вищу, і ще рз задепойтеГтово

10,

**ERC20 Новий файл**

    // SPDX-License-Identifier: UNLICENSED
    pragma solidity ^0.8.17;
    
    // Importing OpenZeppelin contracts for ERC20 and EnumerableSet functionalities
    import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
    import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";// Contract for weighted voting using ERC20 token
    contract WeightedVoting is ERC20 {
        string private salt = "gedt"; // A private string variable
        using EnumerableSet for EnumerableSet.AddressSet; // Importing EnumerableSet for address set functionality    // Custom errors
        error TokensClaimed(); // Error for attempting to claim tokens again
        error AllTokensClaimed(); // Error for attempting to claim tokens when all are already claimed
        error NoTokensHeld(); // Error for attempting to perform an action without holding tokens
        error QuorumTooHigh(); // Error for setting a quorum higher than total supply
        error AlreadyVoted(); // Error for attempting to vote more than once
        error VotingClosed(); // Error for attempting to vote on a closed issue    // Struct to represent an issue
        struct Issue {
            EnumerableSet.AddressSet voters; // Set of voters
            string issueDesc; // Description of the issue
            uint256 quorum; // Quorum required to close the issue
            uint256 totalVotes; // Total number of votes casted
            uint256 votesFor; // Total number of votes in favor
            uint256 votesAgainst; // Total number of votes against
            uint256 votesAbstain; // Total number of abstained votes
            bool passed; // Flag indicating if the issue passed
            bool closed; // Flag indicating if the issue is closed
        }    // Struct to represent a serialized issue
        struct SerializedIssue {
            address[] voters; // Array of voters
            string issueDesc; // Description of the issue
            uint256 quorum; // Quorum required to close the issue
            uint256 totalVotes; // Total number of votes casted
            uint256 votesFor; // Total number of votes in favor
            uint256 votesAgainst; // Total number of votes against
            uint256 votesAbstain; // Total number of abstained votes
            bool passed; // Flag indicating if the issue passed
            bool closed; // Flag indicating if the issue is closed
        }    // Enum to represent different vote options
        enum Vote {
            AGAINST,
            FOR,
            ABSTAIN
        }    // Array to store all issues
        Issue[] internal issues;    // Mapping to track if tokens are claimed by an address
        mapping(address => bool) public tokensClaimed;    uint256 public maxSupply = 1000000; // Maximum supply of tokens
        uint256 public claimAmount = 100; // Amount of tokens to be claimed    string saltt = "any"; // Another string variable    // Constructor to initialize ERC20 token with a name and symbol
        constructor(string memory _name, string memory _symbol)
            ERC20(_name, _symbol)
        {
            issues.push(); // Pushing an empty issue to start from index 1
        }    // Function to claim tokens
        function claim() public {
            // Check if all tokens have been claimed
            if (totalSupply() + claimAmount > maxSupply) {
                revert AllTokensClaimed();
            }
            // Check if the caller has already claimed tokens
            if (tokensClaimed[msg.sender]) {
                revert TokensClaimed();
            }
            // Mint tokens to the caller
            _mint(msg.sender, claimAmount);
            tokensClaimed[msg.sender] = true; // Mark tokens as claimed
        }    // Function to create a new voting issue
        function createIssue(string calldata _issueDesc, uint256 _quorum)
            external
            returns (uint256)
        {
            // Check if the caller holds any tokens
            if (balanceOf(msg.sender) == 0) {
                revert NoTokensHeld();
            }
            // Check if the specified quorum is higher than total supply
            if (_quorum > totalSupply()) {
                revert QuorumTooHigh();
            }
            // Create a new issue and return its index
            Issue storage _issue = issues.push();
            _issue.issueDesc = _issueDesc;
            _issue.quorum = _quorum;
            return issues.length - 1;
        }    // Function to get details of a voting issue
        function getIssue(uint256 _issueId)
            external
            view
            returns (SerializedIssue memory)
        {
            Issue storage _issue = issues[_issueId];
            return
                SerializedIssue({
                    voters: _issue.voters.values(),
                    issueDesc: _issue.issueDesc,
                    quorum: _issue.quorum,
                    totalVotes: _issue.totalVotes,
                    votesFor: _issue.votesFor,
                    votesAgainst: _issue.votesAgainst,
                    votesAbstain: _issue.votesAbstain,
                    passed: _issue.passed,
                    closed: _issue.closed
                });
        }    // Function to cast a vote on a voting issue
        function vote(uint256 _issueId, Vote _vote) public {
            Issue storage _issue = issues[_issueId];        // Check if the issue is closed
            if (_issue.closed) {
                revert VotingClosed();
            }
            // Check if the caller has already voted
            if (_issue.voters.contains(msg.sender)) {
                revert AlreadyVoted();
            }        uint256 nTokens = balanceOf(msg.sender);
            // Check if the caller holds any tokens
            if (nTokens == 0) {
                revert NoTokensHeld();
            }        // Update vote counts based on the vote option
            if (_vote == Vote.AGAINST) {
                _issue.votesAgainst += nTokens;
            } else if (_vote == Vote.FOR) {
                _issue.votesFor += nTokens;
            } else {
                _issue.votesAbstain += nTokens;
            }        // Add the caller to the list of voters and update total votes count
            _issue.voters.add(msg.sender);
            _issue.totalVotes += nTokens;        // Close the issue if quorum is reached and determine if it passed
            if (_issue.totalVotes >= _issue.quorum) {
                _issue.closed = true;
                if (_issue.votesFor > _issue.votesAgainst) {
                    _issue.passed = true;
                }
            }
        }
    }//CHASE
    

![](https://storage.googleapis.com/papyrus_images/6ccf80ad3b7417c05daa2aed9dcbae0514249ccef46d367239a82ea6a60c2cf9.png)

[https://docs.base.org/base-learn/docs/erc-20-token/erc-20-exercise/](https://docs.base.org/base-learn/docs/erc-20-token/erc-20-exercise/)

![](https://storage.googleapis.com/papyrus_images/e426a4e5152cec9d0ed237887324a538a4105db87526b21d532e5396a848299f.png)

Готово

Новий контракт

ERC721

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    
    // Importing OpenZeppelin ERC721 contract
    import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";// Interface for interacting with a submission contract
    interface ISubmission {
        // Struct representing a haiku
        struct Haiku {
            address author; // Address of the haiku author
            string line1; // First line of the haiku
            string line2; // Second line of the haiku
            string line3; // Third line of the haiku
        }    // Function to mint a new haiku
        function mintHaiku(
            string memory _line1,
            string memory _line2,
            string memory _line3
        ) external;    // Function to get the total number of haikus
        function counter() external view returns (uint256);    // Function to share a haiku with another address
        function shareHaiku(uint256 _id, address _to) external;    // Function to get haikus shared with the caller
        function getMySharedHaikus() external view returns (Haiku[] memory);
    }// Contract for managing Haiku NFTs
    contract HaikuNFT is ERC721, ISubmission {
        Haiku[] public haikus; // Array to store haikus
        mapping(address => mapping(uint256 => bool)) public sharedHaikus; // Mapping to track shared haikus
        uint256 public haikuCounter; // Counter for total haikus minted    // Constructor to initialize the ERC721 contract
        constructor() ERC721("HaikuNFT", "HAIKU") {
            haikuCounter = 1; // Initialize haiku counter
        }    string salt = "value"; // A private string variable    // Function to get the total number of haikus
        function counter() external view override returns (uint256) {
            return haikuCounter;
        }    // Function to mint a new haiku
        function mintHaiku(
            string memory _line1,
            string memory _line2,
            string memory _line3
        ) external override {
            // Check if the haiku is unique
            string[3] memory haikusStrings = [_line1, _line2, _line3];
            for (uint256 li = 0; li < haikusStrings.length; li++) {
                string memory newLine = haikusStrings[li];
                for (uint256 i = 0; i < haikus.length; i++) {
                    Haiku memory existingHaiku = haikus[i];
                    string[3] memory existingHaikuStrings = [
                        existingHaiku.line1,
                        existingHaiku.line2,
                        existingHaiku.line3
                    ];
                    for (uint256 eHsi = 0; eHsi < 3; eHsi++) {
                        string memory existingHaikuString = existingHaikuStrings[
                            eHsi
                        ];
                        if (
                            keccak256(abi.encodePacked(existingHaikuString)) ==
                            keccak256(abi.encodePacked(newLine))
                        ) {
                            revert HaikuNotUnique();
                        }
                    }
                }
            }        // Mint the haiku NFT
            _safeMint(msg.sender, haikuCounter);
            haikus.push(Haiku(msg.sender, _line1, _line2, _line3));
            haikuCounter++;
        }    // Function to share a haiku with another address
        function shareHaiku(uint256 _id, address _to) external override {
            require(_id > 0 && _id <= haikuCounter, "Invalid haiku ID");        Haiku memory haikuToShare = haikus[_id - 1];
            require(haikuToShare.author == msg.sender, "NotYourHaiku");        sharedHaikus[_to][_id] = true;
        }    // Function to get haikus shared with the caller
        function getMySharedHaikus()
            external
            view
            override
            returns (Haiku[] memory)
        {
            uint256 sharedHaikuCount;
            for (uint256 i = 0; i < haikus.length; i++) {
                if (sharedHaikus[msg.sender][i + 1]) {
                    sharedHaikuCount++;
                }
            }        Haiku[] memory result = new HaikuUnsupported embed;
            uint256 currentIndex;
            for (uint256 i = 0; i < haikus.length; i++) {
                if (sharedHaikus[msg.sender][i + 1]) {
                    result[currentIndex] = haikus[i];
                    currentIndex++;
                }
            }        if (sharedHaikuCount == 0) {
                revert NoHaikusShared();
            }        return result;
        }    // Custom errors
        error HaikuNotUnique(); // Error for attempting to mint a non-unique haiku
        error NotYourHaiku(); // Error for attempting to share a haiku not owned by the caller
        error NoHaikusShared(); // Error for no haikus shared with the caller
    }//CHASE
    

[https://docs.base.org/base-learn/docs/erc-721-token/erc-721-exercise/](https://docs.base.org/base-learn/docs/erc-721-token/erc-721-exercise/)

---

*Originally published on [Abramovich](https://paragraph.com/@ryslik/base-camp-guild)*
