├── .gitignore ├── .gitmodules ├── 0x0_Introduction ├── Names.sol └── README.md ├── 1x0_Variables ├── README.md └── Variables.sol ├── 1x10_Libraries ├── Library.sol └── README.md ├── 1x11_DataLocations ├── DataLocations.sol └── README.md ├── 1x12_Inheritance ├── Import.sol ├── Inheritance.sol ├── README.md └── SuperHuman.sol ├── 1x13_InteractingOtherContracts ├── Interact.sol └── README.md ├── 1x14_Interfaces ├── IToken.sol ├── Interfaces.sol ├── README.md ├── TokenA.sol ├── TokenB.sol └── Vault.sol ├── 1x15_Call ├── Call.sol └── README.md ├── 1x16_CreatingContracts ├── Create.sol └── README.md ├── 1x1_Functions ├── FunctionModifiers.sol ├── FunctionVisibility.sol ├── Functions.sol └── README.md ├── 1x2_Constructor ├── Constant.sol ├── Constructor.sol ├── Immutable.sol └── README.md ├── 1x3_ControlStructures ├── IfElse.sol ├── Loops.sol └── README.md ├── 1x4_Mappings ├── Mapping.sol └── README.md ├── 1x5_Structs&Enums ├── README.md └── StructEnum.sol ├── 1x6_Modifiers ├── Modifiers.sol └── README.md ├── 1x7_Events ├── Events.sol └── README.md ├── 1x8_SendingEthers ├── Bank.sol └── README.md ├── 1x9_Errors ├── Errors.sol └── README.md ├── 2x0_Hardhat&Ethers ├── README.md ├── boilerplate │ ├── .gitignore │ ├── hardhat.config.js │ ├── package-lock.json │ └── package.json └── lock-project │ ├── .gitignore │ ├── artifacts │ ├── @openzeppelin │ │ └── contracts │ │ │ ├── token │ │ │ └── ERC20 │ │ │ │ ├── ERC20.sol │ │ │ │ ├── ERC20.dbg.json │ │ │ │ └── ERC20.json │ │ │ │ ├── IERC20.sol │ │ │ │ ├── IERC20.dbg.json │ │ │ │ └── IERC20.json │ │ │ │ └── extensions │ │ │ │ └── IERC20Metadata.sol │ │ │ │ ├── IERC20Metadata.dbg.json │ │ │ │ └── IERC20Metadata.json │ │ │ └── utils │ │ │ └── Context.sol │ │ │ ├── Context.dbg.json │ │ │ └── Context.json │ ├── build-info │ │ └── 0d0b38c894558aa7e7bf8fc5f072b75a.json │ └── contracts │ │ ├── Lock.sol │ │ ├── Lock.dbg.json │ │ └── Lock.json │ │ └── Token.sol │ │ ├── BEEToken.dbg.json │ │ └── BEEToken.json │ ├── cache │ └── solidity-files-cache.json │ ├── contracts │ ├── Lock.sol │ └── Token.sol │ ├── hardhat.config.js │ ├── package-lock.json │ ├── package.json │ ├── scripts │ └── deploy.js │ └── test │ └── Lock-test.js ├── 2x1_HardhatAdvanced ├── README.md ├── lock-project-advanced │ ├── .gitignore │ ├── artifacts │ │ ├── @openzeppelin │ │ │ └── contracts │ │ │ │ ├── token │ │ │ │ └── ERC20 │ │ │ │ │ ├── ERC20.sol │ │ │ │ │ ├── ERC20.dbg.json │ │ │ │ │ └── ERC20.json │ │ │ │ │ ├── IERC20.sol │ │ │ │ │ ├── IERC20.dbg.json │ │ │ │ │ └── IERC20.json │ │ │ │ │ └── extensions │ │ │ │ │ └── IERC20Metadata.sol │ │ │ │ │ ├── IERC20Metadata.dbg.json │ │ │ │ │ └── IERC20Metadata.json │ │ │ │ └── utils │ │ │ │ └── Context.sol │ │ │ │ ├── Context.dbg.json │ │ │ │ └── Context.json │ │ ├── build-info │ │ │ ├── a2f01697a6889a698d47d77e24e7e1aa.json │ │ │ └── f0b57f0a294a321c51220877f1874533.json │ │ ├── contracts │ │ │ ├── Lock.sol │ │ │ │ ├── Lock.dbg.json │ │ │ │ └── Lock.json │ │ │ └── Token.sol │ │ │ │ ├── BEEToken.dbg.json │ │ │ │ └── BEEToken.json │ │ └── hardhat │ │ │ └── console.sol │ │ │ ├── console.dbg.json │ │ │ └── console.json │ ├── cache │ │ ├── hardhat-network-fork │ │ │ └── recommendations-already-shown.json │ │ └── solidity-files-cache.json │ ├── contracts │ │ ├── Lock.sol │ │ └── Token.sol │ ├── hardhat.config.js │ ├── package-lock.json │ ├── package.json │ ├── scripts │ │ └── deploy.js │ └── test │ │ ├── Lock-test.js │ │ └── Timelock-test.js └── mainnet forking example.jpeg ├── 2x2_HardhatVsFoundry ├── README.md ├── foundry │ ├── foundry.toml │ ├── remappings.txt │ ├── script │ │ └── Deploy.sol │ ├── src │ │ └── Purchase.sol │ └── test │ │ └── Purchase.t.sol └── hardhat │ ├── contracts │ └── Purchase.sol │ ├── hardhat.config.ts │ ├── scripts │ └── deploy.ts │ └── test │ └── index.ts ├── 2x4_FoundryTests ├── .gitignore ├── foundry.toml ├── remappings.txt ├── script │ └── Contract.s.sol ├── src │ └── Owner.sol └── test │ └── Owner.t.sol ├── 2x5_FoundryCheatcodes ├── .gitignore ├── foundry.toml ├── remappings.txt ├── script │ └── Contract.s.sol ├── src │ └── Cheatcodes.sol └── test │ └── Cheatcodes.t.sol ├── 2x7_Go-Ethereum ├── README.md ├── app │ ├── app.go │ └── url_mappings.go ├── build │ ├── NumStore.abi │ └── NumStore.bin ├── controllers │ ├── chain │ │ └── chain_controller.go │ ├── club │ │ └── club_controller.go │ └── contracts │ │ └── contracts_controller.go ├── domain │ ├── account.go │ ├── chain.go │ └── contracts.go ├── ethereum │ ├── chain_interaction.go │ ├── client.go │ ├── contract_interaction.go │ ├── contracts │ │ ├── NumStore.go │ │ └── NumStore.sol │ └── private.go ├── go.mod ├── go.sum ├── main.go ├── services │ ├── chain_services.go │ └── contract_services.go └── utils │ ├── error_utils │ ├── errors.go │ └── rest_errors.go │ └── ethereum_utils │ └── ethereum_utils.go ├── 3x0_CustomAndBuiltInHooks ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── hooks │ └── useRandomUser.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js ├── 3x1_WalletConnection ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js ├── 3x2_ContractInteraction ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── constants │ ├── abi.js │ └── addresses.js │ ├── hooks │ └── useLockContract.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js ├── 3x3_SendingTransactions ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── constants │ ├── abi.js │ └── addresses.js │ ├── hooks │ ├── useAllowance.js │ └── useLockContract.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ └── setupTests.js ├── 3x4_ReduxToolkit ├── .gitignore ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── constants │ ├── abi.js │ └── addresses.js │ ├── hooks │ ├── useAddress.js │ ├── useProvider.js │ └── useSigner.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ ├── setupTests.js │ └── store │ ├── index.js │ └── slicers │ ├── contracts.js │ └── data.js ├── 3x5_EventListening ├── .gitignore ├── LockContract │ ├── Lock.sol │ └── Token.sol ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── constants │ ├── abi.js │ └── addresses.js │ ├── hooks │ ├── useAddress.js │ ├── useProvider.js │ └── useSigner.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ ├── setupTests.js │ └── store │ ├── index.js │ └── slicers │ ├── contracts.js │ └── data.js ├── 3x6_MetamaskManagement ├── .gitignore ├── LockContract │ ├── Lock.sol │ └── Token.sol ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── constants │ ├── abi.js │ ├── addresses.js │ └── networks.js │ ├── hooks │ ├── useAddress.js │ ├── useProvider.js │ └── useSigner.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ ├── setupTests.js │ └── store │ ├── index.js │ └── slicers │ ├── contracts.js │ └── data.js ├── 3x7_Web3Modal ├── .env ├── .gitignore ├── LockContract │ ├── Lock.sol │ └── Token.sol ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── constants │ ├── abi.js │ ├── addresses.js │ └── networks.js │ ├── hooks │ ├── useAddress.js │ ├── useProvider.js │ └── useSigner.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── reportWebVitals.js │ ├── setupTests.js │ ├── store │ ├── index.js │ └── slicers │ │ ├── contracts.js │ │ └── data.js │ └── web3modal │ ├── index.js │ └── useWalletConnection.js ├── 4x0_SmartContractSecurity_1 ├── Exploit1.sol ├── Exploit2.sol ├── README.md └── Slides.pdf ├── 4x1_SmartContractSecurity_2 ├── Exploit3.sol ├── Exploit4.sol ├── README.md └── Slides.pdf ├── 4x4_Slither ├── BadRandomness.sol ├── README.md └── Reentrancy.sol ├── 4x5_Echidna ├── Exercise1.sol ├── Exercise2.sol ├── README.md ├── Solution1.sol ├── Solution2.sol ├── Solution5.sol └── solution5.config.yaml ├── 5x0_ERC20 ├── ERC-20 │ └── ERC20.sol └── README.md ├── 5x1_ERC721 ├── ERC-721 │ └── ERC721.sol └── README.md ├── 5x2_ERC1155 ├── ERC-1155 │ ├── ERC1155.sol │ └── MiniGame.sol └── README.md ├── 5x3_NFTMarketplaceContract ├── NFTMarketplace │ └── NFTMarketplace.sol └── README.md ├── 5x4_NFTMarketplace_Interface ├── NFTMarketplace_Interface │ ├── .gitignore │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── manifest.json │ │ └── robots.txt │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── Assets │ │ └── logo.png │ │ ├── Components │ │ ├── NFT │ │ │ ├── NFT.js │ │ │ └── NFT.module.scss │ │ ├── Navbar │ │ │ ├── Navbar.js │ │ │ └── Navbar.module.scss │ │ └── index.js │ │ ├── Contract │ │ ├── Constant │ │ │ └── Info.js │ │ └── NFTMarketplace.sol │ │ ├── Hooks │ │ ├── useContractFunctions.js │ │ ├── useGetNFTs.js │ │ └── useSetAccount.js │ │ ├── Pages │ │ ├── Auctions │ │ │ ├── Auctions.js │ │ │ └── Auctions.module.scss │ │ ├── Home │ │ │ ├── Home.js │ │ │ └── Home.module.scss │ │ ├── ListedItems │ │ │ ├── ListedItems.js │ │ │ └── ListedItems.module.scss │ │ ├── MyNFTs │ │ │ ├── MyNFTs.js │ │ │ └── MyNFTs.module.scss │ │ └── index.js │ │ ├── Store │ │ ├── index.js │ │ └── slicers │ │ │ └── accounts.js │ │ ├── index.js │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ └── utils │ │ ├── clsnm.js │ │ └── parseAddress.js └── README.md ├── 5x5_MultisigWallet ├── MultiSig.sol ├── README.md ├── accmodel.png ├── accstxs.png ├── eoainnw.png └── multisig.png ├── 5x6_SimpleBasketballGame ├── README.md └── contracts │ ├── Game.sol │ ├── Marketplace.sol │ ├── Team.sol │ └── tokens │ └── W3J721.sol ├── 5x7_StakingContract ├── README.md └── StakingContract.sol ├── 5x8_BasicDEX&AMM ├── .gitignore ├── README.md ├── contracts │ └── Exchange.sol ├── hardhat.config.js ├── package.json └── yarn.lock ├── 6x0_MerkleTrees ├── .gitignore ├── Merkle.sol ├── README.md ├── WLMint.sol ├── hashtree.png ├── merkle.js └── package.json ├── 6x3_ChainlinkApplication ├── ChainlinkApplication │ ├── ChainlinkApplication.sol │ ├── ConfirmedOwner.sol │ ├── ConfirmedOwnerWithProposal.sol │ └── interfaces │ │ ├── AggregatorV3Interface.sol │ │ ├── OwnableInterface.sol │ │ ├── VRFConsumerBaseV2.sol │ │ └── VRFCoordinatorV2Interface.sol └── README.md ├── 6x4_LayerZeroApplication ├── LayerZeroApplication │ ├── LzApp.sol │ ├── NonblockingLzApp.sol │ ├── OmniCounter.sol │ ├── interfaces │ │ ├── ILayerZeroEndpoint.sol │ │ ├── ILayerZeroReceiver.sol │ │ └── ILayerZeroUserApplicationConfig.sol │ └── util │ │ ├── BytesLib.sol │ │ └── ExcessivelySafeCall.sol └── README.md ├── 7x0_PatikaLendingWorkshop ├── Intro.pdf ├── Lending.sol ├── README.md └── USD.sol ├── README.md ├── itublockchain&ef.png └── videoimgs ├── 0x0.png ├── 1x0.png ├── 1x1.png ├── 1x10.png ├── 1x11.png ├── 1x12.png ├── 1x13.png ├── 1x14.png ├── 1x15.png ├── 1x16.png ├── 1x2.png ├── 1x3.png ├── 1x4.png ├── 1x5.png ├── 1x6.png ├── 1x7.png ├── 1x8.png ├── 1x9.png ├── 2x0.png ├── 2x1.png ├── 2x2.png ├── 2x3.png ├── 2x4.png ├── 2x5.png ├── 2x6.png ├── 2x7.png ├── 2x8.png ├── 3x0.png ├── 3x1.png ├── 3x2.png ├── 3x3.png ├── 3x4.png ├── 3x5.png ├── 3x6.png ├── 3x7.png ├── 3x8.png ├── 4x0.png ├── 4x1.png ├── 4x2.png ├── 4x3.png ├── 4x4.png ├── 4x5.png ├── 5x0.png ├── 5x1.png ├── 5x10.png ├── 5x11.png ├── 5x12.png ├── 5x2.png ├── 5x3.png ├── 5x4.png ├── 5x5.png ├── 5x6.png ├── 5x7.png ├── 5x8.png ├── 5x9.png ├── 6x0.png ├── 6x1.png ├── 6x2.png ├── 6x3.png ├── 6x4.png ├── announce.png └── otopsi.jpeg /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "2x4_FoundryTests/lib/forge-std"] 2 | path = 2x4_FoundryTests/lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | [submodule "2x5_FoundryCheatcodes/lib/forge-std"] 5 | path = 2x5_FoundryCheatcodes/lib/forge-std 6 | url = https://github.com/foundry-rs/forge-std 7 | -------------------------------------------------------------------------------- /0x0_Introduction/Names.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "@openzeppelin/contracts/access/Ownable.sol"; 5 | 6 | contract Names is Ownable { 7 | string public ownerName; 8 | string[] public names; 9 | int256 private luckyNumber; 10 | 11 | constructor(string memory _ownerName, int256 _luckyNumber) { 12 | ownerName = _ownerName; 13 | names.push(_ownerName); 14 | luckyNumber = _luckyNumber; 15 | } 16 | 17 | function addMyName(string memory _myName) public { 18 | names.push(_myName); 19 | } 20 | 21 | function isAdded(string memory _name) public view returns (bool) { 22 | for (uint256 i = 0; i < names.length; i++) { 23 | if ( 24 | keccak256(abi.encodePacked((_name))) == 25 | keccak256(abi.encodePacked((names[i]))) 26 | ) return true; 27 | } 28 | return false; 29 | } 30 | 31 | function getNames() public view returns (string[] memory) { 32 | return names; 33 | } 34 | 35 | function nameCount() public view returns (uint256) { 36 | return names.length; 37 | } 38 | 39 | function changeOwnersName(string memory _ownerName) public onlyOwner { 40 | ownerName = _ownerName; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /1x10_Libraries/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde Library konusunu işledik. 4 | 5 | `library`: Kontratlara benzer fakat ether alamaması ve durum değişkeni tutamaması ile farklılaşır. Kontratların içerisine gömülü fonksiyonların eklenmesine benzetilebilir. 6 | 7 | `using for ` tanımlaması ile de kullanılabilir. 8 | 9 | [Video İçeriği](https://www.youtube.com/watch?v=azSY27x8pxc&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=12) 10 | 11 | [Library](./Library.sol) -------------------------------------------------------------------------------- /1x11_DataLocations/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu derste "Data Locations" konusunu işledik 4 | 5 | TLDR; 6 | EVM'de 3 çeşit hafıza alanı (data location) bulunur. 7 | - `storage`: Bu veriler blokzincirde tutulur 8 | - `memory` : Bu veriler fonksiyon çağrıldıktan itibaren EVM tarafından ayrılan özel bir bölgeder tutulur ve fonksiyon bittiğinde silinir. 9 | - `calldata`: Bu veriler fonksiyon çağrılırken, çağrının (transaction) içerisinde tutulur (`msg.data`). Bu veriler sadece okunabilir. 10 | 11 | `bytes`, `string`, `uint256[]`, `struct` gibi referans tipleri fonksiyonlarda 12 | kullanılırken bu verilerin hangi hafıza alanından alınacağı belirtilmelidir. 13 | 14 | > `calldata` sadece fonksiyon parametreleri için kullanılabilir 15 | > `storage` sadece fonksiyon gövdesinde kullanılabilir 16 | 17 | ```solidity 18 | function(string memory/calldata parameterString) external { 19 | string memory/storage bodyString = ""; 20 | } 21 | ``` 22 | 23 | [Video İçeriği](https://www.youtube.com/watch?v=MzvzBp9l3y0&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=13) 24 | 25 | [Data Locations](./DataLocations.sol) 26 | -------------------------------------------------------------------------------- /1x12_Inheritance/Import.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | // import "@openzeppelin/contracts/access/Ownable.sol"; 5 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol"; 6 | 7 | contract Wallet is Ownable { 8 | fallback() payable external {} 9 | 10 | function sendEther(address payable to, uint amount) onlyOwner public { 11 | to.transfer(amount); 12 | } 13 | 14 | function showBalance() public view returns(uint) { 15 | return address(this).balance; 16 | } 17 | } -------------------------------------------------------------------------------- /1x12_Inheritance/Inheritance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | 5 | // virtual 6 | 7 | contract A { 8 | uint public x; 9 | 10 | uint public y; 11 | 12 | function setX(uint _x) virtual public { 13 | x = _x; 14 | } 15 | 16 | function setY(uint _y) virtual public { 17 | y = _y; 18 | } 19 | } 20 | // override 21 | 22 | contract B is A { 23 | 24 | uint public z; 25 | 26 | function setZ(uint _z) public { 27 | z = _z; 28 | } 29 | 30 | function setX(uint _x) override public { 31 | x = _x + 2; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /1x12_Inheritance/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu videomuzda Solidity'nin Inheritance özelliğini inceledik. Beraber "virtual, override, super, is" kelimelerinin ne olduğuna baktık. Openzeppelin Ownable contratına da göz attık. 4 | 5 | Solidity çoklu kalıtımı destekleyen bir programlama dilidir. Kontratlar `is` anahtar sözcüğü ile diğer kontratları miras olarak alabilir. 6 | 7 | `virtual`: Bir alt kontrat tarafından fonksiyonun geçersiz kılınabileceğini bildiren niteleyicidir. 8 | 9 | `override`: Bir üst kontratta bulunan `virtual` ile işaretlenmiş fonksiyonları geçersiz kılmamızı ve tekrardan tanımladığımızı bildiren niteleyicidir. 10 | 11 | Miras sırası önemlidir. C3-linearization kurallarına göre `super` anahtar sözcüğü ile miras alınan kontrata erişebiliriz. 12 | 13 | [Video İçeriği](https://www.youtube.com/watch?v=KSrhlrHlti4&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=14) 14 | 15 | [Interitance, virtual, override](./Inheritance.sol) 16 | 17 | [Super](./SuperHuman.sol) 18 | 19 | [Import](./Import.sol) -------------------------------------------------------------------------------- /1x12_Inheritance/SuperHuman.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Human { 5 | function sayHello() public pure virtual returns(string memory) { 6 | return "itublockchain.com adresi uzerinden kulube uye olabilirsiniz :)"; 7 | } 8 | } 9 | 10 | contract SuperHuman is Human { 11 | function sayHello() public pure override returns(string memory) { 12 | return "Selamlar itu blockchain uyesi, nasilsin ? :)"; 13 | } 14 | 15 | function welcomeMsg(bool isMember) public pure returns(string memory) { 16 | return isMember ? sayHello() : super.sayHello(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /1x13_InteractingOtherContracts/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde akıllı kontratlarda farklı akıllı kontratlarla etkileşmeyi gösterdik. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=BWC-Rlkjs54&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=15) 6 | 7 | [Akıllı Kontrat Örneği](./Interact.sol) -------------------------------------------------------------------------------- /1x14_Interfaces/IToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface IToken { 5 | // Fonksiyonlarda override gerekli 6 | function transferFrom(address from, address to, uint256 amount) external; 7 | function transfer(address to, uint256 amount) external; 8 | function balanceOf(address user) external view returns(uint256); 9 | 10 | // Eventlerde gerekli değil 11 | event Transfer(address indexed from, address indexed to, uint256 amount); 12 | } 13 | -------------------------------------------------------------------------------- /1x14_Interfaces/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde Interfaces konusunu işledik. 4 | 5 | Interface'ler (Arayüzler) çalışma mantığı farklı olan ama yaptığı iş aynı olan kontratların (örneğin token kontratları) ortak bir standarda sahip olmasını böylece bu kontratlarla çalışmak isteyen birinin her bir kontrata özgü kod yazmak yerine bu standarda uygun tek bir kod yazmasını sağlar 6 | 7 | ERC20, ERC721, ERC1155 gibi standartlar aslında bir interface şeklinde tanımlanmıştır. 8 | 9 | bkz. [IERC20 standardı](https://eips.ethereum.org/EIPS/eip-20) 10 | 11 | bkz. [IERC20 interface](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) 12 | 13 | 14 | [Interfaces](./Interfaces.sol) 15 | 16 | [Vault](./Vault.sol) 17 | 18 | [IToken](./IToken.sol) 19 | 20 | [TokenA](./TokenA.sol) 21 | 22 | [TokenB](./TokenB.sol) 23 | 24 | [Video İçeriği](https://www.youtube.com/watch?v=QZDvZD-lczM&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=16) -------------------------------------------------------------------------------- /1x14_Interfaces/Vault.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "./IToken.sol"; 5 | 6 | /// @title Vault 7 | /// @notice Allows users to deposit and withdraw any token (?) 8 | contract Vault { 9 | /// @dev User -> Token -> Balance 10 | mapping(address => mapping(IToken => uint256)) tokenBalances; 11 | 12 | function depositToken(IToken token, uint256 amount) external { 13 | token.transferFrom(msg.sender, address(this), amount); 14 | tokenBalances[msg.sender][token] += amount; 15 | } 16 | 17 | function withdrawToken(IToken token, uint256 amount) external { 18 | tokenBalances[msg.sender][token] -= amount; 19 | token.transfer(msg.sender, amount); 20 | } 21 | 22 | function getBalanceOf(address user, IToken token) external view returns(uint256) { 23 | return token.balanceOf(user); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /1x15_Call/Call.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Test { 5 | uint256 public total = 0; 6 | uint256 public fallbackCalled = 0; 7 | string public incrementer; 8 | 9 | fallback() external payable { 10 | fallbackCalled += 1; 11 | } 12 | 13 | function inc(uint256 _amount, string memory _incrementer) external returns(uint256) { 14 | total += _amount; 15 | incrementer = _incrementer; 16 | 17 | return total; 18 | } 19 | } 20 | 21 | contract Caller { 22 | 23 | function testCall(address _contract, uint256 _amount, string memory _incrementer) external returns (bool, uint256) { 24 | (bool err, bytes memory res) = _contract.call(abi.encodeWithSignature("inc(uint256, string)", _amount, _incrementer)); 25 | uint256 _total = abi.decode(res, (uint256)); 26 | return (err, _total); 27 | } 28 | 29 | function payToFallback(address _contract) external payable { 30 | (bool err,) = _contract.call{value: msg.value}(""); 31 | 32 | if(!err) revert(); 33 | } 34 | 35 | 36 | } -------------------------------------------------------------------------------- /1x15_Call/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde "call" methodu aracılığıyla low-level çağrılar yapma konusunu inceledik. 4 | 5 | [Video İçeriği](https://www.youtube.com/playlist?list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73) 6 | 7 | [Call Methodu Kontrat Örneği](./Call.sol) -------------------------------------------------------------------------------- /1x16_CreatingContracts/Create.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract VaultFactory { 5 | mapping(address => Vault[]) public userVaults; 6 | 7 | function createVault() external { 8 | Vault vault = new Vault(msg.sender); 9 | userVaults[msg.sender].push(vault); 10 | } 11 | 12 | function createVaultWithPayment() external payable { 13 | Vault vault = (new Vault){value: msg.value}(msg.sender); 14 | userVaults[msg.sender].push(vault); 15 | } 16 | } 17 | 18 | contract Vault { 19 | address public owner; 20 | uint256 private balance; 21 | 22 | constructor(address _owner) payable { 23 | owner = _owner; 24 | balance += msg.value; 25 | } 26 | 27 | fallback() external payable { 28 | balance += msg.value; 29 | } 30 | 31 | receive() external payable { 32 | balance += msg.value; 33 | } 34 | 35 | function getBalance() external view returns (uint256) { 36 | return balance; 37 | } 38 | 39 | function deposit() external payable { 40 | balance += msg.value; 41 | } 42 | 43 | function withdraw(uint256 _amount) external { 44 | require(msg.sender == owner, "You are not authorized."); 45 | balance -= _amount; 46 | payable(owner).transfer(_amount); 47 | } 48 | } -------------------------------------------------------------------------------- /1x16_CreatingContracts/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde akıllı kontratlar aracılığıyla farklı akıllı kontratlar deploy etme konusunu inceledik. 4 | 5 | [Video İçeriği](https://www.youtube.com/playlist?list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73) 6 | 7 | [Factory Kontrat Örneği](./Create.sol) -------------------------------------------------------------------------------- /1x1_Functions/FunctionModifiers.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | 5 | contract Functions { 6 | 7 | //View 8 | 9 | uint public number = 3; 10 | 11 | function addToX(uint y) public view returns(uint){ 12 | return number + y; 13 | } 14 | 15 | function addAndView(uint a, uint b) public view returns (uint) { 16 | return a * (b + 42) + block.timestamp; 17 | } 18 | 19 | //Pure 20 | 21 | function addAndPure(uint a, uint b) public pure returns (uint) { 22 | return a * (b + 42); 23 | } 24 | 25 | function hello() pure public returns(string memory) { 26 | return 'Hello World!'; 27 | } 28 | 29 | 30 | 31 | } -------------------------------------------------------------------------------- /1x1_Functions/Functions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | 5 | contract Functions { 6 | 7 | uint luckyNumber = 7; 8 | 9 | function showNumber() public view returns(uint) { 10 | return luckyNumber; 11 | } 12 | 13 | function setNumber( uint _newNumber) public { 14 | luckyNumber = _newNumber; 15 | } 16 | 17 | function nothing() public pure returns(uint, bool, bool) { 18 | return (5, true, false); 19 | } 20 | 21 | function nothing2() public pure returns(uint x, bool y, bool z) { 22 | x = 5; 23 | y = true; 24 | z = false; 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /1x1_Functions/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde "Functions, Function Modifiers and Function Visibility" konularını işledik. 4 | 5 | Fonksiyon Niteleyicileri 6 | 7 | `view`: Fonksiyonun blokchain'den veri okuyacağını fakat üzerinde değişiklik yapmayacağını bildirir. 8 | ```solidity 9 | contract View { 10 | uint x = 7; 11 | 12 | function show() 13 | public 14 | view 15 | returns(uint) 16 | { 17 | return x; 18 | } 19 | } 20 | ``` 21 | `pure`: Fonksiyonun blokchain'den hem veri okumayacağını hem de değişiklik yapmayacağını bildirir. 22 | ```solidity 23 | contract Pure { 24 | function add(uint x, uint y) 25 | public 26 | pure 27 | returns(uint) 28 | { 29 | return x + y; 30 | } 31 | } 32 | ``` 33 | 34 | Fonksiyon Görünürlükleri 35 | 36 | - `public`: Herhangi bir akıllı kontrat ve hesap çağırabilir. 37 | - `private`: Yalnızca fonksiyonun tanımlı olduğu kontratın içerisinde çağırılabilir. 38 | - `internal`: Tanımlı olduğu kontrat ile birlikte miras olarak alındığı kontrat tarafından da çağırılabili., 39 | - `external`: Yalnızca diğer akıllı kontratlar ve hesaplar tarafından çağıralabilir. 40 | 41 | 42 | [Video İçeriği](https://www.youtube.com/watch?v=J_B_uPnspws&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=3) 43 | 44 | [Functions](./Functions.sol) 45 | 46 | [Function Modifiers](./FunctionModifiers.sol) 47 | 48 | [Function Visibility](./FunctionVisibility.sol) 49 | -------------------------------------------------------------------------------- /1x2_Constructor/Constant.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Constants { 5 | 6 | address public constant MY_ADDRESS = 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc; 7 | uint public constant MY_UINT = 123; 8 | 9 | } -------------------------------------------------------------------------------- /1x2_Constructor/Constructor.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Constructor{ 5 | 6 | string public tokenName; 7 | uint public totalSupply; 8 | 9 | constructor(string memory name, uint number) { 10 | tokenName = name; 11 | totalSupply = number; 12 | } 13 | 14 | function set(uint number) public { 15 | totalSupply = number; 16 | } 17 | } -------------------------------------------------------------------------------- /1x2_Constructor/Immutable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Immutable { 5 | 6 | address public immutable MY_ADDRESS; 7 | uint public immutable MY_LUCKYNUMBER; 8 | 9 | constructor(uint _myNumber) { 10 | MY_ADDRESS = msg.sender; 11 | MY_LUCKYNUMBER = _myNumber; 12 | } 13 | } -------------------------------------------------------------------------------- /1x2_Constructor/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde "Constructor, Constant & Immutable" konusunu işledik. 4 | 5 | `constructor`: Kontrat deploy edilirken yalnızca bir kere çalışan, daha sonrada bir daha çağırılamayan isteğe bağlı bir fonksiyondur. 6 | 7 | ```solidity 8 | contract Constructor { 9 | uint x; 10 | 11 | constructor(uint _x) { 12 | x = _x; 13 | } 14 | } 15 | ``` 16 | 17 | `constant`: Değeri değiştirilemeyen değişkenlerdir. Atanan değer kontrat deploy edildikten sonra bir daha değiştirilemez. Gaz maaliyetinden tasarruf sağlayabilir. 18 | 19 | `immutable`: Değeri değiştirilemeyen değişkenlerdir. Constant'tan farkı immutable ile işaretlenmiş değişkenin değerinin constructor ile başlangıçta değiştirilebiliyor oluşudur. 20 | 21 | 22 | 23 | [Video İçeriği](https://www.youtube.com/watch?v=XQR2tL4v0_c&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=4) 24 | 25 | [Constructor](./Constructor.sol) 26 | 27 | [Constant](./Constant.sol) 28 | 29 | [Immutable](./Immutable.sol) 30 | -------------------------------------------------------------------------------- /1x3_ControlStructures/Loops.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Loops { 5 | uint256[15] public numbers0; 6 | uint256[15] public numbers1; 7 | bool public state = true; 8 | int256 public num = 0; 9 | 10 | function listByFor() public { 11 | uint256[15] memory nums = numbers0; 12 | 13 | for (uint256 i = 0; i < nums.length; i++) { 14 | //if(i == 13) continue; 15 | //if(i == 14) break; 16 | nums[i] = i; 17 | } 18 | 19 | numbers0 = nums; 20 | } 21 | 22 | function getArr0() public view returns (uint256[15] memory) { 23 | return numbers0; 24 | } 25 | 26 | function listByWhile() public { 27 | uint256 i = 0; 28 | while (i < numbers1.length) { 29 | numbers1[i] = i; 30 | i++; 31 | } 32 | } 33 | 34 | function getArr1() public view returns (uint256[15] memory) { 35 | return numbers1; 36 | } 37 | 38 | function crashByWhile() public { 39 | while (state) { 40 | num++; 41 | num--; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /1x3_ControlStructures/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde "Control Structures" konusunu, yani If-Else kontrol yapılarını ve For - While döngülerini işledik. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=a9PtEe3CXSg&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=5) 6 | 7 | [If Else Koşul Yapıları Kontrat Örneği](./IfElse.sol) 8 | 9 | [For - While Döngüleri Kontrat Örneği](./Loops.sol) 10 | -------------------------------------------------------------------------------- /1x4_Mappings/Mapping.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Mapping { 5 | mapping(address => bool) public registered; 6 | mapping(address => int256) public favNums; 7 | 8 | function register(int256 _favNum) public { 9 | //require(!registered[msg.sender], "Kullanıcınız daha önce kayıt yaptı."); 10 | require(!isRegistered(), "Kullaniciniz daha once kayit yapti."); 11 | registered[msg.sender] = true; 12 | favNums[msg.sender] = _favNum; 13 | } 14 | 15 | function isRegistered() public view returns (bool) { 16 | return registered[msg.sender]; 17 | } 18 | 19 | function deleteRegistered() public { 20 | require(isRegistered(), "Kullaniciniz kayitli degil."); 21 | delete (registered[msg.sender]); 22 | delete (favNums[msg.sender]); 23 | } 24 | } 25 | 26 | contract NestedMapping { 27 | mapping(address => mapping(address => uint256)) public debts; 28 | 29 | function incDebt(address _borrower, uint256 _amount) public { 30 | debts[msg.sender][_borrower] += _amount; 31 | } 32 | 33 | function decDebt(address _borrower, uint256 _amount) public { 34 | require(debts[msg.sender][_borrower] >= _amount, "Not enough debt."); 35 | debts[msg.sender][_borrower] -= _amount; 36 | } 37 | 38 | function getDebt(address _borrower) public view returns (uint256) { 39 | return debts[msg.sender][_borrower]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /1x4_Mappings/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde Mapping veri tipini inceledik. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=aZDdyhfesEc&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=6) 6 | 7 | [Mappings Kontrat Örneği](./Mapping.sol) -------------------------------------------------------------------------------- /1x5_Structs&Enums/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde Struct ve Enum veri tiplerini inceledik. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=lV_QtWkp3MY&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=7) 6 | 7 | [Struct & Enum Kontrat Örneği](./StructEnum.sol) -------------------------------------------------------------------------------- /1x6_Modifiers/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde Modifiers konusunu işledik. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=58MDeT4hoig&t=3s) 6 | 7 | [Modifier Kontrat Örneği](./Modifiers.sol) 8 | 9 | [Remix Desktop](https://github.com/ethereum/remix-desktop/releases) 10 | 11 | [Remixd](https://remix-ide.readthedocs.io/en/latest/remixd.html) -------------------------------------------------------------------------------- /1x7_Events/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde Event konusunu inceledik. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=wM63xPvUekM) 6 | 7 | [Events Kontrat Örneği](./Events.sol) -------------------------------------------------------------------------------- /1x8_SendingEthers/Bank.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Bank { 5 | 6 | mapping(address => uint ) balances; 7 | 8 | function sendEtherToContract() payable external { 9 | balances[msg.sender] = msg.value; 10 | } 11 | 12 | function showBalance() external view returns(uint) { 13 | return balances[msg.sender]; 14 | } 15 | 16 | function withdraw(address payable to, uint amount) external { 17 | // require(balances[msg.sender] >= amount,"yetersiz bakiye"); 18 | to.transfer(amount); 19 | balances[to] += amount; 20 | balances[msg.sender] -= amount; 21 | } 22 | 23 | // Transfer() 24 | // Revert 25 | 26 | // Send() 27 | // true, false 28 | 29 | // Call() 30 | // bool, data 31 | 32 | uint public receiveCount = 0; 33 | uint public fallbackCount = 0; 34 | 35 | receive() external payable { 36 | receiveCount +=1; 37 | } 38 | 39 | fallback() external payable { 40 | fallbackCount += 1; 41 | } 42 | } -------------------------------------------------------------------------------- /1x9_Errors/Errors.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | contract Errors { 5 | uint256 public totalBalance; 6 | mapping(address => uint256) public userBalances; 7 | 8 | error ExceedingAmount(address user, uint256 exceedingAmount); 9 | error Deny(string reason); 10 | 11 | receive() external payable { 12 | revert Deny("No direct payments."); 13 | } 14 | 15 | fallback() external payable { 16 | revert Deny("No direct payments."); 17 | } 18 | 19 | function pay() noZero(msg.value) external payable { 20 | require(msg.value == 1 ether, "Only payments in 1 ether"); 21 | 22 | totalBalance += 1 ether; // 1e18 23 | userBalances[msg.sender] += 1 ether; // 10000...0000 24 | } 25 | 26 | function withdraw(uint256 _amount) noZero(_amount) external { 27 | uint256 initalBalance = totalBalance; 28 | 29 | //require(userBalances[msg.sender] >= _amount, "Insufficient balance."); 30 | 31 | if(userBalances[msg.sender] < _amount) { 32 | //revert("Insufficient balance."); 33 | revert ExceedingAmount(msg.sender, _amount - userBalances[msg.sender]); 34 | } 35 | 36 | totalBalance -= _amount; 37 | userBalances[msg.sender] -= _amount; 38 | // address => address payable 39 | payable(msg.sender).transfer(_amount); 40 | 41 | assert(totalBalance < initalBalance); 42 | } 43 | 44 | modifier noZero(uint256 _amount) { 45 | require(_amount != 0); 46 | _; 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /1x9_Errors/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde Solidity'de hata mesajları yayınlayarak fonksiyonların çalışmasını engellediğimiz "error, revert, require, assert" gibi kullanımlara değindik. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=TUQzMu4DYjc&list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73&index=11) 6 | 7 | [https://www.youtube.com/playlist?list=PLby2HXktGwN4Cof_6a8YwlMrboX8-hs73](./Errors.sol) -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/boilerplate/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/boilerplate/hardhat.config.js: -------------------------------------------------------------------------------- 1 | //require("@nomiclabs/hardhat-ethers"); 2 | require("@nomiclabs/hardhat-waffle"); 3 | 4 | const PRIVATE_KEY = "PRIVATE_KEY"; 5 | 6 | 7 | module.exports = { 8 | solidity: "0.8.2", 9 | networks: { 10 | mainnet: { 11 | url: `https://api.avax.network/ext/bc/C/rpc`, 12 | accounts: [`${PRIVATE_KEY}`] 13 | }, 14 | fuji: { 15 | url: `https://api.avax-test.network/ext/bc/C/rpc`, 16 | accounts: [`${PRIVATE_KEY}`] 17 | } 18 | } 19 | }; -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/boilerplate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "project", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@nomiclabs/hardhat-ethers": "^2.0.5", 14 | "@nomiclabs/hardhat-waffle": "^2.0.3", 15 | "chai": "^4.3.6", 16 | "ethereum-waffle": "^3.4.4", 17 | "ethers": "^5.6.5", 18 | "hardhat": "^2.9.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/artifacts/@openzeppelin/contracts/token/ERC20/ERC20.sol/ERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../../build-info/0d0b38c894558aa7e7bf8fc5f072b75a.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/artifacts/@openzeppelin/contracts/token/ERC20/IERC20.sol/IERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../../build-info/0d0b38c894558aa7e7bf8fc5f072b75a.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/artifacts/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol/IERC20Metadata.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../../../build-info/0d0b38c894558aa7e7bf8fc5f072b75a.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/0d0b38c894558aa7e7bf8fc5f072b75a.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "Context", 4 | "sourceName": "@openzeppelin/contracts/utils/Context.sol", 5 | "abi": [], 6 | "bytecode": "0x", 7 | "deployedBytecode": "0x", 8 | "linkReferences": {}, 9 | "deployedLinkReferences": {} 10 | } 11 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/artifacts/contracts/Lock.sol/Lock.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/0d0b38c894558aa7e7bf8fc5f072b75a.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/artifacts/contracts/Token.sol/BEEToken.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/0d0b38c894558aa7e7bf8fc5f072b75a.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/contracts/Lock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "./Token.sol"; 5 | 6 | contract Lock { 7 | BEEToken Token; 8 | uint256 public lockerCount; 9 | uint256 public totalLocked; 10 | mapping(address => uint256) public lockers; 11 | 12 | constructor(address tokenAddress) { 13 | Token = BEEToken(tokenAddress); 14 | } 15 | 16 | function lockTokens(uint256 amount) external { 17 | require(amount > 0, "Token amount must be bigger than 0."); 18 | 19 | // require(Token.balanceOf(msg.sender) >= amount, "Insufficient balance."); 20 | // require(Token.allowance(msg.sender, address(this)) >= amount, "Insufficient allowance."); 21 | 22 | if(!(lockers[msg.sender] > 0)) lockerCount++; 23 | totalLocked += amount; 24 | lockers[msg.sender] += amount; 25 | 26 | bool ok = Token.transferFrom(msg.sender, address(this), amount); 27 | require(ok, "Transfer failed."); 28 | } 29 | 30 | function withdrawTokens() external { 31 | require(lockers[msg.sender] > 0, "Not enough token."); 32 | uint256 amount = lockers[msg.sender]; 33 | delete(lockers[msg.sender]); 34 | totalLocked -= amount; 35 | lockerCount--; 36 | require(Token.transfer(msg.sender, amount), "Transfer failed."); 37 | } 38 | } -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/contracts/Token.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract BEEToken is ERC20 { 7 | constructor() ERC20("BEE Token", "BEE") { 8 | _mint(msg.sender, 1773000 * 10**decimals()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/hardhat.config.js: -------------------------------------------------------------------------------- 1 | //require("@nomiclabs/hardhat-ethers"); 2 | require("@nomiclabs/hardhat-waffle"); 3 | 4 | const PRIVATE_KEY = "KEY"; 5 | 6 | 7 | module.exports = { 8 | solidity: "0.8.2", 9 | networks: { 10 | mainnet: { 11 | url: `https://api.avax.network/ext/bc/C/rpc`, 12 | accounts: [`${PRIVATE_KEY}`] 13 | }, 14 | fuji: { 15 | url: `https://api.avax-test.network/ext/bc/C/rpc`, 16 | accounts: [`${PRIVATE_KEY}`] 17 | } 18 | } 19 | }; -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lock-project", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@nomiclabs/hardhat-ethers": "^2.0.5", 14 | "@nomiclabs/hardhat-waffle": "^2.0.3", 15 | "chai": "^4.3.6", 16 | "ethereum-waffle": "^3.4.4", 17 | "ethers": "^5.6.5", 18 | "hardhat": "^2.9.3" 19 | }, 20 | "dependencies": { 21 | "@openzeppelin/contracts": "^4.6.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /2x0_Hardhat&Ethers/lock-project/scripts/deploy.js: -------------------------------------------------------------------------------- 1 | const { ethers } = require("hardhat"); 2 | 3 | async function main() { 4 | const [deployer] = await ethers.getSigners(); 5 | 6 | const Lock = await ethers.getContractFactory("Lock"); 7 | const lock = await Lock.deploy("0xa9d19d5e8712C1899C4344059FD2D873a3e2697E"); 8 | 9 | console.log("Contract address:", lock.address); 10 | } 11 | 12 | main() 13 | .then(() => process.exit(0)) 14 | .catch((error) => { 15 | console.error(error); 16 | process.exit(1); 17 | }); 18 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/@openzeppelin/contracts/token/ERC20/ERC20.sol/ERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../../build-info/a2f01697a6889a698d47d77e24e7e1aa.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/@openzeppelin/contracts/token/ERC20/IERC20.sol/IERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../../build-info/a2f01697a6889a698d47d77e24e7e1aa.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol/IERC20Metadata.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../../../build-info/a2f01697a6889a698d47d77e24e7e1aa.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/a2f01697a6889a698d47d77e24e7e1aa.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/@openzeppelin/contracts/utils/Context.sol/Context.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "Context", 4 | "sourceName": "@openzeppelin/contracts/utils/Context.sol", 5 | "abi": [], 6 | "bytecode": "0x", 7 | "deployedBytecode": "0x", 8 | "linkReferences": {}, 9 | "deployedLinkReferences": {} 10 | } 11 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/contracts/Lock.sol/Lock.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/f0b57f0a294a321c51220877f1874533.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/contracts/Token.sol/BEEToken.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/a2f01697a6889a698d47d77e24e7e1aa.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/hardhat/console.sol/console.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/f0b57f0a294a321c51220877f1874533.json" 4 | } 5 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/artifacts/hardhat/console.sol/console.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "console", 4 | "sourceName": "hardhat/console.sol", 5 | "abi": [], 6 | "bytecode": "0x60566050600b82828239805160001a6073146043577f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e047e2b22c935db96ddc7fd6e285df0242f18674eeadcc9648816130ba34ddfb64736f6c63430008020033", 7 | "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e047e2b22c935db96ddc7fd6e285df0242f18674eeadcc9648816130ba34ddfb64736f6c63430008020033", 8 | "linkReferences": {}, 9 | "deployedLinkReferences": {} 10 | } 11 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/cache/hardhat-network-fork/recommendations-already-shown.json: -------------------------------------------------------------------------------- 1 | true 2 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/contracts/Token.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract BEEToken is ERC20 { 7 | constructor() ERC20("BEE Token", "BEE") { 8 | _mint(msg.sender, 1773000 * 10**decimals()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | 3 | const PRIVATE_KEY = "KEY"; 4 | 5 | module.exports = { 6 | solidity: "0.8.2", 7 | networks: { 8 | 9 | hardhat: { 10 | forking: { 11 | url: "ALCHEMY_API", 12 | } 13 | }, 14 | 15 | mainnet: { 16 | url: `https://api.avax.network/ext/bc/C/rpc`, 17 | accounts: [`${PRIVATE_KEY}`] 18 | }, 19 | fuji: { 20 | url: `https://api.avax-test.network/ext/bc/C/rpc`, 21 | accounts: [`${PRIVATE_KEY}`] 22 | } 23 | } 24 | }; -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lock-project-advanced", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@nomiclabs/hardhat-ethers": "^2.0.6", 14 | "@nomiclabs/hardhat-waffle": "^2.0.3", 15 | "chai": "^4.3.6", 16 | "ethereum-waffle": "^3.4.4", 17 | "ethers": "^5.6.8", 18 | "hardhat": "^2.9.6" 19 | }, 20 | "dependencies": { 21 | "@openzeppelin/contracts": "^4.6.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/lock-project-advanced/scripts/deploy.js: -------------------------------------------------------------------------------- 1 | const { ethers } = require("hardhat"); 2 | 3 | async function main() { 4 | const [deployer] = await ethers.getSigners(); 5 | 6 | const Lock = await ethers.getContractFactory("Lock"); 7 | const lock = await Lock.deploy("0xa9d19d5e8712C1899C4344059FD2D873a3e2697E"); 8 | 9 | console.log("Contract address:", lock.address); 10 | } 11 | 12 | main() 13 | .then(() => process.exit(0)) 14 | .catch((error) => { 15 | console.error(error); 16 | process.exit(1); 17 | }); 18 | -------------------------------------------------------------------------------- /2x1_HardhatAdvanced/mainnet forking example.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/2x1_HardhatAdvanced/mainnet forking example.jpeg -------------------------------------------------------------------------------- /2x2_HardhatVsFoundry/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde [Hardhat](https://hardhat.org) ve [Foundry](https://book.getfoundry.sh/) frameworkleri arasındaki temel farklara değindik. 4 | 5 | [Video İçeriği](https://youtu.be/1h43HzpzEvo) 6 | 7 | [Hardhat Dizini](./hardhat) 8 | 9 | [Foundry Dizini](./foundry) -------------------------------------------------------------------------------- /2x2_HardhatVsFoundry/foundry/foundry.toml: -------------------------------------------------------------------------------- 1 | [default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config -------------------------------------------------------------------------------- /2x2_HardhatVsFoundry/foundry/remappings.txt: -------------------------------------------------------------------------------- 1 | forge-std=lib/forge-std/src -------------------------------------------------------------------------------- /2x2_HardhatVsFoundry/foundry/script/Deploy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSE 2 | pragma solidity ^0.8.13; 3 | 4 | import "../src/Purchase.sol"; 5 | import "forge-std/Script.sol"; 6 | 7 | contract Deploy is Script { 8 | uint256 constant START_AMOUNT = 0.2 ether; 9 | 10 | function run() public { 11 | vm.startBroadcast(0x66c30924155b1deE8a9829C0b0886D93bE44e168); 12 | new Purchase{ value: START_AMOUNT }(); 13 | } 14 | } -------------------------------------------------------------------------------- /2x2_HardhatVsFoundry/hardhat/hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from "dotenv"; 2 | 3 | import { HardhatUserConfig, task } from "hardhat/config"; 4 | import "@nomiclabs/hardhat-etherscan"; 5 | import "@nomiclabs/hardhat-waffle"; 6 | import "@typechain/hardhat"; 7 | import "hardhat-gas-reporter"; 8 | import "solidity-coverage"; 9 | 10 | dotenv.config(); 11 | 12 | // This is a sample Hardhat task. To learn how to create your own go to 13 | // https://hardhat.org/guides/create-task.html 14 | task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { 15 | const accounts = await hre.ethers.getSigners(); 16 | 17 | for (const account of accounts) { 18 | console.log(account.address); 19 | } 20 | }); 21 | 22 | task("hello-world", "Says hello world", async () => { 23 | console.log("hello wolrd"); 24 | }); 25 | 26 | // You need to export an object to set up your config 27 | // Go to https://hardhat.org/config/ to learn more 28 | 29 | const config: HardhatUserConfig = { 30 | solidity: "0.8.4", 31 | networks: { 32 | ropsten: { 33 | url: process.env.ROPSTEN_URL || "", 34 | accounts: 35 | process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], 36 | }, 37 | }, 38 | gasReporter: { 39 | enabled: process.env.REPORT_GAS !== undefined, 40 | currency: "USD", 41 | }, 42 | etherscan: { 43 | apiKey: process.env.ETHERSCAN_API_KEY, 44 | }, 45 | }; 46 | 47 | export default config; 48 | -------------------------------------------------------------------------------- /2x2_HardhatVsFoundry/hardhat/scripts/deploy.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "hardhat"; 2 | 3 | async function main() { 4 | const [ signer ] = await ethers.getSigners(); 5 | const SafeRemotePurchase = await ethers.getContractFactory("Purchase"); 6 | const safePurchase = await SafeRemotePurchase.connect(signer).deploy({ 7 | value: ethers.utils.parseEther('0.2') 8 | }); 9 | 10 | await safePurchase.deployed(); 11 | 12 | console.log("Safe Purchase deployed to:", safePurchase.address); 13 | } 14 | 15 | main().catch((error) => { 16 | console.error(error); 17 | process.exitCode = 1; 18 | }); 19 | -------------------------------------------------------------------------------- /2x4_FoundryTests/.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | .DS_Store -------------------------------------------------------------------------------- /2x4_FoundryTests/foundry.toml: -------------------------------------------------------------------------------- 1 | [default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config -------------------------------------------------------------------------------- /2x4_FoundryTests/remappings.txt: -------------------------------------------------------------------------------- 1 | ds-test/=lib/forge-std/lib/ds-test/src/ 2 | forge-std/=lib/forge-std/src/ 3 | -------------------------------------------------------------------------------- /2x4_FoundryTests/script/Contract.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "forge-std/Script.sol"; 5 | 6 | contract ContractScript is Script { 7 | function setUp() public {} 8 | 9 | function run() public { 10 | vm.broadcast(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /2x4_FoundryTests/test/Owner.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "forge-std/Test.sol"; 5 | import "../src/Owner.sol"; 6 | 7 | contract ContractTest is Test { 8 | Owner ownerContract; 9 | address newOwner = address(0xBEEF); 10 | address firstOwner = 0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84; 11 | 12 | function setUp() public { 13 | ownerContract = new Owner(); 14 | } 15 | 16 | function testFirstOwner() public { 17 | assertEq(ownerContract.getOwner(), firstOwner); 18 | } 19 | 20 | function testChangeOwner() public { 21 | ownerContract.changeOwner(newOwner); 22 | assertEq(ownerContract.getOwner(), newOwner); 23 | } 24 | 25 | function testChangeOwnerUnauthorized() public { 26 | vm.prank(newOwner); 27 | vm.expectRevert("Caller is not owner"); 28 | ownerContract.changeOwner(newOwner); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /2x5_FoundryCheatcodes/.gitignore: -------------------------------------------------------------------------------- 1 | /out 2 | /cache -------------------------------------------------------------------------------- /2x5_FoundryCheatcodes/foundry.toml: -------------------------------------------------------------------------------- 1 | [default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | 6 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config -------------------------------------------------------------------------------- /2x5_FoundryCheatcodes/remappings.txt: -------------------------------------------------------------------------------- 1 | ds-test/=lib/forge-std/lib/ds-test/src/ 2 | forge-std/=lib/forge-std/src/ 3 | -------------------------------------------------------------------------------- /2x5_FoundryCheatcodes/script/Contract.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "forge-std/Script.sol"; 5 | 6 | contract ContractScript is Script { 7 | function setUp() public {} 8 | 9 | function run() public { 10 | vm.broadcast(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /2x5_FoundryCheatcodes/src/Cheatcodes.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | contract Cheatcodes { 5 | address alice = address(0xBEEF); 6 | 7 | function fPrank() public view returns (bool) { 8 | require(msg.sender == alice); 9 | return true; 10 | } 11 | 12 | function fPrankTxOrigin() public view returns (bool) { 13 | require(tx.origin == alice); 14 | return true; 15 | } 16 | 17 | function fDeal() public view returns (bool) { 18 | require(msg.sender.balance == 5 ether); 19 | return true; 20 | } 21 | 22 | function fWarp() public view returns (bool) { 23 | require(block.timestamp > 50000000); 24 | return true; 25 | } 26 | 27 | function fRoll() public view returns (bool) { 28 | require(block.number > 50000000); 29 | return true; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /2x5_FoundryCheatcodes/test/Cheatcodes.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity ^0.8.13; 3 | 4 | import "forge-std/Test.sol"; 5 | import "../src/Cheatcodes.sol"; 6 | 7 | contract ContractTest is Test { 8 | address alice = address(0xBEEF); 9 | 10 | Cheatcodes CC; 11 | 12 | bytes32 randomPK = 0xf4390b831e81c148424b08398cdd250155923787d8a625747e10c823e6ed4100; 13 | bytes32 data = 0x0000000000000000000000000000000000000000000000000000000000000025; 14 | address randomAddress = vm.addr(uint256(randomPK)); 15 | 16 | function setUp() public { 17 | CC = new Cheatcodes(); 18 | } 19 | 20 | function testRecover() public { 21 | (uint8 v, bytes32 r, bytes32 s) = vm.sign(uint256(randomPK), data); 22 | address recoveredAddress = ecrecover(data, v, r, s); 23 | assertEq(recoveredAddress, randomAddress); 24 | } 25 | 26 | function testPrank() public { 27 | vm.prank(alice); 28 | CC.fPrank(); 29 | } 30 | 31 | function testPrankTxOrigin() public { 32 | vm.prank(address(0), alice); 33 | CC.fPrankTxOrigin(); 34 | } 35 | 36 | function testDeal() public { 37 | vm.prank(alice); 38 | vm.deal(alice, 5 ether); 39 | CC.fDeal(); 40 | } 41 | 42 | function testWarp() public { 43 | vm.warp(500000000000); 44 | CC.fWarp(); 45 | } 46 | 47 | function testRoll() public { 48 | vm.roll(5000000000000); 49 | CC.fRoll(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde, Ethereum'un resmi GoLang implementasyonu olan "Go Ethereum"u kullanarak uygulamalarımıza Ethereum entegrasyonlarımızı nasıl Go kullanarak yapabileceğimizi inceledik. 4 | 5 | [Go Ethereum](https://geth.ethereum.org/) 6 | 7 | [Go Ethereum Book](https://goethereumbook.org/en/) 8 | 9 | [Go pkgs](https://pkg.go.dev/github.com/ethereum/go-ethereum) 10 | 11 | [Go pkg 'ethclient' - RPC API](https://pkg.go.dev/github.com/ethereum/go-ethereum/ethclient) 12 | 13 | [Go pkg 'common'- Helper fns](https://pkg.go.dev/github.com/ethereum/go-ethereum/common) 14 | 15 | [Go pkg 'bind' - Contract bindings](https://pkg.go.dev/github.com/ethereum/go-ethereum/accounts/abi/bind) 16 | 17 | [Go pkg 'types' - Ethereum data types](https://pkg.go.dev/github.com/ethereum/go-ethereum/core/types) 18 | 19 | [Akıllı kontratlar için gerekli programları yüklemek için](https://goethereumbook.org/en/smart-contract-compile/) 20 | 21 |
22 | 23 | ```bash 24 | // Generating the abi of the contract 25 | solc --abi ethereum/contracts/NumStore.sol -o build 26 | 27 | // Converting abi to GO file 28 | abigen --abi=./build/NumStore.abi --pkg=numstore --out=ethereum/contracts/NumStore.go 29 | 30 | // Generates EVM bytecodes of the contract 31 | solc --bin ethereum/contracts/NumStore.sol -o build 32 | 33 | // Implements deploy params to GO file 34 | abigen --bin=./build/NumStore.bin --abi=./build/NumStore.abi --pkg=numstore --out=./ethereum/contracts/NumStore.go 35 | ``` -------------------------------------------------------------------------------- /2x7_Go-Ethereum/app/app.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "go-ethereum-tutorial/controllers/club" 5 | "go-ethereum-tutorial/controllers/chain" 6 | "go-ethereum-tutorial/controllers/contracts" 7 | ) 8 | 9 | func mapUrls() { 10 | router.GET("/", club.Name) 11 | 12 | router.GET("/chain/balance/:address", chain.Balance); 13 | router.POST("/chain/faucet", chain.Faucet); 14 | 15 | router.GET("/contracts/number", contracts.Number); 16 | router.POST("/contracts/add", contracts.Add); 17 | } -------------------------------------------------------------------------------- /2x7_Go-Ethereum/app/url_mappings.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import "github.com/gin-gonic/gin" 4 | 5 | var router *gin.Engine 6 | 7 | func init() { 8 | router = gin.Default() 9 | } 10 | 11 | func Start() { 12 | mapUrls() 13 | 14 | if err := router.Run(":8080"); err != nil { 15 | panic(err) 16 | } 17 | } -------------------------------------------------------------------------------- /2x7_Go-Ethereum/build/NumStore.abi: -------------------------------------------------------------------------------- 1 | [{"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"addNumber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}] -------------------------------------------------------------------------------- /2x7_Go-Ethereum/build/NumStore.bin: -------------------------------------------------------------------------------- 1 | 608060405234801561001057600080fd5b506101c4806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063775a25e31461003b578063fce6802314610059575b600080fd5b610043610075565b60405161005091906100b2565b60405180910390f35b610073600480360381019061006e91906100fe565b61007e565b005b60008054905090565b8060008082825461008f919061015a565b9250508190555050565b6000819050919050565b6100ac81610099565b82525050565b60006020820190506100c760008301846100a3565b92915050565b600080fd5b6100db81610099565b81146100e657600080fd5b50565b6000813590506100f8816100d2565b92915050565b600060208284031215610114576101136100cd565b5b6000610122848285016100e9565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061016582610099565b915061017083610099565b92508282019050808211156101885761018761012b565b5b9291505056fea2646970667358221220be213790526a01ddb9037252c9b1a96846dbcac151398d2d7040687606d8490064736f6c63430008110033 -------------------------------------------------------------------------------- /2x7_Go-Ethereum/controllers/chain/chain_controller.go: -------------------------------------------------------------------------------- 1 | package chain 2 | 3 | import ( 4 | "go-ethereum-tutorial/domain" 5 | "go-ethereum-tutorial/services" 6 | errutils "go-ethereum-tutorial/utils/error_utils" 7 | 8 | "github.com/ethereum/go-ethereum/common" 9 | "github.com/gin-gonic/gin" 10 | "net/http" 11 | ) 12 | 13 | func Balance(c *gin.Context) { 14 | accAddress := common.HexToAddress(c.Param("address")) 15 | check := domain.AddressQuery{Address: accAddress} 16 | 17 | response, err := services.ChainService.GetBalance(check) 18 | if err != nil { 19 | c.JSON(err.Status(), err) 20 | return 21 | } 22 | 23 | c.JSON(http.StatusCreated, response) 24 | } 25 | 26 | func Faucet(c *gin.Context) { 27 | var request domain.FaucetRequest 28 | if err := c.ShouldBindJSON(&request); err != nil { 29 | apiErr := errutils.NewBadRequestError("Invalid json body") 30 | c.JSON(apiErr.Status(), apiErr) 31 | return 32 | } 33 | 34 | response, apiErr := services.ChainService.Faucet(request) 35 | if apiErr != nil { 36 | c.JSON(apiErr.Status(), apiErr) 37 | return 38 | } 39 | 40 | c.JSON(http.StatusCreated, response) 41 | } 42 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/controllers/club/club_controller.go: -------------------------------------------------------------------------------- 1 | package club 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | "net/http" 6 | ) 7 | 8 | func Name(c *gin.Context) { 9 | c.String(http.StatusOK, "ITU Blockchain\n") 10 | } 11 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/controllers/contracts/contracts_controller.go: -------------------------------------------------------------------------------- 1 | package contracts 2 | 3 | import ( 4 | "go-ethereum-tutorial/domain" 5 | "go-ethereum-tutorial/services" 6 | errutils "go-ethereum-tutorial/utils/error_utils" 7 | 8 | "github.com/gin-gonic/gin" 9 | "net/http" 10 | ) 11 | 12 | func Number(c *gin.Context) { 13 | response, err := services.ContractService.GetNumber() 14 | if err != nil { 15 | c.JSON(err.Status(), err) 16 | return 17 | } 18 | 19 | c.JSON(http.StatusCreated, response) 20 | 21 | } 22 | 23 | func Add(c *gin.Context) { 24 | var request domain.AddRequest 25 | if err := c.ShouldBindJSON(&request); err != nil { 26 | apiErr := errutils.NewBadRequestError("Invalid json body") 27 | c.JSON(apiErr.Status(), apiErr) 28 | return 29 | } 30 | 31 | response, apiErr := services.ContractService.AddNumber(request) 32 | if apiErr != nil { 33 | c.JSON(apiErr.Status(), apiErr) 34 | return 35 | } 36 | 37 | c.JSON(http.StatusCreated, response) 38 | } 39 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/domain/account.go: -------------------------------------------------------------------------------- 1 | package domain 2 | 3 | import ( 4 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 5 | "github.com/ethereum/go-ethereum/common" 6 | ) 7 | 8 | type Account struct { 9 | FromAddress common.Address 10 | Auth *bind.TransactOpts 11 | } -------------------------------------------------------------------------------- /2x7_Go-Ethereum/domain/chain.go: -------------------------------------------------------------------------------- 1 | package domain 2 | 3 | import ( 4 | errutils "go-ethereum-tutorial/utils/error_utils" 5 | ethutils "go-ethereum-tutorial/utils/ethereum_utils" 6 | 7 | "github.com/ethereum/go-ethereum/common" 8 | "github.com/shopspring/decimal" 9 | ) 10 | 11 | type AddressQuery struct { 12 | Address common.Address `json:"user_addr"` 13 | } 14 | 15 | func (q *AddressQuery) Validate() errutils.ApiError { 16 | if !ethutils.IsValidAddress(q.Address) || ethutils.IsZeroAddress(q.Address) { 17 | err := errutils.NewBadRequestError("Invalid address") 18 | return err 19 | } 20 | return nil 21 | } 22 | 23 | type AddressResponse struct { 24 | Address common.Address `json:"user_addr"` 25 | Balance decimal.Decimal `json:"balance"` 26 | } 27 | 28 | type FaucetRequest struct { 29 | Address common.Address `json:"user_addr"` 30 | Amount uint `json:"amount"` 31 | } 32 | 33 | func (r *FaucetRequest) Validate() errutils.ApiError { 34 | if !ethutils.IsValidAddress(r.Address) || ethutils.IsZeroAddress(r.Address) { 35 | apiErr := errutils.NewBadRequestError("Invalid address") 36 | return apiErr 37 | } 38 | if !(r.Amount > 0 && r.Amount <= 2) { 39 | apiErr := errutils.NewBadRequestError("Invalid amount") 40 | return apiErr 41 | } 42 | return nil 43 | } 44 | 45 | type FaucetResponse struct { 46 | Address common.Address `json:"user_addr"` 47 | Amount decimal.Decimal `json:"amount"` 48 | } 49 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/domain/contracts.go: -------------------------------------------------------------------------------- 1 | package domain 2 | 3 | import ( 4 | errutils "go-ethereum-tutorial/utils/error_utils" 5 | "strconv" 6 | ) 7 | 8 | type NumberResponse struct { 9 | Number string `json:"number"` 10 | } 11 | 12 | type AddRequest struct { 13 | Number string `json:"number"` 14 | } 15 | 16 | func (r *AddRequest) Validate() errutils.ApiError { 17 | if _, err := strconv.Atoi(r.Number); err != nil { 18 | return errutils.NewBadRequestError("Number is not valid.") 19 | } 20 | return nil 21 | } 22 | 23 | type AddResponse struct { 24 | Number string `json:"number"` 25 | Result string `json:"result"` 26 | } 27 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/ethereum/client.go: -------------------------------------------------------------------------------- 1 | package ethereum 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | "github.com/ethereum/go-ethereum/ethclient" 7 | ) 8 | 9 | var Client *ethclient.Client 10 | var CHAIN_ID *big.Int 11 | 12 | func init() { 13 | var err error 14 | Client, err = ethclient.Dial("https://api.avax-test.network/ext/bc/C/rpc") 15 | if err != nil { 16 | panic(err) 17 | } 18 | 19 | chainID, err := Client.NetworkID(context.Background()) 20 | if err != nil { 21 | panic(err) 22 | } 23 | CHAIN_ID = chainID 24 | } 25 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/ethereum/contracts/NumStore.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | // 0x5fdE8808a25ea3c4DE959081b225661363b2B11a - fuji 3 | pragma solidity ^0.8.0; 4 | 5 | contract NumStore { 6 | // Total number added to the contract 7 | uint256 private total; 8 | 9 | // Get the total number 10 | function getTotal() external view returns (uint256) { 11 | return total; 12 | } 13 | 14 | // Add number to the contract 15 | function addNumber(uint256 number) external { 16 | total += number; 17 | } 18 | } -------------------------------------------------------------------------------- /2x7_Go-Ethereum/ethereum/private.go: -------------------------------------------------------------------------------- 1 | package ethereum 2 | 3 | import ( 4 | "fmt" 5 | "crypto/ecdsa" 6 | "go-ethereum-tutorial/domain" 7 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 8 | "github.com/ethereum/go-ethereum/crypto" 9 | "github.com/ethereum/go-ethereum/common" 10 | ) 11 | 12 | var Account domain.Account 13 | 14 | const private_key string = "PRIVATE_KEY" 15 | 16 | var PrivateECDSA *ecdsa.PrivateKey 17 | 18 | func init() { 19 | PrivateECDSA = crypto.ToECDSAUnsafe(common.FromHex(private_key)) 20 | 21 | publicKey := PrivateECDSA.Public() 22 | 23 | publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) 24 | if !ok { 25 | fmt.Println("cannot assert type") 26 | } 27 | 28 | fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) 29 | 30 | auth, err := bind.NewKeyedTransactorWithChainID(PrivateECDSA, CHAIN_ID) 31 | if err != nil { 32 | fmt.Println(err) 33 | } 34 | 35 | Account = domain.Account{ 36 | FromAddress: fromAddress, 37 | Auth: auth, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "go-ethereum-tutorial/app" 5 | ) 6 | 7 | func main() { 8 | app.Start() 9 | } -------------------------------------------------------------------------------- /2x7_Go-Ethereum/services/chain_services.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "go-ethereum-tutorial/domain" 5 | "go-ethereum-tutorial/ethereum" 6 | errutils "go-ethereum-tutorial/utils/error_utils" 7 | ) 8 | 9 | type chainService struct{} 10 | 11 | type chainServiceInterface interface { 12 | GetBalance(Q domain.AddressQuery) (*domain.AddressResponse, errutils.ApiError) 13 | Faucet(r domain.FaucetRequest) (*domain.FaucetResponse, errutils.ApiError) 14 | } 15 | 16 | var ChainService chainServiceInterface 17 | 18 | func init() { 19 | ChainService = &chainService{} 20 | } 21 | 22 | func (ns *chainService) GetBalance(Q domain.AddressQuery) (*domain.AddressResponse, errutils.ApiError) { 23 | err := Q.Validate() 24 | if err != nil { 25 | return nil, errutils.NewBadRequestError("False input format.") 26 | } 27 | 28 | request, err := ethereum.ChainInteraction.GetBalance(Q) 29 | if err != nil { 30 | return nil, errutils.NewInternalServerError("Balance querying error.") 31 | } 32 | return request, nil 33 | } 34 | 35 | func (ns *chainService) Faucet(R domain.FaucetRequest) (*domain.FaucetResponse, errutils.ApiError) { 36 | err := R.Validate() 37 | if err != nil { 38 | return nil, errutils.NewBadRequestError("False input format.") 39 | } 40 | 41 | response, err := ethereum.ChainInteraction.Faucet(R) 42 | if err != nil { 43 | return nil, errutils.NewApiError(err.Status(), "ETHs couldn't send.") 44 | } 45 | return response, nil 46 | } 47 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/services/contract_services.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "go-ethereum-tutorial/domain" 5 | "go-ethereum-tutorial/ethereum" 6 | errutils "go-ethereum-tutorial/utils/error_utils" 7 | ) 8 | 9 | type contractService struct{} 10 | 11 | type contractServiceInterface interface { 12 | GetNumber() (*domain.NumberResponse, errutils.ApiError) 13 | AddNumber(R domain.AddRequest) (*domain.AddResponse, errutils.ApiError) 14 | } 15 | 16 | var ContractService contractServiceInterface 17 | 18 | func init() { 19 | ContractService = &contractService{} 20 | } 21 | 22 | func (cs *contractService) GetNumber() (*domain.NumberResponse, errutils.ApiError) { 23 | request, err := ethereum.ContractInteraction.GetNumber() 24 | if err != nil { 25 | return nil, errutils.NewInternalServerError("Number querying error.") 26 | } 27 | return request, nil 28 | } 29 | 30 | func (cs *contractService) AddNumber(R domain.AddRequest) (*domain.AddResponse, errutils.ApiError) { 31 | R.Validate() 32 | 33 | response, err := ethereum.ContractInteraction.AddNumber(R) 34 | if err != nil { 35 | return nil, errutils.NewApiError(err.Status(), "Number couldn't add.") 36 | } 37 | return response, nil 38 | } 39 | -------------------------------------------------------------------------------- /2x7_Go-Ethereum/utils/error_utils/errors.go: -------------------------------------------------------------------------------- 1 | package rest_errors 2 | 3 | type ApiError interface { 4 | Status() int 5 | Message() string 6 | Error() string 7 | } 8 | 9 | type apiError struct { 10 | AStatus int `json:"status"` 11 | AMessage string `json:"message"` 12 | AnError string `json:"error,omitempty"` 13 | } -------------------------------------------------------------------------------- /2x7_Go-Ethereum/utils/error_utils/rest_errors.go: -------------------------------------------------------------------------------- 1 | package rest_errors 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | 8 | func (e *apiError) Status() int { 9 | return e.AStatus 10 | } 11 | 12 | func (e *apiError) Message() string { 13 | return e.AMessage 14 | } 15 | 16 | func (e *apiError) Error() string { 17 | return e.AnError 18 | } 19 | 20 | func NewApiError(statusCode int, message string) ApiError { 21 | return &apiError{AStatus: statusCode, AMessage: message} 22 | } 23 | 24 | func NewBadRequestError(message string) ApiError { 25 | return &apiError{ 26 | AStatus: http.StatusBadRequest, 27 | AMessage: message, 28 | } 29 | } 30 | 31 | func NewInternalServerError(message string) ApiError { 32 | return &apiError{ 33 | AStatus: http.StatusInternalServerError, 34 | AMessage: message, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "week1", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.3.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "react": "^18.1.0", 10 | "react-dom": "^18.1.0", 11 | "react-scripts": "5.0.1", 12 | "web-vitals": "^2.1.4" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x0_CustomAndBuiltInHooks/public/favicon.ico -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x0_CustomAndBuiltInHooks/public/logo192.png -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x0_CustomAndBuiltInHooks/public/logo512.png -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/src/App.js: -------------------------------------------------------------------------------- 1 | import { useCallback, useEffect, useMemo, useRef, useState } from "react"; 2 | import "./App.css"; 3 | import { useRandomUser } from "./hooks/useRandomUser"; 4 | 5 | function App() { 6 | const [value, setValue] = useState(1); 7 | const ref = useRef(false); 8 | 9 | const { state } = useRandomUser(); 10 | 11 | const renderEmail = () => { 12 | if (!state) return null; 13 | return state.email; 14 | }; 15 | 16 | return ( 17 |
18 |

