# 模擬考試題 - JoeHo **及格線:6題/10題** ## [](https://hackmd.io/@intheblack/By_Bmg7qq#Solidity-%E5%9F%BA%E7%A4%8E "Solidity-基礎")Solidity 基礎 **1. 列舉五種 Solidity 的型別並且寫出實際例子** - Integer: - `uint8 public test = 168;` - Boolean: - `bool private isDone = true;` - String: - `string public testString = "test";` - Address: - `address addr1 = msg.sender;` - `address public myAddress = address(0xB42faBF7BCAE8bc5E368716B568a6f8Fdf3F84ec);` - bytes: - `bytes32 private test="test";` **2. 寫出一 function 可接受 eth value 並且 return 自定義結果** ``` function getEth(uint256 memory value) public pure returns (String memory){ return "I got money!"; } ``` **3. ERC20 合約部屬至 rinkeby,寫上部屬的合約地址** - contract: - https://rinkeby.etherscan.io/address/0xe6b4b6002d4f5d9e865751d9fdc2ea1c797ecb39 - transaction: - https://rinkeby.etherscan.io/tx/0xfd62d20ceecadd26c69d23e5f342616e3c197709b4453f2c77e0442830f792c0 - contract code: ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract MyToken is ERC20, Ownable { constructor() ERC20("MyToken", "MTK") {} function mint(address to, uint256 amount) public onlyOwner { _mint(to, amount); } } ``` ## [Solidity 進階](https://hackmd.io/@intheblack/By_Bmg7qq#Solidity-%E9%80%B2%E9%9A%8E "Solidity-進階") **1. 以文字描述為智能合約增加流動性的流程** - 加入 staking - ex. 如何在 pancake 為代幣/contract 添加流動性 **2. 實作 ERC20 質押某代幣,timelock(固定鎖倉期,自定義), reward (回饋該代幣)** - reference - https://hackmd.io/aaWn-YrtQsuXKTBEsjcOaw?view - explain - 需要 reward 原質押代幣 - 質押 USDT 要能夠 reward USDT - 用 week3 homework 的 basic 加上 reward 原代幣 ## [Solidity 整合開發相關](https://hackmd.io/@intheblack/By_Bmg7qq#Solidity-%E6%95%B4%E5%90%88%E9%96%8B%E7%99%BC%E7%9B%B8%E9%97%9C "Solidity-整合開發相關") **1. 試說明如何整合 VSCode, 以及 Remix 的開發環境** - 在 remix 上有 connect localhost - 使用 vs code extension - https://github.com/ethereum/remix-vscode - https://medium.com/remix-ide/a-remix-ide-extension-for-vscode-1f751fdeee46 - Ethereum Remix - https://marketplace.visualstudio.com/items?itemName=RemixProject.ethereum-remix **2. 試寫出 contract auto verify 的 相關內容(npm install xxx, hardhat.config.js, npm hardhat xxx)** - reference - https://moralis.io/how-to-verify-a-smart-contract-with-hardhat/ - https://www.youtube.com/watch?v=h05-TkWPCvA - https://morioh.com/p/e395b47eb0b6 - ... - https://docs.avax.network/dapps/smart-contracts/verify-smart-contract-using-hardhat-and-snowtrace - https://docs.etherscan.io/tutorials/verifying-contracts-programmatically - Verifying Contracts Programmatically - https://ethereum.stackexchange.com/questions/126815/automatic-verification-of-smart-contracts-deployed-from-another-smart-contract - Automatic verification of Smart Contracts deployed from another Smart Contract - - Ans: - ... ```solidity npm install hardhat npm install @openzeppelin/contracts // create ERC20 contract npx hardhat compile // create hardhat deployment script // verify smart contract npm install @openzeppelin/hardhat-etherscan // OR // npm install --save-dev @nomiclabs/hardhat-etherscan // require("@nomiclabs/hardhat-etherscan"); npx hardhat run scripts/deploy.js --network ropsten npx hardhat verify "ADDRESS" --network ropsten ``` ``` // hardhat.config.js require("@nomiclabs/hardhat-etherscan"); module.exports = { networks: { mainnet: { ... } }, etherscan: { // Your API key for Etherscan // Obtain one at https://etherscan.io/ apiKey: "YOUR_ETHERSCAN_API_KEY" } }; ``` **3. 試寫出部屬 ERC721 合約並且先 mint 10 個 NFT 的 hardhat.js script** ``` ##  hardhat.config.js /** * @type import(‘hardhat/config’).HardhatUserConfig */ require(“dotenv”).config(); require(“@nomiclabs/hardhat-ethers”); const { API_URL, PRIVATE_KEY } = process.env; module.exports = { solidity: “0.8.9”, defaultNetwork: “mumbai”, networks: { hardhat: {}, mumbai: { url: API_URL, accounts: [`0x${PRIVATE_KEY}`], }, }, ``` - reference - https://coinsbench.com/erc-721-nft-smart-contract-deployment-using-hardhat-97c74ce1362a ## [Solidity 資安相關](https://hackmd.io/@intheblack/By_Bmg7qq#Solidity-%E8%B3%87%E5%AE%89%E7%9B%B8%E9%97%9C "Solidity-資安相關") **標註程式碼第幾行可能有資安問題,並說明何種資安問題,並提出解法** ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; contract DepositContract { using SafeMath for uint256; mapping(address => uint256) public balance; function deposit() external payable { balance[msg.sender] += msg.value; } function withdraw(uint256 amount) external { require(balance[msg.sender] >= amount, "Account balance is not enough"); balance[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed."); } function withdrawAll() external { (bool success, ) = msg.sender.call{value: balance[msg.sender]}(""); require(success, "Transfer failed."); balance[msg.sender] = 0; } } ``` - Ans - - ... - reference - https://solidity-by-example.org/hacks/re-entrancy - 攻擊者可設置攻擊合約, - withdraw() 此函式裡的 `(bool sent, ) = msg.sender.call{value: bal}("");` 由於未設置 - https://ethereum.stackexchange.com/questions/118859/what-is-returned-from-msg-sender-callvalue-amount - The low level Solidity method call performs a call to a contract and returns if this call was successful and the data it returns. - https://ethereum.stackexchange.com/questions/42521/what-does-msg-sender-call-do-in-solidity - msg.sender.call() calls the fallback-function on msg.sender. - ## [Solidity 節省 Gasfee 相關](https://hackmd.io/@intheblack/By_Bmg7qq#Solidity-%E7%AF%80%E7%9C%81-Gasfee-%E7%9B%B8%E9%97%9C "Solidity-節省-Gasfee-相關") **嘗試閱讀以下程式碼,如何寫出更節省Gas fee 的方法** ```solidity ... ... address[] whitelistedAddresses; function isWhitelisted(address _user) public view returns (bool) { for (uint i = 0; i < whitelistedAddresses.length; i++) { if (whitelistedAddresses[i] == _user) { return true; } } return false; } ``` - Ans: - use mapping, avoid for loop - **完整程式碼** [https://etherscan.io/address/0xae122962331c2b02f837b2aa501d3c5d903ed28a#code](https://etherscan.io/address/0xae122962331c2b02f837b2aa501d3c5d903ed28a#code)