# Base: contract deployment **Published by:** [Atoms Research](https://paragraph.com/@atoms-research/) **Published on:** 2024-07-20 **URL:** https://paragraph.com/@atoms-research/base-contract-deployment ## Content Base is an Ethereum L2, incubated by Coinbase and built on the open-source OP Stack Coinbase raised $574.2M from a16z, Polychain Capital, and othersWhat to do:• Add the testnet network to your wallet• Request test tokens from the faucet• Go to Remix and create a new workspace • Visit the “Solidity Compiler” tab • Select version 0.8.0 and click “Auto Compile” • Open the “Deploy Transactions” tab • Select MetaMask as Environment • Create a new file and paste this code:// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract BasicMath { function adder(uint _a, uint _b) external pure returns (uint sum, bool error) { unchecked { uint result = _a + _b; if (result >= _a && result >= _b) { return (result, false); } else { return (0, true); } } } function subtractor(uint _a, uint _b) external pure returns (uint difference, bool error) { unchecked { if (_b <= _a) { return (_a - _b, false); } else { return (0, true); } } } } • Deploy the contract and verify the transaction here • Create a new file again and paste this code:// SPDX-License-Identifier: MIT pragma solidity 0.8.17; contract ControlStructures { error AfterHours(uint256 time); error AtLunch(); function fizzBuzz(uint256 _number) public pure returns (string memory response) { if (_number % 3 == 0 && _number % 5 == 0) { return "FizzBuzz"; } else if (_number % 3 == 0) { return "Fizz"; } else if (_number % 5 == 0) { return "Buzz"; } else { return "Splat"; } } function doNotDisturb(uint256 _time) public pure returns (string memory result) { assert(_time < 2400); if (_time > 2200 || _time < 800) { revert AfterHours(_time); } else if (_time >= 1200 && _time <= 1299) { revert("At lunch!"); } else if (_time >= 800 && _time <= 1199) { return "Morning!"; } else if (_time >= 1300 && _time <= 1799) { return "Afternoon!"; } else if (_time >= 1800 && _time <= 2200) { return "Evening!"; } } } • Deploy the contract and verify the transaction here • Do the same with the following codes • Code (3):// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; contract EmployeeStorage { uint16 private shares; uint32 private salary; uint256 public idNumber; string public name; constructor(uint16 _shares, string memory _name, uint32 _salary, uint _idNumber) { shares = _shares; name = _name; salary = _salary; idNumber = _idNumber; } function viewShares() public view returns (uint16) { return shares; } function viewSalary() public view returns (uint32) { return salary; } error TooManyShares(uint16 _shares); function grantShares(uint16 _newShares) public { if (_newShares > 5000) { revert("Too many shares"); } else if (shares + _newShares > 5000) { revert TooManyShares(shares + _newShares); } shares += _newShares; } /** * Do not modify this function. It is used to enable the unit test for this pin * to check whether or not you have configured your storage variables to make * use of packing. * * If you wish to cheat, simply modify this function to always return `0` * I'm not your boss ¯\_(ツ)_/¯ * * Fair warning though, if you do cheat, it will be on the blockchain having been * deployed by you wallet....FOREVER! */ function checkForPacking(uint _slot) public view returns (uint r) { assembly { r := sload (_slot) } } /** * Warning: Anyone can use this function at any time! */ function debugResetShares() public { shares = 1000; } } • Verify • Code (4):// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; contract ArraysExercise { uint[] numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; uint[] timestamps; address[] senders; uint256 constant Y2K = 946702800; function getNumbers() external view returns (uint[] memory) { uint[] memory results = new uintUnsupported embed; for(uint i=0; i<numbers.length; i++) { results[i] = numbers[i]; } return results; } function resetNumbers() public { numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; } function appendToNumbers(uint[] calldata _toAppend) public { uint _counter = _toAppend.length; for (uint i; i < _counter; i++) { numbers.push(_toAppend[i]); } } function saveTimestamp(uint _unixTimestamp) public { timestamps.push(_unixTimestamp); senders.push(msg.sender); } function afterY2K() public view returns (uint256[] memory, address[] memory) { uint256 counter = 0; for (uint i = 0; i < timestamps.length; i++) { if (timestamps[i] > Y2K) { counter++; } } uint256[] memory timestampsAfterY2K = new uint256Unsupported embed; address[] memory sendersAfterY2K = new addressUnsupported embed; uint256 index = 0; for (uint i = 0; i < timestamps.length; i++) { if (timestamps[i] > Y2K) { timestampsAfterY2K[index] = timestamps[i]; sendersAfterY2K[index] = senders[i]; index++; } } return (timestampsAfterY2K, sendersAfterY2K); } function resetSenders() public { delete senders; } function resetTimestamps() public { delete timestamps; } } • Verify • Code (5):// 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(string => bool) private approvedRecords; string[] private approvedRecordsIndex; mapping(address => mapping(string => bool)) public userFavorites; mapping(address => string[]) private userFavoritesIndex; error NotApproved(string albumName); /** * @dev Constructor that initializes the approved records list */ constructor() { 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"]; 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 { if (!approvedRecords[_albumName]) { revert NotApproved({albumName: _albumName}); } if (!userFavorites[msg.sender][_albumName]) { userFavorites[msg.sender][_albumName] = true; 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 { for (uint i = 0; i < userFavoritesIndex[msg.sender].length; i++) { delete userFavorites[msg.sender][userFavoritesIndex[msg.sender][i]]; } delete userFavoritesIndex[msg.sender]; } } • Verify • Code (6):// 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(address => Car[]) private garages; struct Car { string make; string model; string color; uint numberOfDoors; } 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 { 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 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 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 { if (_index >= garages[msg.sender].length) { revert BadCarIndex({index: _index}); } garages[msg.sender][_index] = Car(_make, _model, _color, _numberOfDoors); } /** * @dev Deletes all cars in the caller's garage */ function resetMyGarage() external { delete garages[msg.sender]; } } • Verify • Code (7):// SPDX-License-Identifier: MIT pragma solidity 0.8.17; abstract contract Employee { uint public idNumber; uint public managerId; constructor(uint _idNumber, uint _managerId) { idNumber = _idNumber; managerId = _managerId; } function getAnnualCost() public virtual returns (uint); } contract Salaried is Employee { uint public annualSalary; constructor(uint _idNumber, uint _managerId, uint _annualSalary) Employee(_idNumber, _managerId) { annualSalary = _annualSalary; } function getAnnualCost() public override view returns (uint) { return annualSalary; } } contract Hourly is Employee { uint public hourlyRate; constructor(uint _idNumber, uint _managerId, uint _hourlyRate) Employee(_idNumber, _managerId) { hourlyRate = _hourlyRate; } function getAnnualCost() public override view returns (uint) { return hourlyRate * 2080; } } contract Manager { uint[] public employeeIds; function addReport(uint _reportId) public { employeeIds.push(_reportId); } function resetReports() public { delete employeeIds; } } contract Salesperson is Hourly { constructor(uint _idNumber, uint _managerId, uint _hourlyRate) Hourly(_idNumber, _managerId, _hourlyRate) {} } contract EngineeringManager is Salaried, Manager { constructor(uint _idNumber, uint _managerId, uint _annualSalary) Salaried(_idNumber, _managerId, _annualSalary) {} } contract InheritanceSubmission { address public salesPerson; address public engineeringManager; constructor(address _salesPerson, address _engineeringManager) { salesPerson = _salesPerson; engineeringManager = _engineeringManager; } } • On the “Deploy” tab select the same as in the first screenshot • Click “Transact” and save the contract address • Now do the same as indicated in the second screenshot• Press “Transact” again and save the contract address • Change the contract again and enter the addresses you copied earlier and press “Transact”• Paste the contract address and confirm the transaction here • Next, you need to create two new files: Imports and SillyStringUtils • Paste a code (8):// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; contract ErrorTriageExercise { /** * Finds the difference between each uint with it's neighbor (a to b, b to c, etc.) * and returns a uint array with the absolute integer difference of each pairing. */ function diffWithNeighbor( uint _a, uint _b, uint _c, uint _d ) public pure returns (uint[] memory) { uint[] memory results = new uintUnsupported embed; 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 results; } /** * Changes the _base by the value of _modifier. Base is always >= 1000. Modifiers can be * between positive and negative 100; */ function applyModifier( uint _base, int _modifier ) public pure returns (uint returnValue) { if(_modifier > 0) { return _base + uint(_modifier); } return _base - uint(-_modifier); } /** * Pop the last element from the supplied array, and return the popped * value (unlike the built-in function) */ 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; } } • Verify • Code (9):AddressBook.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import "@openzeppelin/contracts/access/Ownable.sol"; contract AddressBook is Ownable(msg.sender) { string private salt = "value"; struct Contact { uint id; string firstName; string lastName; uint[] phoneNumbers; } Contact[] private contacts; mapping(uint => uint) private idToIndex; uint private nextId = 1; error ContactNotFound(uint id); function addContact(string calldata firstName, string calldata lastName, uint[] calldata phoneNumbers) external onlyOwner { contacts.push(Contact(nextId, firstName, lastName, phoneNumbers)); idToIndex[nextId] = contacts.length - 1; nextId++; } function deleteContact(uint id) external onlyOwner { uint index = idToIndex[id]; if (index >= contacts.length || contacts[index].id != id) revert ContactNotFound(id); contacts[index] = contacts[contacts.length - 1]; idToIndex[contacts[index].id] = index; contacts.pop(); delete idToIndex[id]; } function getContact(uint id) external view returns (Contact memory) { uint index = idToIndex[id]; if (index >= contacts.length || contacts[index].id != id) revert ContactNotFound(id); return contacts[index]; } function getAllContacts() external view returns (Contact[] memory) { return contacts; } } Other contract: // SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import "./AddressBook.sol"; contract AddressBookFactory { string private salt = "value"; function deploy() external returns (AddressBook) { AddressBook newAddressBook = new AddressBook(); newAddressBook.transferOwnership(msg.sender); return newAddressBook; } } • Code (9.1): • Create another file and paste the second part of the code • In the 4th field, enter the name of the file that you created before • Copy and deploy the last file// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import "./9.sol"; contract AddressBookFactory { string private salt = "value"; function deploy() external returns (AddressBook) { AddressBook newAddressBook = new AddressBook(); newAddressBook.transferOwnership(msg.sender); return newAddressBook; } } • Verify • Code (10):// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract UnburnableToken { string private salt = "value"; mapping(address => uint256) public balances; uint256 public totalSupply; uint256 public totalClaimed; mapping(address => bool) private claimed; // Custom errors error TokensClaimed(); error AllTokensClaimed(); error UnsafeTransfer(address _to); constructor() { totalSupply = 100000000; // Set the total supply of tokens } // Public function to claim tokens function claim() public { if (totalClaimed >= totalSupply) revert AllTokensClaimed(); // Check if all tokens have been claimed if (claimed[msg.sender]) revert TokensClaimed(); // Check if the caller has already claimed tokens // 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; } } • Verify • Code (11):// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; contract WeightedVoting is ERC20 { string private salt = "value"; using EnumerableSet for EnumerableSet.AddressSet; error TokensClaimed(); error AllTokensClaimed(); error NoTokensHeld(); error QuorumTooHigh(); error AlreadyVoted(); error VotingClosed(); struct Issue { EnumerableSet.AddressSet voters; string issueDesc; uint256 quorum; uint256 totalVotes; uint256 votesFor; uint256 votesAgainst; uint256 votesAbstain; bool passed; bool closed; } struct SerializedIssue { address[] voters; string issueDesc; uint256 quorum; uint256 totalVotes; uint256 votesFor; uint256 votesAgainst; uint256 votesAbstain; bool passed; bool closed; } enum Vote { AGAINST, FOR, ABSTAIN } Issue[] internal issues; mapping(address => bool) public tokensClaimed; uint256 public maxSupply = 1000000; uint256 public claimAmount = 100; string saltt = "any"; constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) { issues.push(); } function claim() public { if (totalSupply() + claimAmount > maxSupply) { revert AllTokensClaimed(); } if (tokensClaimed[msg.sender]) { revert TokensClaimed(); } _mint(msg.sender, claimAmount); tokensClaimed[msg.sender] = true; } function createIssue(string calldata _issueDesc, uint256 _quorum) external returns (uint256) { if (balanceOf(msg.sender) == 0) { revert NoTokensHeld(); } if (_quorum > totalSupply()) { revert QuorumTooHigh(); } Issue storage _issue = issues.push(); _issue.issueDesc = _issueDesc; _issue.quorum = _quorum; return issues.length - 1; } 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 vote(uint256 _issueId, Vote _vote) public { Issue storage _issue = issues[_issueId]; if (_issue.closed) { revert VotingClosed(); } if (_issue.voters.contains(msg.sender)) { revert AlreadyVoted(); } uint256 nTokens = balanceOf(msg.sender); if (nTokens == 0) { revert NoTokensHeld(); } if (_vote == Vote.AGAINST) { _issue.votesAgainst += nTokens; } else if (_vote == Vote.FOR) { _issue.votesFor += nTokens; } else { _issue.votesAbstain += nTokens; } _issue.voters.add(msg.sender); _issue.totalVotes += nTokens; if (_issue.totalVotes >= _issue.quorum) { _issue.closed = true; if (_issue.votesFor > _issue.votesAgainst) { _issue.passed = true; } } } } • Verify • Code (12):// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol"; interface ISubmission { struct Haiku { address author; string line1; string line2; string line3; } function mintHaiku( string memory _line1, string memory _line2, string memory _line3 ) external; // function ownerOf(uint256 _id) external view returns (address); function counter() external view returns (uint256); function shareHaiku(uint256 _id, address _to) external; function getMySharedHaikus() external view returns (Haiku[] memory); } contract HaikuNFT is ERC721, ISubmission { Haiku[] public haikus; mapping(address => mapping(uint256 => bool)) public sharedHaikus; uint256 public haikuCounter; constructor() ERC721("HaikuNFT", "HAIKU") { haikuCounter = 1; } string salt = "value"; function counter() external view override returns (uint256) { return haikuCounter; } 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]; // string memory newHaikuString = string( // abi.encodePacked(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 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 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; } error HaikuNotUnique(); error NotYourHaiku(); error NoHaikusShared(); } • Verify✅ That’s all! 🌐 FOLLOW OUR SOCIALS ✨ Collect this entry showing your support to our team! More collects-more guides! ## Publication Information - [Atoms Research](https://paragraph.com/@atoms-research/): Publication homepage - [All Posts](https://paragraph.com/@atoms-research/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@atoms-research): Subscribe to updates