以太坊智能合約開發之代幣合約
智能合約開發是以太坊開發的核心,而代幣合約的編寫是智能合約開發的核心,用solidity開發一個代幣合約的例子是學習以太坊開發智能合約時必須掌握的。
以太坊的應用被稱為去中心化應用(DApp),DApp的開發主要包括兩大部分:
- 智能合約的開發
- 用戶界面的開發
在本文中,我們將介紹智能合約的開發語言solidity。
讓我們先從一個非常基礎的例子開始,不用擔心你現在還一點都不了解,我們將逐步了解到更多的細節。
contract SimpleStorage {
uint storedData; function set(uint x) {
storedData = x;
} function get() constant returns (uint retVal) { return storedData;
}
}
在Solidity中,一個合約由一組代碼(合約的函數)和數據(合約的狀態)組成。合約位於以太坊區塊鏈上的一個特殊地址。
uint storedData; 這行代碼聲明了一個狀態變量,變量名為storedData,類型為 uint (256bits無符號整數)。你可以認為它就像數據庫裏面的一個存儲單元,跟管理數據庫一樣,可以通過調用函數查詢和修改它。在以太坊中,通常只有合約的擁有者才能這樣做。在這個例子中,函數 set 和 get 分別用於修改和查詢變量的值。
跟很多其他語言一樣,訪問狀態變量時,不需要在前面增加 this. 這樣的前綴。
這個合約還無法做很多事情(受限於以太坊的基礎設施),僅僅是允許任何人儲存一個數字。而且世界上任何一個人都可以來存取這個數字,缺少一個(可靠的)方式來保護你發布的數字。任何人都可以調用set方法設置一個不同的數字覆蓋你發布的數字。但是你的數字將會留存在區塊鏈的歷史上。稍後我們會學習如何增加一個存取限制,使得只有你才能修改這個數字。
編寫代幣合約
接下來的合約將實現一個形式最簡單的加密貨幣。任何人都可以發送貨幣給其他人,不需要註冊用戶名和密碼,只要有一對以太坊的公私鑰即可。
contract Coin { //關鍵字“public”使變量能從合約外部訪問。 address public minter;
mapping (address => uint) public balances; //事件讓輕客戶端能高效的對變化做出反應。 event Sent(address from, address to, uint amount); //這個構造函數的代碼僅僅只在合約創建的時候被運行。 function Coin() {
minter = msg.sender;
} function mint(address receiver, uint amount) { if (msg.sender != minter) return;
balances[receiver] += amount;
} function send(address receiver, uint amount) { if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Sent(msg.sender, receiver, amount);
}
}
這個合約引入了一些新的概念,讓我們來逐個介紹。
address public minter;`
這行代碼聲明了一個可公開訪問的狀態變量,類型為address。address類型的值大小為160 bits,不支持任何算術操作。適用於存儲合約的地址或其他人的公私鑰。public關鍵字會自動為其修飾的狀態變量生成訪問函數。沒有public關鍵字的變量將無法被其他合約訪問。另外只有本合約內的代碼才能寫入。自動生成的函數如下:
function minter() returns (address) { return minter; }
當然我們自己增加一個這樣的訪問函數是行不通的。編譯器會報錯,指出這個函數與一個狀態變量重名。
下一行代碼創建了一個public的狀態變量,但是其類型更加復雜:
mapping (address => uint) public balances;
該類型將一些address映射到無符號整數。mapping可以被認為是一個哈希表,每一個可能的key對應的value被虛擬的初始化為全0.這個類比不是很嚴謹,對於一個mapping,無法獲取一個包含其所有key或者value的鏈表。所以我們得自己記著添加了哪些東西到mapping中。更好的方式是維護一個這樣的鏈表,或者使用其他更高級的數據類型。或者只在不受這個缺陷影響的場景中使用mapping,就像這個例子。在這個例子中由public關鍵字生成的訪問函數將會更加復雜,其代碼大致如下:
function balances(address _account) returns (uint balance) { return balances[_account];
}
我們可以很方便的通過這個函數查詢某個特定賬號的余額。
event Sent(address from, address to, uint value);
這行代碼聲明了一個“事件”。由send函數的最後一行代碼觸發。客戶端(服務端應用也適用)可以以很低的開銷來監聽這些由區塊鏈觸發的事件。事件觸發時,監聽者會同時接收到from,to,value這些參數值,可以方便的用於跟蹤交易。為了監聽這個事件,你可以使用如下代碼:
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));
}
}
註意在客戶端中是如何調用自動生成的 balances 函數的。
這裏有個比較特殊的函數 Coin。它是一個構造函數,會在合約創建的時候運行,之後就無法被調用。它會永久得存儲合約創建者的地址。msg(以及tx和block)是一個神奇的全局變量,它包含了一些可以被合約代碼訪問的屬於區塊鏈的屬性。msg.sender 總是存放著當前函數的外部調用者的地址。
最後,真正被用戶或者其他合約調用,用來完成本合約功能的函數是mint和send。如果合約創建者之外的其他人調用mint,什麽都不會發生。而send可以被任何人(擁有一定數量的代幣)調用,發送一些幣給其他人。註意,當你通過該合約發送一些代幣到某個地址,在區塊鏈瀏覽器中查詢該地址將什麽也看不到。因為發送代幣導致的余額變化只存儲在該代幣合約的數據存儲中。通過事件我們可以很容易創建一個可以追蹤你的新幣交易和余額的“區塊鏈瀏覽器”。
分享兩個教程和一些免費資料給讀者:
一個適合區塊鏈新手的以太坊DApp開發教程:
http://xc.hubwiz.com/course/5a952991adb3847553d205d1
一個用區塊鏈、星際文件系統(IPFS)、Node.js和MongoDB來構建電商平臺:
http://xc.hubwiz.com/course/5abbb7acc02e6b6a59171dd6
收集整理了一些免費區塊鏈、以太坊技術開發相關的文件,有需要的可以下載,文件鏈接:
1. web3.js API官方文檔中文版:https://pan.baidu.com/s/1hOV9hEzi7hFxJCL4LTvC6g
2. 以太坊官方文檔中文版 :https://pan.baidu.com/s/1ktODJKLMBmkOsi8MPrpIJA
3. 以太坊白皮書中文版 :https://pan.baidu.com/s/1bzAFnzJ35hlQxJ2J4Oj-Ow
4. Solidity的官方文檔中文版 :https://pan.baidu.com/s/18yp9XjEqAHpiFm2ZSCygHw
5. Truffle的官方文檔中文版 :https://pan.baidu.com/s/1y6SVd7lSLUHK21YF5FzIUQ
6. C#區塊鏈編程指南 :https://pan.baidu.com/s/1sJPLqp1eQqkG7jmxqwn3EA
7. 區塊鏈技術指南 :https://pan.baidu.com/s/13cJxAa80I6iMCczA04CZhg
8. 精通比特幣中文版 :https://pan.baidu.com/s/1lz6te3wcQuNJm28rFvBfxg
9. Node.js區塊鏈開發 :https://pan.baidu.com/s/1Ldpn0DvJ5LgLqwix6eWgyg
10. geth使用指南文檔中文版 :https://pan.baidu.com/s/1M0WxhmumF_fRqzt_cegnag
11. 以太坊DApp開發環境搭建-Ubuntu : https://pan.baidu.com/s/10qL4q-uKooMehv9X2R1qSA
12. 以太坊DApp開發環境搭建-windows :https://pan.baidu.com/s/1cyYkhIJIFuI2oyxM9Ut0eA
13. 以太坊DApp開發私鏈搭建-Ubuntu : https://pan.baidu.com/s/1aBOFZT2bCjD2o0EILBWs-g
14. 以太坊DApp開發私鏈搭建-windows :https://pan.baidu.com/s/10Y6F1cqUltZNN99aJv9kAA
以太坊智能合約開發之代幣合約