Week {value} - Introduction to custom hooks

19 | 30 |

{renderEmail()}

31 |
32 | ); 33 | } 34 | 35 | export default App; 36 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/src/hooks/useRandomUser.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useRandomUser = () => { 4 | const [state, setState] = useState(null); 5 | 6 | useEffect(() => { 7 | const fn = async () => { 8 | const result = await fetch("https://randomuser.me/api/"); 9 | const json = await result.json(); 10 | setState(json.results[0]); 11 | }; 12 | console.log("hjere"); 13 | fn(); 14 | }, []); 15 | 16 | return { state }; 17 | }; 18 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /3x0_CustomAndBuiltInHooks/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /3x1_WalletConnection/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "week2", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.3.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "ethers": "^5.6.8", 10 | "react": "^18.2.0", 11 | "react-dom": "^18.2.0", 12 | "react-scripts": "5.0.1", 13 | "web-vitals": "^2.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /3x1_WalletConnection/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x1_WalletConnection/public/favicon.ico -------------------------------------------------------------------------------- /3x1_WalletConnection/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x1_WalletConnection/public/logo192.png -------------------------------------------------------------------------------- /3x1_WalletConnection/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x1_WalletConnection/public/logo512.png -------------------------------------------------------------------------------- /3x1_WalletConnection/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /3x1_WalletConnection/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /3x1_WalletConnection/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x1_WalletConnection/src/App.js: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import { useState } from "react"; 3 | import { ethers } from "ethers"; 4 | 5 | function App() { 6 | const [account, setAccount] = useState(""); 7 | const [provider, setProvider] = useState(null); 8 | 9 | function connect() { 10 | if (!window.ethereum) { 11 | alert("Metamask is not installed"); 12 | return; 13 | } 14 | const provider = new ethers.providers.Web3Provider(window.ethereum); 15 | setProvider(provider); 16 | provider 17 | .send("eth_requestAccounts", []) 18 | .then((accounts) => setAccount(accounts[0])) 19 | .catch((err) => console.log(err)); 20 | const signer = provider.getSigner(); 21 | signer.getAddress().then((address) => console.log(address)); 22 | console.log(signer); 23 | } 24 | 25 | return ( 26 |
27 | 35 |
36 | ); 37 | } 38 | 39 | export default App; 40 | -------------------------------------------------------------------------------- /3x1_WalletConnection/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /3x1_WalletConnection/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /3x1_WalletConnection/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /3x1_WalletConnection/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /3x1_WalletConnection/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "week3", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.3.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "ethers": "^5.6.8", 10 | "react": "^18.2.0", 11 | "react-dom": "^18.2.0", 12 | "react-scripts": "5.0.1", 13 | "web-vitals": "^2.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x2_ContractInteraction/public/favicon.ico -------------------------------------------------------------------------------- /3x2_ContractInteraction/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x2_ContractInteraction/public/logo192.png -------------------------------------------------------------------------------- /3x2_ContractInteraction/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x2_ContractInteraction/public/logo512.png -------------------------------------------------------------------------------- /3x2_ContractInteraction/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/App.js: -------------------------------------------------------------------------------- 1 | import { BigNumber, ethers } from "ethers"; 2 | import { useState } from "react"; 3 | import "./App.css"; 4 | import { useLockContract } from "./hooks/useLockContract"; 5 | 6 | function App() { 7 | const lockContract = useLockContract(); 8 | const [totalLockedAmount, setTotalLockedAmount] = useState(BigNumber.from(0)); 9 | 10 | const getTotalLocked = async () => { 11 | if (!lockContract) return; 12 | const result = await lockContract.totalLocked(); 13 | setTotalLockedAmount(result); 14 | }; 15 | 16 | return ( 17 |
18 | 19 |

