1.7 For迴圈, While迴圈 + 4小練習

閱讀時間約 9 分鐘
forLoop, WhileLoop

forLoop, WhileLoop

ForLoop

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ArtAuction {
mapping(uint => uint) public artworks;
uint public constant NUM_ARTWORKS = 5;

constructor() {
// 初始化畫作和價格
for (uint i = 0; i < NUM_ARTWORKS; i++) {
artworks[i] = (i + 1) * 100; // 價格為畫作編號乘以 100
}
}

function buyArtworks(uint[] memory _artworkIds) public payable {
require(_artworkIds.length > 0, "At least one artwork must be purchased");
uint totalCost = 0;
for (uint i = 0; i < _artworkIds.length; i++) {
uint artworkId = _artworkIds[i];
require(artworkId < NUM_ARTWORKS, "Invalid artwork ID");

totalCost += artworks[artworkId];
artworks[artworkId] = 0; // 購買後將畫作庫存設為 0
}
require(msg.value >= totalCost, "Insufficient funds");

// 購買成功,執行轉帳等操作
}
}

WhileLoop

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ArtAuction {
mapping(uint => uint) public artworks;
uint public constant NUM_ARTWORKS = 5;

constructor() {
// 初始化畫作和價格
uint i = 0;
while (i < NUM_ARTWORKS) {
artworks[i] = (i + 1) * 100; // 價格為畫作編號乘以 100
i++;
}
}

function buyArtworks(uint[] memory _artworkIds) public payable {
require(_artworkIds.length > 0, "At least one artwork must be purchased");
uint totalCost = 0;
uint i = 0;
while (i < _artworkIds.length) {
uint artworkId = _artworkIds[i];
require(artworkId < NUM_ARTWORKS, "Invalid artwork ID");

totalCost += artworks[artworkId];
artworks[artworkId] = 0; // 購買後將畫作庫存設為 0
i++;
}
require(msg.value >= totalCost, "Insufficient funds");

// 購買成功,執行轉帳等操作
}
}
  • 有一個智能合約 ArtAuction 用於小朋友的義賣活動。
  • 每幅畫作有一個價格,小朋友爸媽可以購買畫作,直到庫存用完為止。
  • 我們需要編寫一個函式,允許小朋友爸媽購買一個或多個畫作。
  • for 迴圈和 while 迴圈都用於初始化畫作和價格,以及在購買畫作時遍歷 _artworkIds 陣列。

[4小練習]

練習題 1 (這題沒有很懂, 暫時跳過)

    • 如何寫出一個可以跑十次迴圈的函數,每次將一輸入的整數 + 1,計算 uint a = 10 經過迴圈的計算結果。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

contract loop {
uint public a = 10;
function ForLoop() public {
for(uint i = 0; i < 10; i++) {
a++;
}
}
}


練習題 2

    • 如何寫出一個可以判斷奇數的函數?
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

contract oddNum {
function isOddNumber(uint _number) public view returns(bool) {
return (_number % 2 != 0 ? true : false);
}
}
raw-image

練習題 3 (不懂為什麼是 3000 * 10 * 18)

    • 小明賣水果,已知水果一斤 3 ether,如何寫出一個函式 sell() 每次執行可以賣出一斤水果以及一個函式 profit() 計算當前賺了多少 wei?
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

contract accountBalance {
uint amount = 0;
uint public Profit = 0;
function sell() public {
amount++;
}
function profit() public {
Profit = amount * 3000 * (10 **18);
}
}
  1. function sell() public { ... }: 此函式名為 sell,是一個公開(public)的函式,沒有參數。每次執行此函式,amount 變數的值會增加 1,代表賣出了一斤水果。
  2. function profit() public { ... }: 此函式名為 profit,是一個公開(public)的函式,沒有參數。當執行此函式時,會計算當前的利潤,利潤的計算方式是將 amount 變數乘以 3000(代表一斤水果的價格,以 wei 為單位)再乘以 10 的 18 次方(將結果轉換為 wei)。最後,將計算結果存儲在 Profit 變數中


練習題 4

    • 如何寫出一個函數可以讀取 Operation:add、sub,並且回傳 1+1 分別經過 +、- 兩種運算的結果。
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

contract String {
int public answer = 10;
function Operator(string memory operation) public {
if(keccak256(abi.encodePacked(operation)) == keccak256(abi.encodePacked("add"))){
answer = 1+1;
}
if(keccak256(abi.encodePacked(operation)) == keccak256(abi.encodePacked("sub"))){
answer = 1-1;
}
}
}
  • 函數參數string memory operation。這個參數是函數的輸入,用於指定要進行的數學運算。memory關鍵字表示這個參數是在內存中分配的,不會影響合約的永久存儲。
  • 運算判斷:使用keccak256(abi.encodePacked(operation))來對輸入的操作進行哈希處理,以確保無論操作是大寫還是小寫,都能正確識別。這裡使用了keccak256函數來生成哈希值,因為它是Solidity中可用的哈希函數之一。

[Reference]

  1. Solidity 教學: 流程控制 Selection and Repetition,  KryptoCamp - 智能合約教學與區塊鏈工程師課程
    尋大神腳印, 亦步亦趨。
    留言0
    查看全部
    發表第一個留言支持創作者!
    從 Google News 追蹤更多 vocus 的最新精選內容