W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
以下合約實現(xiàn)了最簡單的加密貨幣形式。該合約僅允許其創(chuàng)建者創(chuàng)建新硬幣(可能有不同的發(fā)行方案)。任何人都可以互相發(fā)送硬幣,而無需使用用戶名和密碼進行注冊,您所需要的只是一個以太坊密鑰對。
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
contract Coin {
// The keyword "public" makes variables
// accessible from other contracts
address public minter;
mapping (address => uint) public balances;
// Events allow clients to react to specific
// contract changes you declare
event Sent(address from, address to, uint amount);
// Constructor code is only run when the contract
// is created
constructor() {
minter = msg.sender;
}
// Sends an amount of newly created coins to an address
// Can only be called by the contract creator
function mint(address receiver, uint amount) public {
require(msg.sender == minter);
balances[receiver] += amount;
}
// Errors allow you to provide information about
// why an operation failed. They are returned
// to the caller of the function.
error InsufficientBalance(uint requested, uint available);
// Sends an amount of existing coins
// from any caller to an address
function send(address receiver, uint amount) public {
if (amount > balances[msg.sender])
revert InsufficientBalance({
requested: amount,
available: balances[msg.sender]
});
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}
這份合約引入了一些新概念,讓我們一一來介紹。
該行?address public minter;
?聲明了一個地址類型的狀態(tài)變量。該?address
?類型是一個 160 位的值,不允許任何算術運算。它適用于存儲合約的地址,或屬于外部賬戶的密鑰對的公共一半的哈希。
關鍵字?public
?自動生成一個函數(shù),允許您從合約外部訪問狀態(tài)變量的當前值。如果沒有這個關鍵字,其他合約就無法訪問該變量。編譯器生成的函數(shù)代碼等價于以下(暫時忽略?external
?和?view
?):
function minter() external view returns (address) { return minter; }
你可以自己添加一個像上面這樣的函數(shù),但是你會有一個同名的函數(shù)和狀態(tài)變量。您不需要這樣做,編譯器會為您計算出來。
下一行?mapping (address => uint) public balances;
?也創(chuàng)建了一個公共狀態(tài)變量,但它是一個更復雜的數(shù)據(jù)類型。映射類型將地址映射到無符號整數(shù)。
映射可以看作是虛擬初始化的哈希表,這樣每個可能的鍵從一開始就存在,并映射到一個字節(jié)表示全為零的值。但是,既不可能獲得映射的所有鍵的列表,也不可能獲得所有值的列表。記錄您添加到映射中的內(nèi)容,或在不需要的上下文中使用它。或者更好的是,保留一個列表,或者使用更合適的數(shù)據(jù)類型。
在映射的情況下,由關鍵字?public
?創(chuàng)建的getter 函數(shù)更復雜。它如下所示:
function balances(address account) external view returns (uint) {
return balances[account];
}
您可以使用該功能查詢單個賬戶的余額。
該行?event Sent(address from, address to, uint amount);
?聲明了一個“事件”,它在函數(shù)?send
?的最后一行觸發(fā) 。以太坊客戶端(例如 Web 應用程序)可以在無需太多成本的情況下偵聽在區(qū)塊鏈上發(fā)出的這些事件。一旦它發(fā)出,偵聽器就會收到from
, to
和 amount
?參數(shù),這使得跟蹤事務成為可能。
要監(jiān)聽此事件,您可以使用以下 JavaScript 代碼,該代碼使用web3.js創(chuàng)建Coin合約對象,并且任何用戶界面都會調(diào)用?balances
?上面自動生成的函數(shù):
Coin.Sent().watch({}, '', function(error, result) {
if (!error) {
console.log("Coin transfer: " + result.args.amount +
" coins were sent from " + result.args.from +
" to " + result.args.to + ".");
console.log("Balances now:\n" +
"Sender: " + Coin.balances.call(result.args.from) +
"Receiver: " + Coin.balances.call(result.args.to));
}
})
構造函數(shù)是一個特殊的函數(shù),在合約創(chuàng)建過程中執(zhí)行,之后不能調(diào)用。在這種情況下,它會永久存儲創(chuàng)建合約的人的地址。?msg
?變量(連同?tx
?和?block
?)是一個 特殊的全局變量,包含允許訪問區(qū)塊鏈的屬性。?msg.sender
?始終是當前(外部)函數(shù)調(diào)用的來源地址。
構成合約以及用戶和合約可以調(diào)用的函數(shù)是?mint
?和?send
?。
該mint函數(shù)將一定數(shù)量的新創(chuàng)建的硬幣發(fā)送到另一個地址。require函數(shù)調(diào)用定義了在未滿足時還原所有更改的條件。在這個例子中,?require(msg.sender == minter);
?確保只有合約的創(chuàng)建者可以調(diào)用?mint
?. 一般來說,創(chuàng)建者可以鑄造任意數(shù)量的代幣,但在某些時候,這會導致一種稱為“溢出”的現(xiàn)象。請注意,由于默認的Checked 算法,如果表達式 ?balances[receiver] += amount;
?溢出,即任意精度算術中的?balances[receiver] + amount
?大于uint
(2**256 - 1
)的最大值時,事務將恢復。函數(shù)send中的語句?balances[receiver] += amount;
?也是如此。
錯誤允許您向調(diào)用者提供有關條件或操作失敗原因的更多信息。錯誤與revert 語句一起使用 。?revert
?語句無條件中止并恢復與?require
?函數(shù)類似的所有更改,但它還允許您提供錯誤的名稱和將提供給調(diào)用者(并最終提供給前端應用程序或塊資源管理器)的附加數(shù)據(jù),以便故障可以更容易地被調(diào)試或響應。
任何人(已經(jīng)擁有其中一些硬幣)都可以使用?send
?功能將硬幣發(fā)送給其他任何人。如果發(fā)件人沒有足夠的硬幣發(fā)送,則if條件評估為真。因此,?revert
?操作將導致操作失敗,同時使用?InsufficientBalance
?錯誤向發(fā)送者提供?錯誤詳細信息。
筆記
如果您使用此合約將硬幣發(fā)送到某個地址,當您在區(qū)塊鏈瀏覽器上查看該地址時,您將看不到任何內(nèi)容,因為您發(fā)送硬幣的記錄和更改的余額僅存儲在該特定硬幣的數(shù)據(jù)存儲中合同。通過使用事件,您可以創(chuàng)建一個“區(qū)塊鏈瀏覽器”來跟蹤新硬幣的交易和余額,但您必須檢查硬幣合約地址而不是硬幣所有者的地址。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: