在 Solidity 語言中,合約類似於其他面向物件程式設計語言中的類
每個合約中可以包含 狀態變數、 函數、 函數 、事件 Event、 結構體、 和 枚舉類型 的聲明,且合約可以從其他合約繼承。還有一些特殊的合約,例如如庫和介面.
本節用於幫助我們了解合約包含哪些內容,做一個簡單的入門,不會有細節的解釋與範例
Section3. 類型 和 Section6. 合約 章節會比本節包含更多的說明
狀態變數是永久地存儲在合約中的值
在 Azuki.sol 中使用:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Azuki is Ownable, ERC721A, ReentrancyGuard {
uint256 public immutable maxPerAddressDuringMint;
uint256 public immutable amountForDevs;
uint256 public immutable amountForAuctionAndDev;
mapping(address => uint256) public allowlist;
//...
uint256 public constant AUCTION_START_PRICE = 1 ether;
uint256 public constant AUCTION_END_PRICE = 0.15 ether;
uint256 public constant AUCTION_PRICE_CURVE_LENGTH = 340 minutes;
uint256 public constant AUCTION_DROP_INTERVAL = 20 minutes;
uint256 public constant AUCTION_DROP_PER_STEP =
(AUCTION_START_PRICE - AUCTION_END_PRICE) /
(AUCTION_PRICE_CURVE_LENGTH / AUCTION_DROP_INTERVAL);
//...
string private _baseTokenURI;
}
這些變數宣告便是該合約中所有的狀態變數,下一章節會解釋各種狀態變數如何使用
函數是代碼的可執行單元, 函數通常在合約內部定義,但也可以在合約外定義,在 Azuki.sol 中我們可以看到所有函數都被包在 Contract Azuki 裡面
在 Azuki.sol 中使用到的函數類型包含:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Azuki is Ownable, ERC721A, ReentrancyGuard {
function publicSaleMint(uint256 quantity, uint256 callerPublicSaleKey) {
//...
}
function auctionMint(uint256 quantity) external payable callerIsUser {
//...
}
function isPublicSaleOn(
uint256 publicPriceWei,
uint256 publicSaleKey,
uint256 publicSaleStartTime
) public view returns (bool) {
//...
}
function getOwnershipData(uint256 tokenId)
external
view
returns (TokenOwnership memory){
//...
}
function endAuctionAndSetupNonAuctionSaleInfo(
uint64 mintlistPriceWei,
uint64 publicPriceWei,
uint32 publicSaleStartTime
) external onlyOwner {
//...
}
function _baseURI() internal view virtual override returns (string memory) {
//...
}
function withdrawMoney() external onlyOwner nonReentrant {
//...
}
}
只看函數宣告的話,我們並不能了解這個函數的確切用法,但卻可以了解這個函數:
能夠在哪使用 - 我們可以函數宣告中有些函數帶有
external,public,internal這表示這個函數的可見性,其中private也是一種方式,不過這邊沒有使用到需要提供什麼類型參數 -
()內所有的參數,可以看到其聲明方法與第一部分狀態變數雷同,以第一個函數publicSaleMint為例,他需要 caller 提供quantity和callerPublicSaleKey的值,且其類型必須是uint256會回傳什麼類型的資料 -
returns()內的參數,以isPublicSaleOn為例,這個函數會回傳bool也就是 True 或 False
函數修改器可以用來以聲明的方式修改函數語義, Azuki.sol 中使用:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Azuki is Ownable, ERC721A, ReentrancyGuard {
//...
modifier callerIsUser() {
require(tx.origin == msg.sender, "The caller is another contract");
_;
}
//...
}
以上述函數部分 auctionMint 為例,後面 callerIsUser 就是修改器用法
事件是能方便地調用乙太坊虛擬機日誌功能的介面, Azuki.sol 中沒有使用到事件,不過這邊還是簡單說明一下用法
pragma solidity >=0.4.21 <0.9.0;
contract TinyAuction {
event HighestBidIncreased(address bidder, uint amount); // 事件
function bid() public payable {
// ...
emit HighestBidIncreased(msg.sender, msg.value); // 觸發事件
}
}
結構體是可以將幾個變數分組的自定義類型, Azuki.sol 中使用:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Azuki is Ownable, ERC721A, ReentrancyGuard {
//...
struct SaleConfig {
uint32 auctionSaleStartTime;
uint32 publicSaleStartTime;
uint64 mintlistPrice;
uint64 publicPrice;
uint32 publicSaleKey;
}
//...
}
枚舉可用來創建由一定數量的「常量值」構成的自定義類型, Azuki.sol 中沒有使用到事件,不過這邊還是簡單說明一下用法
pragma solidity >=0.4.0 <0.9.0;
contract Upchain {
enum State { Created, Locked, InValid } // 枚举
}
