1. solidity 簡介
Solidity(中文名稱:Solidity 語言)是一種面向智慧合約(Smart Contracts)的高階程式語言,最初由以太坊(Ethereum)的團隊開發並用於以太坊平臺上的智慧合約編寫。Solidity 的設計目標是簡化以太坊智慧合約的開發,使開發者能夠建立安全、可靠的去中心化應用程式(DApps)。
以下是 Solidity 的一些關鍵特點和重要概念:
- 靜態型別語言:Solidity 是一種靜態型別語言,這意味著在編譯時必須指定變數的資料型別。這有助於提高程式碼的安全性和可讀性。
- 以太坊智慧合約:Solidity 主要用於編寫以太坊智慧合約,這些合約是以太坊區塊鏈上的自執行程式碼。合約可以定義規則、儲存資料和執行操作。
- 物件導向:Solidity 支援物件導向程式設計(OOP)的概念,包括合約、繼承、結構體和列舉等。合約可以像類一樣包含狀態變數和函式,可以被例項化和繼承。
- 智慧合約開發:使用 Solidity,開發者可以建立自定義的智慧合約,這些合約可以處理數字貨幣(以太幣)的交易、管理數字資產、實現投票系統、構建去中心化應用等。
- 安全性:Solidity 強調智慧合約的安全性,但也容易引入漏洞,如重入攻擊、整數溢位和邏輯錯誤。因此,開發者需要小心編寫合約,並經常進行審查和測試。
- 事件驅動:Solidity 支援事件,可以在合約狀態發生變化時觸發事件,允許 DApps 監聽和響應合約的活動。
- Gas 費用:在以太坊上執行智慧合約需要支付 Gas 費用,Solidity 允許開發者最佳化合約以降低執行成本。
- 整合開發環境(IDE):開發者可以使用 Solidity 整合開發環境,如 Remix 和 Truffle,來編寫、測試和部署智慧合約。
- ERC-20 和 ERC-721 標準:Solidity 用於實現 Ethereum 的 ERC-20 和 ERC-721 標準,這些標準定義了代幣和非同質代幣(NFT)合約的介面規範。
- 社群支援:Solidity 擁有廣泛的社群支援和文件資源,方便開發者學習和解決問題。
2. solidity 常用資料型別
Solidity 是一種用於編寫智慧合約的程式語言,它具有多種資料型別,用於定義合約中的變數和資料。以下是 Solidity 中常見的資料型別:
- 整數型別(Integer Types):
uint
:無符號整數型別,可以儲存正整數。int
:有符號整數型別,可以儲存正整數和負整數。- 可以指定位數,例如
uint8
表示一個8位的無符號整數。
- 地址型別(Address Types):
address
:用於儲存以太坊地址的資料型別,通常用於儲存使用者地址或合約地址。address payable
:與address
類似,但還可以接收以太幣(ether)的轉賬。
- 布林型別(Boolean Type):
bool
:用於儲存布林值,即true
或false
。
- 固定大小位元組陣列(Fixed-size Byte Arrays):
bytes1
,bytes2
, ...,bytes32
:用於儲存固定大小的位元組陣列,可以儲存原始位元組資料。
- 動態大小位元組陣列(Dynamic-size Byte Arrays):
bytes
:用於儲存動態大小的位元組陣列,可以儲存變長位元組資料。
- 字串型別(String Type):
string
:用於儲存文字字串,支援 UTF-8 編碼的字串。
- 陣列型別(Array Types):
type[]
:用於儲存具有相同資料型別的元素的陣列,可以是固定大小或動態大小的。- 例如,
uint[]
表示一個儲存無符號整數的陣列。
- 對映型別(Mapping Types):
mapping(keyType => valueType)
:用於建立鍵-值對映,類似於雜湊表。- 對映中的
keyType
必須是可雜湊的型別,而valueType
可以是任何型別。
- 結構體型別(Struct Types):
struct
:用於自定義資料結構,可以包含多個欄位,每個欄位可以有不同的資料型別。
- 列舉型別(Enum Types):
enum
:用於定義一組有限的命名常量。每個列舉值都可以與一個整數值相關聯。
- 函式型別(Function Types):
function
:用於儲存函式的引用,通常用於回撥函式或將函式作為引數傳遞。
- 不可變引用型別(Immutable References):
view
和pure
:用於標記函式,表示它們不會修改狀態,並且可以安全地讀取資料。
這些資料型別允許 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
的合約。這個合約包括以下要點:
- 使用
pragma solidity
指令指定 Solidity 的版本。 - 宣告瞭一個名為
storedData
的狀態變數,用於儲存整數值。這個變數是私有的,只能在合約內部訪問。 - 定義了一個
ValueChanged
事件,用於記錄狀態變數的變化。 - 在建構函式中,將
storedData
初始化為 0。 - 實現了一個
set
函式,允許合約的擁有者設定整數值,並觸發ValueChanged
事件。 - 實現了一個
get
函式,允許任何人檢視儲存的整數值。
要使用這個合約,你需要執行以下步驟:
- 部署合約:使用以太坊錢包或 Solidity 開發工具,將這個合約部署到以太坊網路上。
- 設定值:使用合約的擁有者地址呼叫
set
函式,設定儲存的整數值。 - 獲取值:任何人都可以使用
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;
}
}
這個合約包括以下主要部分:
- 候選人結構體
Candidate
:包括候選人的ID、姓名和得票數。 - 候選人列表
candidates
:用於儲存候選人的陣列。 - 投票者記錄
voters
:用於記錄哪些地址已經投票,防止重複投票。 addCandidate
函式:允許任何地址新增候選人。vote
函式:允許任何地址投票給特定的候選人。getVotes
函式:允許查詢特定候選人的得票數。
合約的呼叫者可以透過呼叫函式來新增候選人、投票和查詢候選人的得票數。這只是一個非常簡單的示例,用於演示 Solidity 合約的基本構建塊。在實際應用中,你可以根據需求擴充套件和最佳化合約。確保在以太坊測試網路上進行測試和部署合約,以確保其正常執行。
5. 使用 Remix 進行除錯
Remix IDE 是一個基於 Web 的區塊鏈智慧合約開發環境,它提供了許多有用的功能,包括智慧提示(程式碼補全)功能,以幫助開發者更高效地編寫 Solidity 智慧合約。智慧提示可以在你輸入程式碼時,自動顯示可能的選項,從而加速程式碼編寫和減少錯誤。
以下是如何在 Remix IDE 中除錯智慧合約的步驟:
- 開啟 Remix IDE:
訪問 Remix IDE 的網站:https://remix.ethereum.org/ - 建立或開啟合約:
在 Remix IDE 中,你可以建立新的合約或開啟已有的合約檔案。選擇左側選單欄中的 "File Explorer",然後點選 "Open" 按鈕,選擇你的 Solidity 合約檔案,或者點選 "Create" 建立一個新的合約檔案。 - 選擇 Solidity 版本:
在左上角的選擇框中,選擇你要使用的 Solidity 版本。選擇一個你熟悉的版本,通常會是最新的版本。 - 編寫程式碼:
在程式碼編輯區域中,開始編寫 Solidity 智慧合約。當你輸入程式碼的時候,智慧提示會自動彈出。 - 儲存合約:
在完成程式碼編寫後,記得點選左上角的儲存按鈕,將合約儲存到 Remix IDE 的本地儲存中。 - 執行合約:
一旦合約編寫完成,你可以使用 Remix IDE 提供的 "Deploy & run transactions" 功能來部署和測試你的合約。
宣告:本作品採用署名-非商業性使用-相同方式共享 4.0 國際 (CC BY-NC-SA 4.0)進行許可,使用時請註明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無意