用solidity语言开发代币智能合约
智能合約開發(fā)是以太坊編程的核心之一,而代幣是區(qū)塊鏈應用的關鍵環(huán)節(jié),下面我們來用solidity語言開發(fā)一個代幣合約的實例,希望對大家有幫助。
以太坊的應用被稱為去中心化應用(DApp),DApp的開發(fā)主要包括兩大部分:
- 智能合約的開發(fā)
- 用戶界面的開發(fā)
在本文中,我們將介紹智能合約的開發(fā)語言solidity。
讓我們先從一個非常基礎的例子開始,不用擔心你現(xiàn)在還一點都不了解,我們將逐步了解到更多的細節(jié)。
contract SimpleStorage {uint storedData;function set(uint x) {storedData = x;}function get() constant returns (uint retVal) {return storedData;} }在Solidity中,一個合約由一組代碼(合約的函數(shù))和數(shù)據(jù)(合約的狀態(tài))組成。合約位于以太坊區(qū)塊鏈上的一個特殊地址。
uint storedData; 這行代碼聲明了一個狀態(tài)變量,變量名為storedData,類型為 uint (256bits無符號整數(shù))。你可以認為它就像數(shù)據(jù)庫里面的一個存儲單元,跟管理數(shù)據(jù)庫一樣,可以通過調(diào)用函數(shù)查詢和修改它。在以太坊中,通常只有合約的擁有者才能這樣做。在這個例子中,函數(shù) set 和 get 分別用于修改和查詢變量的值。
跟很多其他語言一樣,訪問狀態(tài)變量時,不需要在前面增加 this. 這樣的前綴。
這個合約還無法做很多事情(受限于以太坊的基礎設施),僅僅是允許任何人儲存一個數(shù)字。而且世界上任何一個人都可以來存取這個數(shù)字,缺少一個(可靠的)方式來保護你發(fā)布的數(shù)字。任何人都可以調(diào)用set方法設置一個不同的數(shù)字覆蓋你發(fā)布的數(shù)字。但是你的數(shù)字將會留存在區(qū)塊鏈的歷史上。稍后我們會學習如何增加一個存取限制,使得只有你才能修改這個數(shù)字。
編寫代幣合約
接下來的合約將實現(xiàn)一個形式最簡單的加密貨幣。任何人都可以發(fā)送貨幣給其他人,不需要注冊用戶名和密碼,只要有一對以太坊的公私鑰即可。
contract Coin { //關鍵字“public”使變量能從合約外部訪問。address public minter;mapping (address => uint) public balances;//事件讓輕客戶端能高效的對變化做出反應。event Sent(address from, address to, uint amount);//這個構造函數(shù)的代碼僅僅只在合約創(chuàng)建的時候被運行。 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;`這行代碼聲明了一個可公開訪問的狀態(tài)變量,類型為address。address類型的值大小為160 bits,不支持任何算術操作。適用于存儲合約的地址或其他人的公私鑰。public關鍵字會自動為其修飾的狀態(tài)變量生成訪問函數(shù)。沒有public關鍵字的變量將無法被其他合約訪問。另外只有本合約內(nèi)的代碼才能寫入。自動生成的函數(shù)如下:
function minter() returns (address) { return minter; }當然我們自己增加一個這樣的訪問函數(shù)是行不通的。編譯器會報錯,指出這個函數(shù)與一個狀態(tài)變量重名。
下一行代碼創(chuàng)建了一個public的狀態(tài)變量,但是其類型更加復雜:
mapping (address => uint) public balances;該類型將一些address映射到無符號整數(shù)。mapping可以被認為是一個哈希表,每一個可能的key對應的value被虛擬的初始化為全0.這個類比不是很嚴謹,對于一個mapping,無法獲取一個包含其所有key或者value的鏈表。所以我們得自己記著添加了哪些東西到mapping中。更好的方式是維護一個這樣的鏈表,或者使用其他更高級的數(shù)據(jù)類型。或者只在不受這個缺陷影響的場景中使用mapping,就像這個例子。在這個例子中由public關鍵字生成的訪問函數(shù)將會更加復雜,其代碼大致如下:
function balances(address _account) returns (uint balance) {return balances[_account]; }我們可以很方便的通過這個函數(shù)查詢某個特定賬號的余額。
event Sent(address from, address to, uint value);這行代碼聲明了一個“事件”。由send函數(shù)的最后一行代碼觸發(fā)。客戶端(服務端應用也適用)可以以很低的開銷來監(jiān)聽這些由區(qū)塊鏈觸發(fā)的事件。事件觸發(fā)時,監(jiān)聽者會同時接收到from,to,value這些參數(shù)值,可以方便的用于跟蹤交易。為了監(jiān)聽這個事件,你可以使用如下代碼:
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));} }注意在客戶端中是如何調(diào)用自動生成的 balances 函數(shù)的。
這里有個比較特殊的函數(shù) Coin。它是一個構造函數(shù),會在合約創(chuàng)建的時候運行,之后就無法被調(diào)用。它會永久得存儲合約創(chuàng)建者的地址。msg(以及tx和block)是一個神奇的全局變量,它包含了一些可以被合約代碼訪問的屬于區(qū)塊鏈的屬性。msg.sender 總是存放著當前函數(shù)的外部調(diào)用者的地址。
最后,真正被用戶或者其他合約調(diào)用,用來完成本合約功能的函數(shù)是mint和send。如果合約創(chuàng)建者之外的其他人調(diào)用mint,什么都不會發(fā)生。而send可以被任何人(擁有一定數(shù)量的代幣)調(diào)用,發(fā)送一些幣給其他人。注意,當你通過該合約發(fā)送一些代幣到某個地址,在區(qū)塊鏈瀏覽器中查詢該地址將什么也看不到。因為發(fā)送代幣導致的余額變化只存儲在該代幣合約的數(shù)據(jù)存儲中。通過事件我們可以很容易創(chuàng)建一個可以追蹤你的新幣交易和余額的“區(qū)塊鏈瀏覽器”。
?
分享個適合區(qū)塊鏈新手的教程:以太坊DApp開發(fā)實戰(zhàn)入門
如果想加入以太坊技術開發(fā)群聊交流技術可以加微信.
轉(zhuǎn)載于:https://www.cnblogs.com/helloworld2018/p/8922278.html
總結
以上是生活随笔為你收集整理的用solidity语言开发代币智能合约的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常见问题及解决方案(前端篇)
- 下一篇: 成都欢乐谷各项目开放时间