solidity入門

2023-10-11 12:01:19

1. solidity 簡介

Solidity(中文名稱:Solidity 語言)是一種面向智慧合約(Smart Contracts)的高階程式語言,最初由以太坊(Ethereum)的團隊開發並用於以太坊平臺上的智慧合約編寫。Solidity 的設計目標是簡化以太坊智慧合約的開發,使開發者能夠建立安全、可靠的去中心化應用程式(DApps)。

以下是 Solidity 的一些關鍵特點和重要概念:

  1. 靜態型別語言:Solidity 是一種靜態型別語言,這意味著在編譯時必須指定變數的資料型別。這有助於提高程式碼的安全性和可讀性。
  2. 以太坊智慧合約:Solidity 主要用於編寫以太坊智慧合約,這些合約是以太坊區塊鏈上的自執行程式碼。合約可以定義規則、儲存資料和執行操作。
  3. 物件導向:Solidity 支援物件導向程式設計(OOP)的概念,包括合約、繼承、結構體和列舉等。合約可以像類一樣包含狀態變數和函數,可以被範例化和繼承。
  4. 智慧合約開發:使用 Solidity,開發者可以建立自定義的智慧合約,這些合約可以處理數位貨幣(以太幣)的交易、管理數位資產、實現投票系統、構建去中心化應用等。
  5. 安全性:Solidity 強調智慧合約的安全性,但也容易引入漏洞,如重入攻擊、整數溢位和邏輯錯誤。因此,開發者需要小心編寫合約,並經常進行審查和測試。
  6. 事件驅動:Solidity 支援事件,可以在合約狀態發生變化時觸發事件,允許 DApps 監聽和響應合約的活動。
  7. Gas 費用:在以太坊上執行智慧合約需要支付 Gas 費用,Solidity 允許開發者優化合約以降低執行成本。
  8. 整合式開發環境(IDE):開發者可以使用 Solidity 整合式開發環境,如 Remix 和 Truffle,來編寫、測試和部署智慧合約。
  9. ERC-20 和 ERC-721 標準:Solidity 用於實現 Ethereum 的 ERC-20 和 ERC-721 標準,這些標準定義了代幣和非同質代幣(NFT)合約的介面規範。
  10. 社群支援:Solidity 擁有廣泛的社群支援和檔案資源,方便開發者學習和解決問題。

2. solidity 常用資料型別

Solidity 是一種用於編寫智慧合約的程式語言,它具有多種資料型別,用於定義合約中的變數和資料。以下是 Solidity 中常見的資料型別:

  1. 整數型別(Integer Types):
    • uint:無符號整數型別,可以儲存正整數。
    • int:有符號整數型別,可以儲存正整數和負整數。
    • 可以指定位數,例如 uint8 表示一個8位元的無符號整數。
  2. 地址型別(Address Types):
    • address:用於儲存以太坊地址的資料型別,通常用於儲存使用者地址或合約地址。
    • address payable:與 address 類似,但還可以接收以太幣(ether)的轉賬。
  3. 布林型別(Boolean Type):
    • bool:用於儲存布林值,即 truefalse
  4. 固定大小位元組陣列(Fixed-size Byte Arrays):
    • bytes1, bytes2, ..., bytes32:用於儲存固定大小的位元組陣列,可以儲存原始位元組資料。
  5. 動態大小位元組陣列(Dynamic-size Byte Arrays):
    • bytes:用於儲存動態大小的位元組陣列,可以儲存變長位元組資料。
  6. 字串型別(String Type):
    • string:用於儲存文字字串,支援 UTF-8 編碼的字串。
  7. 陣列型別(Array Types):
    • type[]:用於儲存具有相同資料型別的元素的陣列,可以是固定大小或動態大小的。
    • 例如,uint[] 表示一個儲存無符號整數的陣列。
  8. 對映型別(Mapping Types):
    • mapping(keyType => valueType):用於建立鍵-值對映,類似於雜湊表。
    • 對映中的 keyType 必須是可雜湊的型別,而 valueType 可以是任何型別。
  9. 結構體型別(Struct Types):
    • struct:用於自定義資料結構,可以包含多個欄位,每個欄位可以有不同的資料型別。
  10. 列舉型別(Enum Types):
    • enum:用於定義一組有限的命名常數。每個列舉值都可以與一個整數值相關聯。
  11. 函數型別(Function Types):
    • function:用於儲存函數的參照,通常用於回撥函數或將函數作為引數傳遞。
  12. 不可變參照型別(Immutable References):
    • viewpure:用於標記函數,表示它們不會修改狀態,並且可以安全地讀取資料。

這些資料型別允許 Solidity 開發者定義合約中的變數、函數引數和返回值。合約中的資料型別選擇取決於合約的需求和邏輯。 Solidity 還支援使用者自定義的複雜資料型別,如結構體和列舉,以便更好地組織資料。合理選擇和使用資料型別是 Solidity 智慧合約開發中的關鍵部分。

3. 入門合約1

下面是一個簡單的 Solidity 合約範例,它實現了一個簡單的數位儲存合約,允許使用者設定和獲取一個整數值。這個合約將幫助你瞭解 Solidity 合約的基本結構和語法。

// 指定 Solidity 的版本
pragma solidity ^0.8.0;

// 定義一個合約
contract SimpleStorage {
    // 宣告一個狀態變數,用於儲存整數值
    uint256 private storedData;

    // 定義一個事件,用於記錄狀態變數的變化
    event ValueChanged(uint256 newValue);

    // 合約建構函式,在部署合約時執行一次,用於初始化狀態變數
    constructor() {
        storedData = 0;
    }

    // 設定整數值的函數,只有合約的擁有者可以呼叫
    function set(uint256 newValue) public {
        storedData = newValue;
        emit ValueChanged(newValue);
    }

    // 獲取整數值的函數,可以被任何人呼叫
    function get() public view returns (uint256) {
        return storedData;
    }
}

