---
# System prepended metadata

title: 模擬考試題 - JoeHo

---

# 模擬考試題 - 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)