20 | Total locked amount is:{" "} 21 | {ethers.utils.formatUnits(totalLockedAmount, 18)} 22 |

23 |
24 | ); 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/constants/addresses.js: -------------------------------------------------------------------------------- 1 | export const LOCK_ADDRESS = "0x66c23EE8bFbf2B158A84e82A642253fd95d00807"; 2 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/hooks/useLockContract.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | import { ethers } from "ethers"; 3 | import { LOCK_ADDRESS } from "../constants/addresses"; 4 | import { LOCK_ABI } from "../constants/abi"; 5 | 6 | export const useLockContract = () => { 7 | const [contract, setContract] = useState(null); 8 | 9 | useEffect(() => { 10 | const provider = new ethers.providers.Web3Provider(window.ethereum); 11 | const _contract = new ethers.Contract(LOCK_ADDRESS, LOCK_ABI, provider); 12 | setContract(_contract); 13 | }, []); 14 | 15 | return contract; 16 | }; 17 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /3x2_ContractInteraction/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "week4", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.16.4", 7 | "@testing-library/react": "^13.3.0", 8 | "@testing-library/user-event": "^13.5.0", 9 | "ethers": "^5.6.9", 10 | "react": "^18.2.0", 11 | "react-dom": "^18.2.0", 12 | "react-scripts": "5.0.1", 13 | "web-vitals": "^2.1.4" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": [ 23 | "react-app", 24 | "react-app/jest" 25 | ] 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x3_SendingTransactions/public/favicon.ico -------------------------------------------------------------------------------- /3x3_SendingTransactions/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x3_SendingTransactions/public/logo192.png -------------------------------------------------------------------------------- /3x3_SendingTransactions/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x3_SendingTransactions/public/logo512.png -------------------------------------------------------------------------------- /3x3_SendingTransactions/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/constants/addresses.js: -------------------------------------------------------------------------------- 1 | export const LOCK_ADDRESS = "0x2c9156378B39D8908835818748d31c1B03f8664b"; 2 | export const BEETOKEN_ADDRESS = "0x93ACaF84bB1A78216255Da952525F1EA7A197065"; 3 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/hooks/useAllowance.js: -------------------------------------------------------------------------------- 1 | import { BigNumber, ethers } from "ethers"; 2 | import { useEffect, useState } from "react"; 3 | import { ERC20 } from "../constants/abi"; 4 | import { BEETOKEN_ADDRESS, LOCK_ADDRESS } from "../constants/addresses"; 5 | 6 | export const useAllowance = () => { 7 | const [allowance, setAllowance] = useState(BigNumber.from(0)); 8 | const [isAppoving, setIsApproving] = useState(false); 9 | 10 | const getAllowance = async () => { 11 | const provider = new ethers.providers.Web3Provider(window.ethereum); 12 | const signer = provider.getSigner(); 13 | const _contract = new ethers.Contract(BEETOKEN_ADDRESS, ERC20, provider); 14 | const result = await _contract.allowance(signer.getAddress(), LOCK_ADDRESS); 15 | setAllowance(result); 16 | }; 17 | 18 | useEffect(() => { 19 | getAllowance(); 20 | }, []); 21 | 22 | const approve = async () => { 23 | const provider = new ethers.providers.Web3Provider(window.ethereum); 24 | const signer = provider.getSigner(); 25 | const _contract = new ethers.Contract(BEETOKEN_ADDRESS, ERC20, signer); 26 | setIsApproving(true); 27 | try { 28 | const txn = await _contract.approve( 29 | LOCK_ADDRESS, 30 | ethers.constants.MaxUint256 31 | ); 32 | await txn.wait(); 33 | setIsApproving(false); 34 | getAllowance(); 35 | } catch { 36 | setIsApproving(false); 37 | } 38 | }; 39 | 40 | return { isAppoving, allowance, approve }; 41 | }; 42 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/hooks/useLockContract.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | import { ethers } from "ethers"; 3 | import { LOCK_ADDRESS } from "../constants/addresses"; 4 | import { LOCK_ABI } from "../constants/abi"; 5 | 6 | export const useLockContract = () => { 7 | const [contract, setContract] = useState(null); 8 | 9 | useEffect(() => { 10 | const provider = new ethers.providers.Web3Provider(window.ethereum); 11 | const signer = provider.getSigner(); 12 | const _contract = new ethers.Contract(LOCK_ADDRESS, LOCK_ABI, signer); 13 | setContract(_contract); 14 | }, []); 15 | 16 | return contract; 17 | }; 18 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /3x3_SendingTransactions/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /3x4_ReduxToolkit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@reduxjs/toolkit": "^1.8.2", 7 | "@testing-library/jest-dom": "^5.16.4", 8 | "@testing-library/react": "^13.3.0", 9 | "@testing-library/user-event": "^13.5.0", 10 | "ethers": "^5.6.9", 11 | "react": "^18.2.0", 12 | "react-dom": "^18.2.0", 13 | "react-redux": "^8.0.2", 14 | "react-scripts": "5.0.1", 15 | "redux": "^4.2.0", 16 | "web-vitals": "^2.1.4" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject" 23 | }, 24 | "eslintConfig": { 25 | "extends": [ 26 | "react-app", 27 | "react-app/jest" 28 | ] 29 | }, 30 | "browserslist": { 31 | "production": [ 32 | ">0.2%", 33 | "not dead", 34 | "not op_mini all" 35 | ], 36 | "development": [ 37 | "last 1 chrome version", 38 | "last 1 firefox version", 39 | "last 1 safari version" 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x4_ReduxToolkit/public/favicon.ico -------------------------------------------------------------------------------- /3x4_ReduxToolkit/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x4_ReduxToolkit/public/logo192.png -------------------------------------------------------------------------------- /3x4_ReduxToolkit/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x4_ReduxToolkit/public/logo512.png -------------------------------------------------------------------------------- /3x4_ReduxToolkit/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/constants/addresses.js: -------------------------------------------------------------------------------- 1 | export const LOCK_ADDRESS = "0x69c19B2D026260da7A0D413f83B6b7dEeCa7bc18"; 2 | export const BEETOKEN_ADDRESS = "0x739A14Bc2A9678e2c639ED97C91C48250d360FB2"; 3 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/hooks/useAddress.js: -------------------------------------------------------------------------------- 1 | export const useAddress = () => { 2 | const address = useSelector((state) => state.data.address); 3 | return address; 4 | }; 5 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/hooks/useProvider.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | 3 | export const useProvider = () => { 4 | const provider = useSelector((state) => state.data.provider); 5 | return provider; 6 | }; 7 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/hooks/useSigner.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | 3 | export const useSigner = () => { 4 | const signer = useSelector((state) => state.data.signer); 5 | return signer; 6 | }; 7 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import reportWebVitals from "./reportWebVitals"; 6 | import { store } from "./store"; 7 | import { Provider } from "react-redux"; 8 | 9 | const root = ReactDOM.createRoot(document.getElementById("root")); 10 | root.render( 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/store/index.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit"; 2 | import dataSlice from "./slicers/data"; 3 | import contractsSlice from "./slicers/contracts"; 4 | 5 | export const store = configureStore({ 6 | reducer: { 7 | data: dataSlice, 8 | contracts: contractsSlice, 9 | }, 10 | middleware: (getDefaultMiddleware) => { 11 | return getDefaultMiddleware({ 12 | serializableCheck: false, 13 | }); 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/store/slicers/contracts.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | lock: null, 5 | beeToken: null, 6 | }; 7 | 8 | export const contractsSlice = createSlice({ 9 | name: "contracts", 10 | initialState, 11 | reducers: { 12 | setLockContract: (state, action) => { 13 | state.lock = action.payload; 14 | }, 15 | setBeeTokenContract: (state, action) => { 16 | state.beeToken = action.payload; 17 | }, 18 | }, 19 | }); 20 | 21 | // Action creators are generated for each case reducer function 22 | export const { setLockContract, setBeeTokenContract } = contractsSlice.actions; 23 | 24 | export default contractsSlice.reducer; 25 | -------------------------------------------------------------------------------- /3x4_ReduxToolkit/src/store/slicers/data.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | provider: null, 5 | signer: null, 6 | address: null, 7 | account: null, 8 | }; 9 | 10 | export const dataSlice = createSlice({ 11 | name: "data", 12 | initialState, 13 | reducers: { 14 | setProvider: (state, action) => { 15 | state.provider = action.payload; 16 | }, 17 | setSigner: (state, action) => { 18 | state.signer = action.payload; 19 | }, 20 | setAddress: (state, action) => { 21 | state.address = action.payload; 22 | }, 23 | setAccount: (state, action) => { 24 | state.account = action.payload; 25 | }, 26 | }, 27 | }); 28 | 29 | // Action creators are generated for each case reducer function 30 | export const { setProvider, setSigner, setAddress, setAccount } = 31 | dataSlice.actions; 32 | 33 | export default dataSlice.reducer; 34 | -------------------------------------------------------------------------------- /3x5_EventListening/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /3x5_EventListening/LockContract/Lock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "./Token.sol"; 5 | 6 | contract Lock { 7 | BEEToken Token; 8 | uint256 public lockerCount; 9 | uint256 public totalLocked; 10 | mapping(address => uint256) public lockers; 11 | 12 | event Locked( 13 | address indexed locker, 14 | uint256 amount 15 | ); 16 | 17 | constructor(address tokenAddress) { 18 | Token = BEEToken(tokenAddress); 19 | } 20 | 21 | function lockTokens(uint256 amount) external { 22 | require(amount > 0, "Token amount must be bigger than 0."); 23 | 24 | // require(Token.balanceOf(msg.sender) >= amount, "Insufficient balance."); 25 | // require(Token.allowance(msg.sender, address(this)) >= amount, "Insufficient allowance."); 26 | 27 | if(!(lockers[msg.sender] > 0)) lockerCount++; 28 | totalLocked += amount; 29 | lockers[msg.sender] += amount; 30 | 31 | bool ok = Token.transferFrom(msg.sender, address(this), amount); 32 | require(ok, "Transfer failed."); 33 | emit Locked(msg.sender, amount); 34 | } 35 | 36 | function withdrawTokens() external { 37 | require(lockers[msg.sender] > 0, "Not enough token."); 38 | uint256 amount = lockers[msg.sender]; 39 | delete(lockers[msg.sender]); 40 | totalLocked -= amount; 41 | lockerCount--; 42 | require(Token.transfer(msg.sender, amount), "Transfer failed."); 43 | } 44 | } -------------------------------------------------------------------------------- /3x5_EventListening/LockContract/Token.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract BEEToken is ERC20 { 7 | constructor() ERC20("BEE Token", "BEE") { 8 | _mint(msg.sender, 1773000 * 10**decimals()); 9 | } 10 | } -------------------------------------------------------------------------------- /3x5_EventListening/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@reduxjs/toolkit": "^1.8.2", 7 | "@testing-library/jest-dom": "^5.16.4", 8 | "@testing-library/react": "^13.3.0", 9 | "@testing-library/user-event": "^13.5.0", 10 | "ethers": "^5.6.9", 11 | "react": "^18.2.0", 12 | "react-dom": "^18.2.0", 13 | "react-redux": "^8.0.2", 14 | "react-scripts": "5.0.1", 15 | "redux": "^4.2.0", 16 | "web-vitals": "^2.1.4" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject" 23 | }, 24 | "eslintConfig": { 25 | "extends": [ 26 | "react-app", 27 | "react-app/jest" 28 | ] 29 | }, 30 | "browserslist": { 31 | "production": [ 32 | ">0.2%", 33 | "not dead", 34 | "not op_mini all" 35 | ], 36 | "development": [ 37 | "last 1 chrome version", 38 | "last 1 firefox version", 39 | "last 1 safari version" 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /3x5_EventListening/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x5_EventListening/public/favicon.ico -------------------------------------------------------------------------------- /3x5_EventListening/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x5_EventListening/public/logo192.png -------------------------------------------------------------------------------- /3x5_EventListening/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x5_EventListening/public/logo512.png -------------------------------------------------------------------------------- /3x5_EventListening/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /3x5_EventListening/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /3x5_EventListening/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x5_EventListening/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /3x5_EventListening/src/constants/addresses.js: -------------------------------------------------------------------------------- 1 | export const LOCK_ADDRESS = "0x69c19B2D026260da7A0D413f83B6b7dEeCa7bc18"; 2 | export const BEETOKEN_ADDRESS = "0x739A14Bc2A9678e2c639ED97C91C48250d360FB2"; 3 | -------------------------------------------------------------------------------- /3x5_EventListening/src/hooks/useAddress.js: -------------------------------------------------------------------------------- 1 | export const useAddress = () => { 2 | const address = useSelector((state) => state.data.address); 3 | return address; 4 | }; 5 | -------------------------------------------------------------------------------- /3x5_EventListening/src/hooks/useProvider.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | 3 | export const useProvider = () => { 4 | const provider = useSelector((state) => state.data.provider); 5 | return provider; 6 | }; 7 | -------------------------------------------------------------------------------- /3x5_EventListening/src/hooks/useSigner.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | 3 | export const useSigner = () => { 4 | const signer = useSelector((state) => state.data.signer); 5 | return signer; 6 | }; 7 | -------------------------------------------------------------------------------- /3x5_EventListening/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /3x5_EventListening/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import reportWebVitals from "./reportWebVitals"; 6 | import { store } from "./store"; 7 | import { Provider } from "react-redux"; 8 | 9 | const root = ReactDOM.createRoot(document.getElementById("root")); 10 | root.render( 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /3x5_EventListening/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /3x5_EventListening/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /3x5_EventListening/src/store/index.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit"; 2 | import dataSlice from "./slicers/data"; 3 | import contractsSlice from "./slicers/contracts"; 4 | 5 | export const store = configureStore({ 6 | reducer: { 7 | data: dataSlice, 8 | contracts: contractsSlice, 9 | }, 10 | middleware: (getDefaultMiddleware) => { 11 | return getDefaultMiddleware({ 12 | serializableCheck: false, 13 | }); 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /3x5_EventListening/src/store/slicers/contracts.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | lock: null, 5 | beeToken: null, 6 | }; 7 | 8 | export const contractsSlice = createSlice({ 9 | name: "contracts", 10 | initialState, 11 | reducers: { 12 | setLockContract: (state, action) => { 13 | state.lock = action.payload; 14 | }, 15 | setBeeTokenContract: (state, action) => { 16 | state.beeToken = action.payload; 17 | }, 18 | }, 19 | }); 20 | 21 | // Action creators are generated for each case reducer function 22 | export const { setLockContract, setBeeTokenContract } = contractsSlice.actions; 23 | 24 | export default contractsSlice.reducer; 25 | -------------------------------------------------------------------------------- /3x5_EventListening/src/store/slicers/data.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | provider: null, 5 | signer: null, 6 | address: null, 7 | account: null, 8 | }; 9 | 10 | export const dataSlice = createSlice({ 11 | name: "data", 12 | initialState, 13 | reducers: { 14 | setProvider: (state, action) => { 15 | state.provider = action.payload; 16 | }, 17 | setSigner: (state, action) => { 18 | state.signer = action.payload; 19 | }, 20 | setAddress: (state, action) => { 21 | state.address = action.payload; 22 | }, 23 | setAccount: (state, action) => { 24 | state.account = action.payload; 25 | }, 26 | }, 27 | }); 28 | 29 | // Action creators are generated for each case reducer function 30 | export const { setProvider, setSigner, setAddress, setAccount } = 31 | dataSlice.actions; 32 | 33 | export default dataSlice.reducer; 34 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /3x6_MetamaskManagement/LockContract/Lock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "./Token.sol"; 5 | 6 | contract Lock { 7 | BEEToken Token; 8 | uint256 public lockerCount; 9 | uint256 public totalLocked; 10 | mapping(address => uint256) public lockers; 11 | 12 | event Locked( 13 | address indexed locker, 14 | uint256 amount 15 | ); 16 | 17 | constructor(address tokenAddress) { 18 | Token = BEEToken(tokenAddress); 19 | } 20 | 21 | function lockTokens(uint256 amount) external { 22 | require(amount > 0, "Token amount must be bigger than 0."); 23 | 24 | // require(Token.balanceOf(msg.sender) >= amount, "Insufficient balance."); 25 | // require(Token.allowance(msg.sender, address(this)) >= amount, "Insufficient allowance."); 26 | 27 | if(!(lockers[msg.sender] > 0)) lockerCount++; 28 | totalLocked += amount; 29 | lockers[msg.sender] += amount; 30 | 31 | bool ok = Token.transferFrom(msg.sender, address(this), amount); 32 | require(ok, "Transfer failed."); 33 | emit Locked(msg.sender, amount); 34 | } 35 | 36 | function withdrawTokens() external { 37 | require(lockers[msg.sender] > 0, "Not enough token."); 38 | uint256 amount = lockers[msg.sender]; 39 | delete(lockers[msg.sender]); 40 | totalLocked -= amount; 41 | lockerCount--; 42 | require(Token.transfer(msg.sender, amount), "Transfer failed."); 43 | } 44 | } -------------------------------------------------------------------------------- /3x6_MetamaskManagement/LockContract/Token.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract BEEToken is ERC20 { 7 | constructor() ERC20("BEE Token", "BEE") { 8 | _mint(msg.sender, 1773000 * 10**decimals()); 9 | } 10 | } -------------------------------------------------------------------------------- /3x6_MetamaskManagement/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@reduxjs/toolkit": "^1.8.2", 7 | "@testing-library/jest-dom": "^5.16.4", 8 | "@testing-library/react": "^13.3.0", 9 | "@testing-library/user-event": "^13.5.0", 10 | "ethers": "^5.6.9", 11 | "react": "^18.2.0", 12 | "react-dom": "^18.2.0", 13 | "react-redux": "^8.0.2", 14 | "react-scripts": "5.0.1", 15 | "redux": "^4.2.0", 16 | "web-vitals": "^2.1.4" 17 | }, 18 | "scripts": { 19 | "start": "react-scripts start", 20 | "build": "react-scripts build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject" 23 | }, 24 | "eslintConfig": { 25 | "extends": [ 26 | "react-app", 27 | "react-app/jest" 28 | ] 29 | }, 30 | "browserslist": { 31 | "production": [ 32 | ">0.2%", 33 | "not dead", 34 | "not op_mini all" 35 | ], 36 | "development": [ 37 | "last 1 chrome version", 38 | "last 1 firefox version", 39 | "last 1 safari version" 40 | ] 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x6_MetamaskManagement/public/favicon.ico -------------------------------------------------------------------------------- /3x6_MetamaskManagement/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x6_MetamaskManagement/public/logo192.png -------------------------------------------------------------------------------- /3x6_MetamaskManagement/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x6_MetamaskManagement/public/logo512.png -------------------------------------------------------------------------------- /3x6_MetamaskManagement/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/constants/addresses.js: -------------------------------------------------------------------------------- 1 | export const LOCK_ADDRESS = "0x69c19B2D026260da7A0D413f83B6b7dEeCa7bc18"; 2 | export const BEETOKEN_ADDRESS = "0x739A14Bc2A9678e2c639ED97C91C48250d360FB2"; 3 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/constants/networks.js: -------------------------------------------------------------------------------- 1 | export const BSC_TESTNET_NETWORK = { 2 | chainId: "0x61", 3 | chainName: "BSC TESTNET", 4 | rpcUrls: ["https://data-seed-prebsc-1-s1.binance.org:8545"], 5 | nativeCurrency: { 6 | symbol: "BNB", 7 | decimals: 18, 8 | name: "BSC Testnet", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/hooks/useAddress.js: -------------------------------------------------------------------------------- 1 | export const useAddress = () => { 2 | const address = useSelector((state) => state.data.address); 3 | return address; 4 | }; 5 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/hooks/useProvider.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | 3 | export const useProvider = () => { 4 | const provider = useSelector((state) => state.data.provider); 5 | return provider; 6 | }; 7 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/hooks/useSigner.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | 3 | export const useSigner = () => { 4 | const signer = useSelector((state) => state.data.signer); 5 | return signer; 6 | }; 7 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import reportWebVitals from "./reportWebVitals"; 6 | import { store } from "./store"; 7 | import { Provider } from "react-redux"; 8 | 9 | const root = ReactDOM.createRoot(document.getElementById("root")); 10 | root.render( 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/store/index.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit"; 2 | import dataSlice from "./slicers/data"; 3 | import contractsSlice from "./slicers/contracts"; 4 | 5 | export const store = configureStore({ 6 | reducer: { 7 | data: dataSlice, 8 | contracts: contractsSlice, 9 | }, 10 | middleware: (getDefaultMiddleware) => { 11 | return getDefaultMiddleware({ 12 | serializableCheck: false, 13 | }); 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/store/slicers/contracts.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | lock: null, 5 | beeToken: null, 6 | }; 7 | 8 | export const contractsSlice = createSlice({ 9 | name: "contracts", 10 | initialState, 11 | reducers: { 12 | setLockContract: (state, action) => { 13 | state.lock = action.payload; 14 | }, 15 | setBeeTokenContract: (state, action) => { 16 | state.beeToken = action.payload; 17 | }, 18 | }, 19 | }); 20 | 21 | // Action creators are generated for each case reducer function 22 | export const { setLockContract, setBeeTokenContract } = contractsSlice.actions; 23 | 24 | export default contractsSlice.reducer; 25 | -------------------------------------------------------------------------------- /3x6_MetamaskManagement/src/store/slicers/data.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | provider: null, 5 | signer: null, 6 | address: null, 7 | account: null, 8 | }; 9 | 10 | export const dataSlice = createSlice({ 11 | name: "data", 12 | initialState, 13 | reducers: { 14 | setProvider: (state, action) => { 15 | state.provider = action.payload; 16 | }, 17 | setSigner: (state, action) => { 18 | state.signer = action.payload; 19 | }, 20 | setAddress: (state, action) => { 21 | state.address = action.payload; 22 | }, 23 | setAccount: (state, action) => { 24 | state.account = action.payload; 25 | }, 26 | }, 27 | }); 28 | 29 | // Action creators are generated for each case reducer function 30 | export const { setProvider, setSigner, setAddress, setAccount } = 31 | dataSlice.actions; 32 | 33 | export default dataSlice.reducer; 34 | -------------------------------------------------------------------------------- /3x7_Web3Modal/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true -------------------------------------------------------------------------------- /3x7_Web3Modal/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .DS_Store -------------------------------------------------------------------------------- /3x7_Web3Modal/LockContract/Lock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "./Token.sol"; 5 | 6 | contract Lock { 7 | BEEToken Token; 8 | uint256 public lockerCount; 9 | uint256 public totalLocked; 10 | mapping(address => uint256) public lockers; 11 | 12 | event Locked( 13 | address indexed locker, 14 | uint256 amount 15 | ); 16 | 17 | constructor(address tokenAddress) { 18 | Token = BEEToken(tokenAddress); 19 | } 20 | 21 | function lockTokens(uint256 amount) external { 22 | require(amount > 0, "Token amount must be bigger than 0."); 23 | 24 | // require(Token.balanceOf(msg.sender) >= amount, "Insufficient balance."); 25 | // require(Token.allowance(msg.sender, address(this)) >= amount, "Insufficient allowance."); 26 | 27 | if(!(lockers[msg.sender] > 0)) lockerCount++; 28 | totalLocked += amount; 29 | lockers[msg.sender] += amount; 30 | 31 | bool ok = Token.transferFrom(msg.sender, address(this), amount); 32 | require(ok, "Transfer failed."); 33 | emit Locked(msg.sender, amount); 34 | } 35 | 36 | function withdrawTokens() external { 37 | require(lockers[msg.sender] > 0, "Not enough token."); 38 | uint256 amount = lockers[msg.sender]; 39 | delete(lockers[msg.sender]); 40 | totalLocked -= amount; 41 | lockerCount--; 42 | require(Token.transfer(msg.sender, amount), "Transfer failed."); 43 | } 44 | } -------------------------------------------------------------------------------- /3x7_Web3Modal/LockContract/Token.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.2; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract BEEToken is ERC20 { 7 | constructor() ERC20("BEE Token", "BEE") { 8 | _mint(msg.sender, 1773000 * 10**decimals()); 9 | } 10 | } -------------------------------------------------------------------------------- /3x7_Web3Modal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@coinbase/wallet-sdk": "^3.0.5", 7 | "@reduxjs/toolkit": "^1.6.2", 8 | "@testing-library/jest-dom": "5.16.3", 9 | "@testing-library/react": "12.1.4", 10 | "@testing-library/user-event": "13.5.0", 11 | "@web3-react/walletlink-connector": "^6.2.14", 12 | "ethers": "^5.6.9", 13 | "react": "17.0.2", 14 | "react-dom": "17.0.2", 15 | "react-redux": "^7.2.6", 16 | "react-scripts": "4.0.0", 17 | "redux": "^4.2.0", 18 | "web-vitals": "^2.1.4", 19 | "web3modal": "^1.9.8" 20 | }, 21 | "scripts": { 22 | "start": "react-scripts start", 23 | "build": "react-scripts build", 24 | "test": "react-scripts test", 25 | "eject": "react-scripts eject" 26 | }, 27 | "eslintConfig": { 28 | "extends": [ 29 | "react-app", 30 | "react-app/jest" 31 | ] 32 | }, 33 | "browserslist": { 34 | "production": [ 35 | ">0.2%", 36 | "not dead", 37 | "not op_mini all" 38 | ], 39 | "development": [ 40 | "last 1 chrome version", 41 | "last 1 firefox version", 42 | "last 1 safari version" 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /3x7_Web3Modal/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x7_Web3Modal/public/favicon.ico -------------------------------------------------------------------------------- /3x7_Web3Modal/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x7_Web3Modal/public/logo192.png -------------------------------------------------------------------------------- /3x7_Web3Modal/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/3x7_Web3Modal/public/logo512.png -------------------------------------------------------------------------------- /3x7_Web3Modal/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /3x7_Web3Modal/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/constants/addresses.js: -------------------------------------------------------------------------------- 1 | export const LOCK_ADDRESS = "0x69c19B2D026260da7A0D413f83B6b7dEeCa7bc18"; 2 | export const BEETOKEN_ADDRESS = "0x739A14Bc2A9678e2c639ED97C91C48250d360FB2"; 3 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/constants/networks.js: -------------------------------------------------------------------------------- 1 | export const BSC_TESTNET_NETWORK = { 2 | chainId: "0x61", 3 | chainName: "BSC TESTNET", 4 | rpcUrls: ["https://data-seed-prebsc-1-s1.binance.org:8545"], 5 | nativeCurrency: { 6 | symbol: "BNB", 7 | decimals: 18, 8 | name: "BSC Testnet", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/hooks/useAddress.js: -------------------------------------------------------------------------------- 1 | export const useAddress = () => { 2 | const address = useSelector((state) => state.data.address); 3 | return address; 4 | }; 5 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/hooks/useProvider.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | 3 | export const useProvider = () => { 4 | const provider = useSelector((state) => state.data.provider); 5 | return provider; 6 | }; 7 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/hooks/useSigner.js: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | 3 | export const useSigner = () => { 4 | const signer = useSelector((state) => state.data.signer); 5 | return signer; 6 | }; 7 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import reportWebVitals from "./reportWebVitals"; 6 | import { store } from "./store"; 7 | import { Provider } from "react-redux"; 8 | 9 | ReactDOM.render( 10 | 11 | 12 | 13 | 14 | , 15 | document.getElementById("root") 16 | ); 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/store/index.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit"; 2 | import dataSlice from "./slicers/data"; 3 | import contractsSlice from "./slicers/contracts"; 4 | 5 | export const store = configureStore({ 6 | reducer: { 7 | data: dataSlice, 8 | contracts: contractsSlice, 9 | }, 10 | middleware: (getDefaultMiddleware) => { 11 | return getDefaultMiddleware({ 12 | serializableCheck: false, 13 | }); 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/store/slicers/contracts.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | lock: null, 5 | beeToken: null, 6 | }; 7 | 8 | export const contractsSlice = createSlice({ 9 | name: "contracts", 10 | initialState, 11 | reducers: { 12 | setLockContract: (state, action) => { 13 | state.lock = action.payload; 14 | }, 15 | setBeeTokenContract: (state, action) => { 16 | state.beeToken = action.payload; 17 | }, 18 | }, 19 | }); 20 | 21 | // Action creators are generated for each case reducer function 22 | export const { setLockContract, setBeeTokenContract } = contractsSlice.actions; 23 | 24 | export default contractsSlice.reducer; 25 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/store/slicers/data.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | provider: null, 5 | signer: null, 6 | address: null, 7 | account: null, 8 | }; 9 | 10 | export const dataSlice = createSlice({ 11 | name: "data", 12 | initialState, 13 | reducers: { 14 | setProvider: (state, action) => { 15 | state.provider = action.payload; 16 | }, 17 | setSigner: (state, action) => { 18 | state.signer = action.payload; 19 | }, 20 | setAddress: (state, action) => { 21 | state.address = action.payload; 22 | }, 23 | setAccount: (state, action) => { 24 | state.account = action.payload; 25 | }, 26 | }, 27 | }); 28 | 29 | // Action creators are generated for each case reducer function 30 | export const { setProvider, setSigner, setAddress, setAccount } = 31 | dataSlice.actions; 32 | 33 | export default dataSlice.reducer; 34 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/web3modal/index.js: -------------------------------------------------------------------------------- 1 | import CoinbaseWalletSDK from "@coinbase/wallet-sdk"; 2 | import { WalletLinkConnector } from "@web3-react/walletlink-connector"; 3 | 4 | export const providerOptions = { 5 | walletlink: { 6 | package: CoinbaseWalletSDK, // Required 7 | options: { 8 | appName: "Your dApp", 9 | rpc: "https://api.avax-test.network/ext/bc/C/rpc", 10 | }, 11 | }, 12 | }; 13 | 14 | export const CoinbaseWallet = new WalletLinkConnector({ 15 | url: `https://mainnet.infura.io/v3/${process.env.INFURA_KEY}`, 16 | appName: "Your dAppName", 17 | supportedChainIds: [1, 3, 4, 5, 42, 56], 18 | }); 19 | -------------------------------------------------------------------------------- /3x7_Web3Modal/src/web3modal/useWalletConnection.js: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import Web3Modal from "web3modal"; 3 | import { providerOptions } from "."; 4 | 5 | const web3Modal = new Web3Modal({ 6 | cacheProvider: false, 7 | providerOptions, 8 | theme: "dark", 9 | disableInjectedProvider: false, 10 | }); 11 | 12 | export const useWalletConnection = () => { 13 | const connectWallet = async () => { 14 | try { 15 | const connector = await web3Modal.connect(); 16 | const provider = new ethers.providers.Web3Provider(connector); 17 | const accounts = await provider.listAccounts(); 18 | const network = await provider.getNetwork(); 19 | 20 | const signer = await provider.getSigner(); 21 | const address = await signer.getAddress(); 22 | 23 | console.log(accounts, network, address); 24 | } catch (error) {} 25 | }; 26 | 27 | const disconnect = async () => { 28 | await web3Modal.clearCachedProvider(); 29 | window.location.reload(); 30 | }; 31 | 32 | return { connectWallet, disconnect }; 33 | }; 34 | -------------------------------------------------------------------------------- /4x0_SmartContractSecurity_1/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde akıllı kontrat güvenliğine giriş yaptık ve akıllı kontrat yazarken yapılan hatalardan biri olan dikkat hatalarının üzerinden nasıl geleceğimize değindik. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=SqTW-uKnsoE&ab_channel=ITUBlockchain) 6 | 7 | [Exploit1.sol](./Exploit1.sol) 8 | 9 | [Exploit2.sol](./Exploit2.sol) 10 | 11 | [Secureum Yazıları](https://secureum.substack.com) 12 | -------------------------------------------------------------------------------- /4x0_SmartContractSecurity_1/Slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/4x0_SmartContractSecurity_1/Slides.pdf -------------------------------------------------------------------------------- /4x1_SmartContractSecurity_2/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde akıllı kontrat güvenliğine giriş yaptık ve akıllı kontrat yazarken yapılan hatalardan biri olan mantık hatalarının üzerinden nasıl geleceğimize değindik. 4 | 5 | [Exploit3.sol](./Exploit3.sol) 6 | [Exploit4.sol](./Exploit4.sol) 7 | 8 | [DEX hatasının detayları](https://medium.com/@this_post/ethernaut-22-dex-modified-version-writeups-4330c33a0743) 9 | [Ethernaut Challenge'ları](https://ethernaut.openzeppelin.com/) -------------------------------------------------------------------------------- /4x1_SmartContractSecurity_2/Slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/4x1_SmartContractSecurity_2/Slides.pdf -------------------------------------------------------------------------------- /4x4_Slither/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde akıllı kontrat geliştiriciliğinde sıkça kullanılan araçlardan 4 | biri olan Slither'ı ele aldık ve statik analiz methodunun artıları eksilerinden 5 | bahsettik. 6 | 7 | [BadRandomness.sol](./BadRandomness.sol) 8 | [Reentrancy.sol](./Reentrancy.sol) 9 | 10 | [Slither Github](https://github.com/crytic/slither) 11 | [Slither'ın bulduğu hatalar](https://github.com/crytic/slither/wiki/Detector-Documentation) 12 | [Docker talimatları](https://docs.docker.com/get-docker/) 13 | -------------------------------------------------------------------------------- /4x4_Slither/Reentrancy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.15; 2 | 3 | contract Reentrance { 4 | mapping (address => uint) userBalance; 5 | 6 | function getBalance(address u) constant returns(uint){ 7 | return userBalance[u]; 8 | } 9 | 10 | function addToBalance() payable{ 11 | userBalance[msg.sender] += msg.value; 12 | } 13 | 14 | function withdrawBalance(){ 15 | // send userBalance[msg.sender] ethers to msg.sender 16 | // if mgs.sender is a contract, it will call its fallback function 17 | if(!(msg.sender.call.value(userBalance[msg.sender])())){ 18 | throw; 19 | } 20 | userBalance[msg.sender] = 0; 21 | } 22 | 23 | function withdrawBalance_fixed(){ 24 | // to protect against re-entrancy, the state variable 25 | // has to be change before the call 26 | uint amount = userBalance[msg.sender]; 27 | userBalance[msg.sender] = 0; 28 | if( ! (msg.sender.call.value(amount)() ) ){ 29 | throw; 30 | } 31 | } 32 | 33 | function withdrawBalance_fixed_2(){ 34 | // send() and transfer() are safe against reentrancy 35 | // they do not transfer the remaining gas 36 | // and they give just enough gas to execute few instructions 37 | // in the fallback function (no further call possible) 38 | msg.sender.transfer(userBalance[msg.sender]); 39 | userBalance[msg.sender] = 0; 40 | } 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /4x5_Echidna/Exercise1.sol: -------------------------------------------------------------------------------- 1 | // Create a scenario where contract is paused and ownership is revoked 2 | // Try the property that the contract cannot be unpaused 3 | 4 | pragma solidity ^0.7.0; 5 | 6 | contract Ownership{ 7 | address owner = msg.sender; 8 | function Owner() public { 9 | owner = msg.sender; 10 | } 11 | 12 | modifier isOwner(){ 13 | require(owner == msg.sender); 14 | _; 15 | } 16 | } 17 | 18 | contract Pausable is Ownership{ 19 | bool is_paused; 20 | 21 | modifier ifNotPaused() { 22 | require(!is_paused); 23 | _; 24 | } 25 | 26 | function paused() isOwner public{ 27 | is_paused = true; 28 | } 29 | 30 | function resume() isOwner public{ 31 | is_paused = false; 32 | } 33 | } 34 | 35 | contract Token is Pausable{ 36 | mapping(address => uint) public balances; 37 | 38 | function transfer(address to, uint value) ifNotPaused public{ 39 | balances[msg.sender] -= value; 40 | balances[to] += value; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /4x5_Echidna/Exercise2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.7.0; 2 | 3 | contract Ownership{ 4 | address owner = msg.sender; 5 | 6 | function Owner() public { 7 | owner = msg.sender; 8 | } 9 | 10 | modifier isOwner(){ 11 | require(owner == msg.sender); 12 | _; 13 | } 14 | } 15 | 16 | contract Pausable is Ownership{ 17 | bool is_paused; 18 | 19 | modifier ifNotPaused(){ 20 | require(!is_paused); 21 | _; 22 | } 23 | 24 | function paused() isOwner public{ 25 | is_paused = true; 26 | } 27 | 28 | function resume() isOwner public{ 29 | is_paused = false; 30 | } 31 | } 32 | 33 | contract Token is Pausable{ 34 | mapping(address => uint) public balances; 35 | 36 | function transfer(address to, uint value) ifNotPaused public{ 37 | balances[msg.sender] -= value; 38 | balances[to] += value; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /4x5_Echidna/Solution1.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.7.0; 2 | 3 | import {Token} from "./Exercise1.sol"; 4 | 5 | contract Exercise1Test is Token { 6 | address echidna_caller = msg.sender; 7 | 8 | constructor() public { 9 | balances[echidna_caller] = 10000; 10 | } 11 | 12 | function echidna_test_balance() public view returns(bool) { 13 | // We expect lte 10k, else we should fail 14 | return balances[echidna_caller] <= 10000; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /4x5_Echidna/Solution2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import {Token} from "./Exercise2.sol"; 4 | 5 | contract Exercise1Test is Token { 6 | constructor() { 7 | paused(); 8 | owner = address(0x0); 9 | } 10 | 11 | function echidna_cannot_unpause() public view returns(bool) { 12 | return is_paused; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /4x5_Echidna/Solution5.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.8.0; 2 | 3 | import "./UnstoppableLender.sol"; 4 | import "../DamnValuableToken.sol"; 5 | 6 | contract UnstoppableLenderEchidna { 7 | uint256 constant TOKENS_IN_POOL = 1_000_000 ether; 8 | uint256 constant INITIAL_ATTACKER_TOKEN_BALANCE = 100 ether; 9 | 10 | DamnValuableToken dvt; 11 | UnstoppableLender unl; 12 | 13 | constructor() { 14 | dvt = new DamnValuableToken(); 15 | unl = new UnstoppableLender( address(dvt) ); 16 | 17 | dvt.approve(address(unl), TOKENS_IN_POOL); 18 | unl.depositTokens(TOKENS_IN_POOL); 19 | 20 | dvt.transfer(msg.sender, INITIAL_ATTACKER_TOKEN_BALANCE); 21 | } 22 | 23 | function receiveTokens(address tokenAddr, uint256 amount) external { 24 | require(msg.sender == address(unl)); 25 | require(dvt.transfer(msg.sender, amount)); 26 | } 27 | 28 | function echidna_flashLoan() public returns (bool) { 29 | unl.flashLoan(100); 30 | return true; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /4x5_Echidna/solution5.config.yaml: -------------------------------------------------------------------------------- 1 | # The deployer and sender must be the same for this example. 2 | # The deployer is the 'attacker' and is sent INITIAL_ATTACKER_BALANCE 3 | deployer: '0x30000' 4 | # Sender must be the same so that it can use the attacker balance to try to break the invariant. 5 | sender: ['0x30000'] 6 | # Allow for multi-abi use 7 | multi-abi: true 8 | 9 | # Allow Echidna to run for more cycles. This will aid in additional exploration. 10 | testLimit: 1000000 11 | # Filter functions that will definitely revert to aid Echidna in exploration 12 | filterBlacklist: true 13 | filterFunctions: [ 14 | 'UnstoppableLender.depositTokens(uint256)', 15 | 'UnstoppableLender.flashLoan(uint256)', 16 | 'ReceiverUnstoppable.receiveTokens(address,uint256)', 17 | 'ReceiverUnstoppable.executeFlashLoan(uint256)' 18 | ] 19 | -------------------------------------------------------------------------------- /5x0_ERC20/ERC-20/ERC20.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.4; 3 | 4 | import "@openzeppelin/contracts@4.6.0/token/ERC20/ERC20.sol"; 5 | 6 | contract ITUBlockchain is ERC20 { 7 | mapping(address => uint) time; 8 | 9 | constructor() ERC20("ITU Blockchain", "ITU") { 10 | } 11 | 12 | function mint(address to) public { 13 | _mint(to, (block.timestamp - totalSupply())); 14 | } 15 | 16 | function burn(address from, uint amount) public { 17 | _burn(from, amount); 18 | } 19 | 20 | function transfer(address to, uint amount) public virtual override returns(bool){ 21 | require(block.timestamp - time[_msgSender()] > 20); 22 | time[_msgSender()] = block.timestamp; 23 | 24 | return super.transfer(to, amount); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /5x1_ERC721/ERC-721/ERC721.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.4; 3 | 4 | import "@openzeppelin/contracts@4.6.0/token/ERC721/ERC721.sol"; 5 | import "@openzeppelin/contracts@4.6.0/utils/Strings.sol"; 6 | 7 | 8 | contract ITUBlockchain is ERC721 { 9 | using Strings for uint256; 10 | 11 | constructor() ERC721("ITU Blockchain", "ITU") { 12 | 13 | } 14 | 15 | function _baseURI() internal pure override returns (string memory) { 16 | return "ipfs://QmPCDduf9Cbdfd1JvHUxD7srqKTz4MehG6SyeH29SZaFdy/"; 17 | } 18 | 19 | function tokenURI(uint256 tokenId) public view virtual override returns(string memory){ 20 | super.tokenURI; 21 | 22 | ownerOf(tokenId); 23 | return string(abi.encodePacked(_baseURI(), tokenId.toString(), ".json")); 24 | } 25 | 26 | 27 | function safeMint(address to, uint256 tokenId) public { 28 | _safeMint(to, tokenId); 29 | } 30 | } 31 | 32 | contract Empty { 33 | 34 | } -------------------------------------------------------------------------------- /5x2_ERC1155/ERC-1155/ERC1155.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.4; 3 | 4 | import "@openzeppelin/contracts@4.6.0/token/ERC1155/ERC1155.sol"; 5 | import "@openzeppelin/contracts@4.6.0/access/Ownable.sol"; 6 | 7 | contract ITUBlockchain is ERC1155, Ownable { 8 | string public name; 9 | string public symbol; 10 | constructor() ERC1155("") { 11 | name = "ITU Blockchain"; 12 | symbol = "ITU"; 13 | } 14 | 15 | function mint(address account, uint256 id, uint256 amount, bytes memory data) 16 | public 17 | payable 18 | { 19 | require(id < 3); 20 | require(msg.value == 1 ether); 21 | _mint(account, id, amount, data); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 25 | 26 | # dependencies 27 | /node_modules 28 | /.pnp 29 | .pnp.js 30 | 31 | # testing 32 | /coverage 33 | 34 | # production 35 | /build 36 | 37 | # misc 38 | .DS_Store 39 | .env.local 40 | .env.development.local 41 | .env.test.local 42 | .env.production.local 43 | 44 | npm-debug.log* 45 | yarn-debug.log* 46 | yarn-error.log* 47 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "marketplace-interface", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@alch/alchemy-sdk": "^1.0.8", 7 | "@openzeppelin/contracts": "^4.7.0", 8 | "@reduxjs/toolkit": "^1.8.3", 9 | "@testing-library/jest-dom": "^5.16.4", 10 | "@testing-library/react": "^13.3.0", 11 | "@testing-library/user-event": "^13.5.0", 12 | "dotenv": "^16.0.1", 13 | "ethers": "^5.6.9", 14 | "fs": "^0.0.1-security", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "react-redux": "^8.0.2", 18 | "react-router-dom": "^6.3.0", 19 | "react-scripts": "5.0.1", 20 | "sass": "^1.53.0", 21 | "web-vitals": "^2.1.4" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build": "react-scripts build", 26 | "test": "react-scripts test", 27 | "eject": "react-scripts eject" 28 | }, 29 | "eslintConfig": { 30 | "extends": [ 31 | "react-app", 32 | "react-app/jest" 33 | ] 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.2%", 38 | "not dead", 39 | "not op_mini all" 40 | ], 41 | "development": [ 42 | "last 1 chrome version", 43 | "last 1 firefox version", 44 | "last 1 safari version" 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/public/favicon.ico -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/public/logo192.png -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/public/logo512.png -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/App.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0; 3 | background: #E2DCE9; 4 | font-family: sans-serif; 5 | } -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/App.js: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import { Navbar } from "./Components"; 3 | import { MyNFTs, ListedItems, Home } from "./Pages"; 4 | import { useDispatch, useSelector } from "react-redux"; 5 | import { BrowserRouter, Route, Routes } from "react-router-dom"; 6 | 7 | 8 | function App() { 9 | const dispatch = useDispatch(); 10 | const currentAccount = useSelector((state) => state.accounts.account); 11 | 12 | 13 | return ( 14 |
15 | 16 | 17 | {currentAccount ? ( 18 | 19 | } /> 20 | } /> 21 | } /> 22 | Not found
} /> 23 | 24 | ) : ( 25 |
You Should connect wallet!
26 | )} 27 | 28 | {/* */} 29 | 30 | ); 31 | } 32 | 33 | export default App; 34 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Assets/logo.png -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Components/Navbar/Navbar.js: -------------------------------------------------------------------------------- 1 | import LOGO from "../../Assets/logo.png"; 2 | import styles from "./Navbar.module.scss"; 3 | import { useSetAccount } from "../../Hooks/useSetAccount"; 4 | import { useSelector } from "react-redux"; 5 | import { parseAddress } from "../../utils/parseAddress"; 6 | import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; 7 | import { Link, useLocation } from "react-router-dom"; 8 | const Navbar = () => { 9 | const { connectAccount } = useSetAccount(); 10 | 11 | const account = useSelector((state) => state.accounts.account); 12 | 13 | return ( 14 |
15 |
16 | 17 | 18 | 19 | ITU BLOCKCHAIN MARKETPLACE 20 |
21 |
22 |
23 | My NFTs 24 | Listed Items 25 | Auctions 26 |
27 |
28 | 36 |
37 | ); 38 | }; 39 | 40 | export { Navbar }; 41 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Components/index.js: -------------------------------------------------------------------------------- 1 | export { Navbar } from "./Navbar/Navbar"; 2 | export { NFT } from "./NFT/NFT"; 3 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Hooks/useContractFunctions.js: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { CONTRACT_ADDRESS } from "./../Contract/Constant/Info"; 3 | import { ABI, ABI2 } from "./../Contract/Constant/Info"; 4 | 5 | export const useContractFunctions = () => { 6 | const provider = new ethers.providers.Web3Provider(window.ethereum); 7 | const signer = provider.getSigner(); 8 | const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, signer); 9 | 10 | const startNFTSale = async (_contractAddress, _price, _tokenId) => { 11 | const contract2 = new ethers.Contract(_contractAddress, ABI2, signer); 12 | const sitution = await contract2.getApproved(_tokenId); 13 | console.log(sitution === CONTRACT_ADDRESS.toString()); 14 | if (sitution === CONTRACT_ADDRESS.toString()) { 15 | await contract.startNFTSale(_contractAddress, _price, _tokenId); 16 | } else { 17 | await contract2.approve(CONTRACT_ADDRESS.toString(), _tokenId); 18 | } 19 | }; 20 | const buyNFT = async (_id, _price) => { 21 | console.log(_id, _price); 22 | await contract.buyNFT(_id, { value: Number(_price) }); 23 | }; 24 | 25 | return { 26 | startNFTSale, 27 | buyNFT, 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/Auctions/Auctions.js: -------------------------------------------------------------------------------- 1 | import styles from "./Auctions.module.scss"; 2 | 3 | const Auctions = () => { 4 | return( 5 |
xd
6 | ) 7 | } 8 | 9 | export {Auctions}; -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/Auctions/Auctions.module.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/Auctions/Auctions.module.scss -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/Home/Home.js: -------------------------------------------------------------------------------- 1 | import styles from "./Home.module.scss"; 2 | 3 | const Home = () => { 4 | return ( 5 |
6 |

ITU Blockchain Marketplace

7 |

Follow on Twitter: @ITUBlockchain

8 |
9 | ); 10 | }; 11 | 12 | export { Home }; 13 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/Home/Home.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper{ 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | flex-direction: column; 6 | margin-top: 150px; 7 | } -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/ListedItems/ListedItems.js: -------------------------------------------------------------------------------- 1 | import styles from "./ListedItems.module.scss"; 2 | import { useSelector } from "react-redux"; 3 | import { useEffect, useState } from "react"; 4 | import { NFT } from "../../Components"; 5 | import { ethers } from "ethers"; 6 | import { CONTRACT_ADDRESS } from "../../Contract/Constant/Info"; 7 | import { ABI } from "../../Contract/Constant/Info"; 8 | import { useGetNFTs } from "../../Hooks/useGetNFTs"; 9 | 10 | const ListedItems = () => { 11 | const acc = useSelector((state) => state.accounts.account); 12 | const listeditems = useSelector((state) => state.accounts.listedNFTs); 13 | const { getListedNFTs } = useGetNFTs(); 14 | useEffect(() => { 15 | const work = async () => { 16 | getListedNFTs(); 17 | }; 18 | work(); 19 | }, []); 20 | 21 | return ( 22 |
23 | {listeditems.length > 0 24 | ? listeditems.map((item, i) => { 25 | return ( 26 | 34 | ); 35 | }) 36 | : "Listed NFTs Information Is Loading..."} 37 |
38 | ); 39 | }; 40 | 41 | export { ListedItems }; 42 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/ListedItems/ListedItems.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper{ 2 | display: flex; 3 | gap: 10px; 4 | flex-wrap: wrap; 5 | margin: 0px 50px; 6 | justify-content: center; 7 | align-items: center; 8 | } -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/MyNFTs/MyNFTs.module.scss: -------------------------------------------------------------------------------- 1 | .wrapper{ 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | flex-wrap: wrap; 6 | } -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Pages/index.js: -------------------------------------------------------------------------------- 1 | export { Auctions } from "./Auctions/Auctions"; 2 | export { Home } from "./Home/Home"; 3 | export { ListedItems } from "./ListedItems/ListedItems"; 4 | export { MyNFTs } from "./MyNFTs/MyNFTs"; 5 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Store/index.js: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit"; 2 | import accountReducer from "./slicers/accounts"; 3 | 4 | export default configureStore({ 5 | reducer: { 6 | accounts: accountReducer, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/Store/slicers/accounts.js: -------------------------------------------------------------------------------- 1 | import { createSlice } from "@reduxjs/toolkit"; 2 | 3 | const initialState = { 4 | account: null, 5 | contract: null, 6 | provider: null, 7 | accNFTs: null, 8 | listedNFTs: [] 9 | }; 10 | 11 | export const accountsSlice = createSlice({ 12 | name: "accounts", 13 | initialState, 14 | reducers: { 15 | setAccount: (state, action) => { 16 | state.account = action.payload; 17 | console.log(state.contract); 18 | }, 19 | setContract: (state, action) => { 20 | state.contract = action.payload; 21 | }, 22 | setProvider: (state, action) => { 23 | state.provider = action.payload; 24 | }, 25 | setNFTs: (state, action) => { 26 | state.accNFTs = action.payload; 27 | }, 28 | setListedNFTs: (state, action) => { 29 | state.listedNFTs = action.payload; 30 | }, 31 | }, 32 | }); 33 | 34 | export const { setAccount, setContract, setProvider, setNFTs, setListedNFTs } = accountsSlice.actions; 35 | export default accountsSlice.reducer; 36 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import App from "./App"; 4 | import store from "./Store"; 5 | import { Provider } from "react-redux"; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById("root")); 8 | 9 | root.render( 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/utils/clsnm.js: -------------------------------------------------------------------------------- 1 | export function clsnm(...classNames) { 2 | let className = ""; 3 | 4 | for (let i = 0; i < classNames?.length; i++) { 5 | if (classNames[i] && classNames[i] !== true) { 6 | className += `${i === 0 ? "" : " "}${classNames[i]}`; 7 | } 8 | } 9 | 10 | return className; 11 | } -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/NFTMarketplace_Interface/src/utils/parseAddress.js: -------------------------------------------------------------------------------- 1 | export const parseAddress = (address) => { 2 | return ( 3 | address?.substring?.(0, 5) + 4 | "..." + 5 | address?.substring?.(address?.length - 5) 6 | ); 7 | }; -------------------------------------------------------------------------------- /5x4_NFTMarketplace_Interface/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde bir önceki derste hazırladığımız NFT Marketplace contratı için kullanıcı etkileşim arayüzü kodladık. Bunun için React tercihinde bulunduk. Sadece kullanıcıların sahip oldukları NFT'leri ve direk satış için gerekli sayfayı içeren bu websitesini inceleyerek Alchemy API kullanımını, Ethersjs ile kontrat etkileşimini öğrenebilirsiniz. 4 | 5 |
6 | 7 | [Video İçeriği](https://www.youtube.com/watch?v=zf4orRramo4) 8 | 9 | [Proje Dizini](./NFTMarketplace_Interface) 10 | -------------------------------------------------------------------------------- /5x5_MultisigWallet/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde çeşitli organizasyon fonlarının ve akıllı kontratlarının yönetiminde sıklıkla başvurduğumuz Multisig yani "Çoklu İmza Gerektiren" cüzdanlara yönelik basit bir akıllı kontrat örneği geliştirdik. Ayrıca bu örnekle beraber ise Ethereum cüzdan / hesap modelinin nasıl çalıştığına değindik. 4 | 5 |
6 | 7 | wallets 8 | 9 |
10 | 11 | eoa_in_network 12 | 13 | accounts_txs 14 | 15 | account_model 16 | 17 |
18 | 19 | [Video İçeriği](https://www.youtube.com/watch?v=XbMWZj0BYvA) 20 | 21 | [Wallet Kontratı](./MultiSig.sol) 22 | -------------------------------------------------------------------------------- /5x5_MultisigWallet/accmodel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x5_MultisigWallet/accmodel.png -------------------------------------------------------------------------------- /5x5_MultisigWallet/accstxs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x5_MultisigWallet/accstxs.png -------------------------------------------------------------------------------- /5x5_MultisigWallet/eoainnw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x5_MultisigWallet/eoainnw.png -------------------------------------------------------------------------------- /5x5_MultisigWallet/multisig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/5x5_MultisigWallet/multisig.png -------------------------------------------------------------------------------- /5x6_SimpleBasketballGame/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde akıllı kontrat geliştirme pratiği oluşturma adına NFT tabanlı tamamen on-chain bir 3'e 3 basketbol menajer oyununun blockchain bölümünü geliştirdik. 4 | 5 |
6 | 7 | [Video İçeriği](https://youtu.be/DtnFYq_sxvU) 8 | 9 | [Proje Kontratları](./contracts) 10 | -------------------------------------------------------------------------------- /5x6_SimpleBasketballGame/contracts/Marketplace.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifer: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "./tokens/W3J721.sol"; 5 | 6 | contract Marketplace { 7 | // 8 | 9 | constructor(address nftAddress) { 10 | // Create token instance 11 | } 12 | 13 | function listPlayer(uint256 tokenId, uint256 price) external { 14 | // Check the ownership of the player 15 | // Take the sale price and store it 16 | // Create a data structure to hold listings 17 | // Transfer NFT to the Marketplace 18 | } 19 | 20 | function removeListing(uint256 tokenId) external { 21 | // Check if the player is listed from the msg.sender 22 | // Give the player back to the msg.sender 23 | // Clean listing data 24 | 25 | } 26 | 27 | function buyPlayer(uint256 tokenId) external payable { 28 | // Check the player is on sale for the msg.value 29 | // Clean listing data 30 | // Send the msg.value to the NFT's old owner, but take commision for the game treasury 31 | // Send the NFT to the new owner 32 | } 33 | 34 | function changePrice(uint256 tokenId, uint256 price) external { 35 | // Check if the player is listed from the msg.sender 36 | // Edit the listing data 37 | } 38 | } -------------------------------------------------------------------------------- /5x7_StakingContract/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde akıllı kontrat geliştirme pratiği oluşturma adına Staking Contract üzerine bir video hazırladık. İki bölümden oluşacak bu konseptin ilk videosunda token başına ödül kazanılmasını sağlayan Staking Contract'ını geliştirdik. 4 | 5 |
6 | 7 | [Video İçeriği](https://youtu.be/BSGkOhwdx1c) 8 | 9 | [Proje Kontratları](./contracts) 10 | -------------------------------------------------------------------------------- /5x8_BasicDEX&AMM/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | typechain-types 7 | 8 | #Hardhat files 9 | cache 10 | artifacts 11 | 12 | -------------------------------------------------------------------------------- /5x8_BasicDEX&AMM/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde bir DEX - AMM'in nasıl çalıştığını basit br kontrat örneği üzerinden inceledik. 4 | 5 |
6 | 7 | [Video İçeriği](https://youtu.be/6AUfrT1Envw) 8 | 9 | [Proje Kontratları](./contracts) 10 | 11 | [Kaynaklar](https://jeiwan.net/posts/programming-defi-uniswap-1/) 12 | -------------------------------------------------------------------------------- /5x8_BasicDEX&AMM/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomicfoundation/hardhat-toolbox"); 2 | 3 | /** @type import('hardhat/config').HardhatUserConfig */ 4 | module.exports = { 5 | solidity: "0.8.17", 6 | }; 7 | -------------------------------------------------------------------------------- /5x8_BasicDEX&AMM/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@ethersproject/abi": "^5.4.7", 4 | "@ethersproject/providers": "^5.4.7", 5 | "@nomicfoundation/hardhat-chai-matchers": "^1.0.0", 6 | "@nomicfoundation/hardhat-network-helpers": "^1.0.0", 7 | "@nomicfoundation/hardhat-toolbox": "^2.0.0", 8 | "@nomiclabs/hardhat-ethers": "^2.0.0", 9 | "@nomiclabs/hardhat-etherscan": "^3.0.0", 10 | "@openzeppelin/contracts": "^4.7.3", 11 | "@typechain/ethers-v5": "^10.1.0", 12 | "@typechain/hardhat": "^6.1.2", 13 | "chai": "^4.2.0", 14 | "ethers": "^5.4.7", 15 | "hardhat": "^2.12.1", 16 | "hardhat-gas-reporter": "^1.0.8", 17 | "solidity-coverage": "^0.8.0", 18 | "typechain": "^8.1.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /6x0_MerkleTrees/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json 3 | .deps/ 4 | artifacts/ -------------------------------------------------------------------------------- /6x0_MerkleTrees/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde, "Whitlesit ve Airdrop" gibi durumlarda adres listelerinin blockchaine iletilmesinde sıklıkla başvurulan kriptografik bir kanıtlama yöntemi olan "Merkle Proof"ların akıllı kontratlara nasıl entegre edilebileceğine yönelik bir örnek yaptık. 4 | 5 | mainnet_forking 6 | 7 | Sıfırdan merkle script'i hazırlamak için: 8 | 9 | ```bash 10 | npm init -y 11 | 12 | npm i merkletreejs 13 | 14 | npm i keccak256 15 | 16 | npm i ethers 17 | 18 | node merkle 19 | ``` 20 | 21 | Klasörü klonlayıp çalışmak için: 22 | 23 | ```bash 24 | npm i 25 | ``` 26 | [Video İçeriği](https://youtu.be/9gGkPPui_tw) 27 | 28 | [Merkle Tree Oluşturma Scripti](.merkle.js) 29 | 30 | [Uygulama Örneği](./WLMint.sol) 31 | 32 | [Merkle Proof Contract (Link Below)](./Merkle.sol) 33 | 34 | [ENS Merkle Proof Contract Link](https://github.com/ensdomains/governance/blob/master/contracts/MerkleProof.sol) 35 | 36 | [OpenZeppelin Bitmaps](https://docs.openzeppelin.com/contracts/4.x/api/utils#BitMaps) -------------------------------------------------------------------------------- /6x0_MerkleTrees/WLMint.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 5 | import "@openzeppelin/contracts/utils/structs/BitMaps.sol"; 6 | import "./Merkle.sol"; 7 | 8 | contract MerkleNFT is ERC721 { 9 | using BitMaps for BitMaps.BitMap; 10 | 11 | bytes32 public merkleRoot; 12 | BitMaps.BitMap private minted; 13 | uint256 public lastId; 14 | 15 | constructor(bytes32 root) ERC721("MerkleNFT", "MNFT") { 16 | merkleRoot = root; 17 | } 18 | 19 | function wlMint(uint256 amount, bytes32[] calldata merkleProof) external { 20 | bytes32 leafNode = keccak256(abi.encodePacked(msg.sender, amount)); 21 | (bool v, uint256 i) = MerkleProof.verify( 22 | merkleProof, 23 | merkleRoot, 24 | leafNode 25 | ); 26 | require(v, "Not matching."); 27 | require(!minted.get(i), "Already minted."); 28 | minted.set(i); 29 | mint(msg.sender, amount); 30 | } 31 | 32 | function mint(address to, uint256 amount) private { 33 | for (uint256 i; i < amount; i++) { 34 | lastId++; 35 | _safeMint(to, lastId); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /6x0_MerkleTrees/hashtree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/6x0_MerkleTrees/hashtree.png -------------------------------------------------------------------------------- /6x0_MerkleTrees/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "6x0_merkletrees", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "ethers": "^5.6.9", 14 | "keccak256": "^1.0.6", 15 | "merkletreejs": "^0.2.32" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /6x3_ChainlinkApplication/ChainlinkApplication/ConfirmedOwner.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "./ConfirmedOwnerWithProposal.sol"; 5 | 6 | /** 7 | * @title The ConfirmedOwner contract 8 | * @notice A contract with helpers for basic contract ownership. 9 | */ 10 | contract ConfirmedOwner is ConfirmedOwnerWithProposal { 11 | constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {} 12 | } -------------------------------------------------------------------------------- /6x3_ChainlinkApplication/ChainlinkApplication/interfaces/AggregatorV3Interface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface AggregatorV3Interface { 5 | function decimals() external view returns (uint8); 6 | 7 | function description() external view returns (string memory); 8 | 9 | function version() external view returns (uint256); 10 | 11 | function getRoundData(uint80 _roundId) 12 | external 13 | view 14 | returns ( 15 | uint80 roundId, 16 | int256 answer, 17 | uint256 startedAt, 18 | uint256 updatedAt, 19 | uint80 answeredInRound 20 | ); 21 | 22 | function latestRoundData() 23 | external 24 | view 25 | returns ( 26 | uint80 roundId, 27 | int256 answer, 28 | uint256 startedAt, 29 | uint256 updatedAt, 30 | uint80 answeredInRound 31 | ); 32 | } -------------------------------------------------------------------------------- /6x3_ChainlinkApplication/ChainlinkApplication/interfaces/OwnableInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface OwnableInterface { 5 | function owner() external returns (address); 6 | 7 | function transferOwnership(address recipient) external; 8 | 9 | function acceptOwnership() external; 10 | } -------------------------------------------------------------------------------- /6x3_ChainlinkApplication/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde blockchain içerisinde var olmayan, dışarıdan almak istediğimiz verileri bizim kontratlarımıza iletmemizi sağlayan Chainlink projesini inceledik. Basit bir oyun üzerinden ETH/USD fiyatını ve random bir sayıyı Chainlink sayesinde kontratımıza entegre ettik. 4 | 5 |
6 | 7 | # Chainlink dokümantasyonları 8 | 9 | * [Chainlink Docs](https://chain.link/) 10 | * [Chainlink Github](https://github.com/smartcontractkit/chainlink) 11 | 12 | 13 |
14 | 15 | 16 | [Video İçeriği](https://www.youtube.com/watch?v=zf4orRramo4) 17 | 18 | [Proje Dizini](./ChainlinkApplication/) 19 | -------------------------------------------------------------------------------- /6x4_LayerZeroApplication/LayerZeroApplication/OmniCounter.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | pragma abicoder v2; 5 | 6 | import "./NonblockingLzApp.sol"; 7 | 8 | /// @title A LayerZero example sending a cross chain message from a source chain to a destination chain to increment a counter 9 | contract OmniCounter is NonblockingLzApp { 10 | uint256 public counter; 11 | 12 | constructor(address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {} 13 | 14 | function _nonblockingLzReceive( 15 | uint16, 16 | bytes memory, 17 | uint64, 18 | bytes memory 19 | ) internal override { 20 | counter += 1; 21 | } 22 | 23 | function incrementCounter(uint16 _dstChainId) public payable { 24 | _lzSend( 25 | _dstChainId, 26 | bytes(""), 27 | payable(msg.sender), 28 | address(0x0), 29 | bytes(""), 30 | msg.value 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /6x4_LayerZeroApplication/LayerZeroApplication/interfaces/ILayerZeroReceiver.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface ILayerZeroReceiver { 6 | // @notice LayerZero endpoint will invoke this function to deliver the message on the destination 7 | // @param _srcChainId - the source endpoint identifier 8 | // @param _srcAddress - the source sending contract address from the source chain 9 | // @param _nonce - the ordered message nonce 10 | // @param _payload - the signed payload is the UA bytes has encoded to be sent 11 | function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external; 12 | } 13 | -------------------------------------------------------------------------------- /6x4_LayerZeroApplication/LayerZeroApplication/interfaces/ILayerZeroUserApplicationConfig.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | interface ILayerZeroUserApplicationConfig { 6 | // @notice set the configuration of the LayerZero messaging library of the specified version 7 | // @param _version - messaging library version 8 | // @param _chainId - the chainId for the pending config change 9 | // @param _configType - type of configuration. every messaging library has its own convention. 10 | // @param _config - configuration in the bytes. can encode arbitrary content. 11 | function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external; 12 | 13 | // @notice set the send() LayerZero messaging library version to _version 14 | // @param _version - new messaging library version 15 | function setSendVersion(uint16 _version) external; 16 | 17 | // @notice set the lzReceive() LayerZero messaging library version to _version 18 | // @param _version - new messaging library version 19 | function setReceiveVersion(uint16 _version) external; 20 | 21 | // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload 22 | // @param _srcChainId - the chainId of the source chain 23 | // @param _srcAddress - the contract address of the source contract at the source chain 24 | function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external; 25 | } 26 | -------------------------------------------------------------------------------- /6x4_LayerZeroApplication/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu dersimizde blockchain ekosistemindeki büyük problemlerden bir tanesi olan blok zincirler arası iletişim sorununa çözüm üretmek amacıyla geliştirilmiş protocollerden bir tanesi olan LayerZero projesini inceledik. Öncelikle nasıl çalıştığına, ardından da LayerZero'yu nasıl kontratlarımıza entegre edebileceğimizi inceledik. 4 | 5 |
6 | 7 | # LayerZero dokümantasyonları 8 | 9 | * [LayerZero Docs](https://layerzero.gitbook.io/) 10 | * [LayerZero Github](https://github.com/LayerZero-Labs/solidity-examples) 11 | 12 | 13 |
14 | 15 | 16 | [Video İçeriği](https://www.youtube.com/watch?v=Ioxp875TmT8) 17 | 18 | [Proje Dizini](./LayerZeroApplication/) 19 | -------------------------------------------------------------------------------- /7x0_PatikaLendingWorkshop/Intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/7x0_PatikaLendingWorkshop/Intro.pdf -------------------------------------------------------------------------------- /7x0_PatikaLendingWorkshop/README.md: -------------------------------------------------------------------------------- 1 | # Smart Contract Developer Bootcamp - İTÜ Blockchain 2 | 3 | Bu etkinliğimizde [Patika](https://www.patika.dev/)'ya konuk olduk. Akıllı kontratlara giriş üzerine sohbet ettik ve bir P2P Lending - Borrowing kontrat örneği üzerinden anlatım yaptık. 4 | 5 | [Video İçeriği](https://www.youtube.com/watch?v=3GNgTvobj_g) 6 | 7 | [Lending Kontrat Örneği](./USD.sol) 8 | 9 | [ERC-20 Token Kontrat Örneği](./Lending.sol) 10 | 11 | [Giriş Slaytı](./Intro.pdf) 12 | 13 | * [Görsel Kaynak Makalesi I](https://www.preethikasireddy.com/post/how-does-ethereum-work-anyway) 14 | * [Görsel Kaynak Makalesi II](https://blog.ibby.dev/introduction-to-web3-development) -------------------------------------------------------------------------------- /7x0_PatikaLendingWorkshop/USD.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | import "@openzeppelin/contracts/access/Ownable.sol"; 6 | 7 | contract USDolar is ERC20, Ownable { 8 | constructor() ERC20("US Dolar", "USD") {} 9 | 10 | function mint(address to, uint256 amount) public onlyOwner { 11 | _mint(to, amount); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /itublockchain&ef.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/itublockchain&ef.png -------------------------------------------------------------------------------- /videoimgs/0x0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/0x0.png -------------------------------------------------------------------------------- /videoimgs/1x0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x0.png -------------------------------------------------------------------------------- /videoimgs/1x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x1.png -------------------------------------------------------------------------------- /videoimgs/1x10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x10.png -------------------------------------------------------------------------------- /videoimgs/1x11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x11.png -------------------------------------------------------------------------------- /videoimgs/1x12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x12.png -------------------------------------------------------------------------------- /videoimgs/1x13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x13.png -------------------------------------------------------------------------------- /videoimgs/1x14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x14.png -------------------------------------------------------------------------------- /videoimgs/1x15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x15.png -------------------------------------------------------------------------------- /videoimgs/1x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x16.png -------------------------------------------------------------------------------- /videoimgs/1x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x2.png -------------------------------------------------------------------------------- /videoimgs/1x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x3.png -------------------------------------------------------------------------------- /videoimgs/1x4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x4.png -------------------------------------------------------------------------------- /videoimgs/1x5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x5.png -------------------------------------------------------------------------------- /videoimgs/1x6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x6.png -------------------------------------------------------------------------------- /videoimgs/1x7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x7.png -------------------------------------------------------------------------------- /videoimgs/1x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x8.png -------------------------------------------------------------------------------- /videoimgs/1x9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/1x9.png -------------------------------------------------------------------------------- /videoimgs/2x0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x0.png -------------------------------------------------------------------------------- /videoimgs/2x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x1.png -------------------------------------------------------------------------------- /videoimgs/2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x2.png -------------------------------------------------------------------------------- /videoimgs/2x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x3.png -------------------------------------------------------------------------------- /videoimgs/2x4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x4.png -------------------------------------------------------------------------------- /videoimgs/2x5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x5.png -------------------------------------------------------------------------------- /videoimgs/2x6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x6.png -------------------------------------------------------------------------------- /videoimgs/2x7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x7.png -------------------------------------------------------------------------------- /videoimgs/2x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/2x8.png -------------------------------------------------------------------------------- /videoimgs/3x0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x0.png -------------------------------------------------------------------------------- /videoimgs/3x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x1.png -------------------------------------------------------------------------------- /videoimgs/3x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x2.png -------------------------------------------------------------------------------- /videoimgs/3x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x3.png -------------------------------------------------------------------------------- /videoimgs/3x4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x4.png -------------------------------------------------------------------------------- /videoimgs/3x5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x5.png -------------------------------------------------------------------------------- /videoimgs/3x6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x6.png -------------------------------------------------------------------------------- /videoimgs/3x7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x7.png -------------------------------------------------------------------------------- /videoimgs/3x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/3x8.png -------------------------------------------------------------------------------- /videoimgs/4x0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/4x0.png -------------------------------------------------------------------------------- /videoimgs/4x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/4x1.png -------------------------------------------------------------------------------- /videoimgs/4x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/4x2.png -------------------------------------------------------------------------------- /videoimgs/4x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/4x3.png -------------------------------------------------------------------------------- /videoimgs/4x4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/4x4.png -------------------------------------------------------------------------------- /videoimgs/4x5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/4x5.png -------------------------------------------------------------------------------- /videoimgs/5x0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x0.png -------------------------------------------------------------------------------- /videoimgs/5x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x1.png -------------------------------------------------------------------------------- /videoimgs/5x10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x10.png -------------------------------------------------------------------------------- /videoimgs/5x11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x11.png -------------------------------------------------------------------------------- /videoimgs/5x12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x12.png -------------------------------------------------------------------------------- /videoimgs/5x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x2.png -------------------------------------------------------------------------------- /videoimgs/5x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x3.png -------------------------------------------------------------------------------- /videoimgs/5x4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x4.png -------------------------------------------------------------------------------- /videoimgs/5x5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x5.png -------------------------------------------------------------------------------- /videoimgs/5x6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x6.png -------------------------------------------------------------------------------- /videoimgs/5x7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x7.png -------------------------------------------------------------------------------- /videoimgs/5x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x8.png -------------------------------------------------------------------------------- /videoimgs/5x9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/5x9.png -------------------------------------------------------------------------------- /videoimgs/6x0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/6x0.png -------------------------------------------------------------------------------- /videoimgs/6x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/6x1.png -------------------------------------------------------------------------------- /videoimgs/6x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/6x2.png -------------------------------------------------------------------------------- /videoimgs/6x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/6x3.png -------------------------------------------------------------------------------- /videoimgs/6x4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/6x4.png -------------------------------------------------------------------------------- /videoimgs/announce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/announce.png -------------------------------------------------------------------------------- /videoimgs/otopsi.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itublockchain/web3-bootcamp/dde05b4aa5af13065ed8952c19e85b455f836776/videoimgs/otopsi.jpeg --------------------------------------------------------------------------------