在這個範例中,我們建立了一個名為 SimpleStorage 的合約。這個合約包括以下要點:

  1. 使用 pragma solidity 指令指定 Solidity 的版本。
  2. 宣告了一個名為 storedData 的狀態變數,用於儲存整數值。這個變數是私有的,只能在合約內部存取。
  3. 定義了一個 ValueChanged 事件,用於記錄狀態變數的變化。
  4. 在建構函式中,將 storedData 初始化為 0。
  5. 實現了一個 set 函數,允許合約的擁有者設定整數值,並觸發 ValueChanged 事件。
  6. 實現了一個 get 函數,允許任何人檢視儲存的整數值。

要使用這個合約,你需要執行以下步驟:

  1. 部署合約:使用以太坊錢包或 Solidity 開發工具,將這個合約部署到以太坊網路上。
  2. 設定值:使用合約的擁有者地址呼叫 set 函數,設定儲存的整數值。
  3. 獲取值:任何人都可以使用 get 函數檢視儲存的整數值。

這只是一個非常簡單的範例,但它涵蓋了 Solidity 合約的基本結構,包括狀態變數、建構函式、函數、事件等。你可以根據需要擴充套件這個範例,建立更復雜的智慧合約。注意,智慧合約的開發需要謹慎,特別是在處理資金和重要資料時,請務必小心編寫和測試程式碼。

4. 入門合約2

下面的合約實現了一個簡單的數位投票系統。合約允許使用者為不同的候選人投票,並且可以查詢每個候選人的得票數。

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

// 宣告一個智慧合約
contract SimpleVoting {
    // 宣告候選人結構體
    struct Candidate {
        uint256 id;
        string name;
        uint256 voteCount;
    }

    // 使用陣列儲存候選人列表
    Candidate[] public candidates;

    // 用於儲存每個地址的投票記錄
    mapping(address => bool) public voters;

    // 新增候選人
    function addCandidate(string memory _name) public {
        // 檢查呼叫者是否已投票
        require(!voters[msg.sender], "You can only add one candidate.");

        uint256 candidateId = candidates.length;
        candidates.push(Candidate(candidateId, _name, 0));
        voters[msg.sender] = true;
    }

    // 進行投票
    function vote(uint256 _candidateId) public {
        // 檢查呼叫者是否已投票
        require(!voters[msg.sender], "You can only vote once.");

        // 檢查候選人是否存在
        require(_candidateId < candidates.length, "Candidate does not exist.");

        // 增加候選人的得票數
        candidates[_candidateId].voteCount++;

        // 標記呼叫者已投票
        voters[msg.sender] = true;
    }

    // 查詢候選人的得票數
    function getVotes(uint256 _candidateId) public view returns (uint256) {
        require(_candidateId < candidates.length, "Candidate does not exist.");
        return candidates[_candidateId].voteCount;
    }
}

這個合約包括以下主要部分:

  1. 候選人結構體 Candidate:包括候選人的ID、姓名和得票數。
  2. 候選人列表 candidates:用於儲存候選人的陣列。
  3. 投票者記錄 voters:用於記錄哪些地址已經投票,防止重複投票。
  4. addCandidate 函數:允許任何地址新增候選人。
  5. vote 函數:允許任何地址投票給特定的候選人。
  6. getVotes 函數:允許查詢特定候選人的得票數。

合約的呼叫者可以通過呼叫函數來新增候選人、投票和查詢候選人的得票數。這只是一個非常簡單的範例,用於演示 Solidity 合約的基本構建塊。在實際應用中,你可以根據需求擴充套件和優化合約。確保在以太坊測試網路上進行測試和部署合約,以確保其正常執行。

5. 使用 Remix 進行偵錯

Remix IDE 是一個基於 Web 的區塊鏈智慧合約開發環境,它提供了許多有用的功能,包括智慧提示(程式碼補全)功能,以幫助開發者更高效地編寫 Solidity 智慧合約。智慧提示可以在你輸入程式碼時,自動顯示可能的選項,從而加速程式碼編寫和減少錯誤。

以下是如何在 Remix IDE 中偵錯智慧合約的步驟:

  1. 開啟 Remix IDE
    存取 Remix IDE 的網站:https://remix.ethereum.org/
  2. 建立或開啟合約
    在 Remix IDE 中,你可以建立新的合約或開啟已有的合約檔案。選擇左側選單欄中的 "File Explorer",然後點選 "Open" 按鈕,選擇你的 Solidity 合約檔案,或者點選 "Create" 建立一個新的合約檔案。
  3. 選擇 Solidity 版本
    在左上角的選擇框中,選擇你要使用的 Solidity 版本。選擇一個你熟悉的版本,通常會是最新的版本。
  4. 編寫程式碼
    在程式碼編輯區域中,開始編寫 Solidity 智慧合約。當你輸入程式碼的時候,智慧提示會自動彈出。
  5. 儲存合約
    在完成程式碼編寫後,記得點選左上角的儲存按鈕,將合約儲存到 Remix IDE 的本地儲存中。
  6. 執行合約
    一旦合約編寫完成,你可以使用 Remix IDE 提供的 "Deploy & run transactions" 功能來部署和測試你的合約。

孟斯特

宣告:本作品採用署名-非商業性使用-相同方式共用 4.0 國際 (CC BY-NC-SA 4.0)進行許可,使用時請註明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無意