【新年企劃】來去自如跳來跳去的幣 | 智能合約開發計劃 #3

閱讀時間約 14 分鐘

前言

這是新年特別企劃的第三篇,我們的目標是在過年前學習寫自己的第一個智能合約並發行自己的加密貨幣,可以作為紅包發送給親友,或是想想自己幣的用途,打造一個貨幣的經濟模型,所以如果你一篇都還沒看過的話,第一篇的連結在這裡
但是你會發現,前一篇文章的兩個試作品除了當作花瓶欣賞以外,甚麼事情都做不到。既然是貨幣,轉帳交易功能是基本的吧。
沒問題,我們馬上來寫第三支程式,像前兩個程式一樣,回到檔案總管,在contracts底下開啟新檔,我將其命名為TransferToken.sol,這次程式複雜多了,我們一部分一部分拆開來看,整個完整的程式碼會附在文章的後面。

第三個試作品 | 可交易的智能合約

要完成一個可以正常運作的加密貨幣,除了上次開發的加密貨幣初始參數客製化功能以外,還需要兩個步驟,分為錢包餘額查詢以及轉帳兩部分。

《錢包餘額查詢》

要讓幣可以被交易的話,那就一定要有能夠查詢餘額的功能,為甚麼?
試想若你是銀行,遇到一筆來自客戶的交易請求,請求內容是請你將他的錢匯款到其他人的帳戶之中,那第一個要做的事情,就是先檢查他銀行帳戶的餘額有沒有比要匯出的金額多或是剛好,否則扣款後帳戶變成負的後續會很麻煩,或許銀行還能凍結他的帳戶之類的方式追回錢,但在區塊鏈的世界中,錢匯出就是匯出了根本無從處理,只能祈禱他有一天會記得還錢。
所以要能夠達成交易的功能,查錢包裡的錢夠不夠就會是第一步,這個也是整個程式碼中最簡單的部分,只有一行而已:
mapping(address => uint256) public balanceOf;
意思是將錢包的餘額數據讀取出來,存入名為balanceOf的變數之中。多了這個變數之後,當我們發佈智能合約之後,原先在Deployed Contracts的地方就會從四個變數按紐變為五個。
我們先先複製發佈這個智能合約的錢包地址,錢包地址就在 “DEPLOY & RUN TRANSACTIONS”裡面的ACCOUNT,右邊就有複製標誌了。
點擊balanceOf按鈕之前,只要貼上剛剛複製的錢包地址,再按下balanceOf按紐,錢包餘額數據就直接出現了了,數量應該要跟當初設定的 _totalSupply 一樣,因為這些錢會在發佈智能合約的當下存入發佈者的地址!若是拿其他錢包地址查詢balanceOf的話都必須要是0哦,因為我們還沒有撰寫轉帳交易的功能,除了發佈者以外不可能拿到這個加密貨幣。

《轉帳》

轉帳是這個程式中最重要的部分,一個不能夠被轉出的東西不要說是貨幣了,或許連物品都稱不上。

事件

平常購物時,我們會把錢包裡的錢交給店員,這個動作本身是一個事件,在Solidity叫做event,所以我們必須先定義一個event,這個event是一個以太坊虛擬主機(EVM)提供的便利接口,當真的發生金錢轉移時就可以直接呼叫這個event,它就會協助我們把這筆交易寫在區塊鏈的帳本上哦。
event Transfer(address indexed from, address indexed to, uint256 value);
我們建立一個叫做Transfer的事件,from就是匯款人的錢包地址,to就是接收款人的錢包地址,value是多少錢,value前面的uint256意思是不是一個負數的整數(所以value的值必須是0或正整數),但這是已經結束交易,要請主機幫我們上鏈時呼叫的程式碼,前置作業我們還是得自己來。

轉帳程式碼

事實上在撰寫智能合約時就像在打造一部不需要人力也能自動運作的自動販賣機,既然要協助轉帳,我們就必須將自己想像成一間銀行或一台ATM,以此角度思考會更容易理解。
轉帳會有「匯款人」與「收款人」兩個角色,要做的事情是「給出多少錢」,先看程式碼:
function transfer(address _to, uint256 _value) external returns (bool success) {
require(balanceOf[msg.sender] >= _value);
require(_to != address(0));

balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;

emit Transfer(msg.sender, _to, _value);
return true;
}
先大致描述一下這段程式碼的用意:
定義一個轉帳的function叫transfer,要使用這個轉帳功能需要提供 _to 與 _value兩個參數,若這個程式執行成功會返回true表示交易都沒問題了;若返回false表示程式執行時遇到問題,可能是他寫的轉帳地址不對,或是他根本沒有這麼多錢。

角色定義

在區塊鏈中的「匯款人」是誰?就是使用這台自動販賣機的人,也就是使用智能合約的錢包地址,在Solidity中可以直接使用 “msg.sender” (message sender, 訊息的傳遞者),這背後代表的就是發佈或是呼叫智能合約的地址,如果顯示出來的話就會是 0x…….. 。
「收款人」是誰、「給出多少錢」又是什麼呢?想像一下要做一筆銀行轉帳給朋友,我們一定要輸入兩個東西,一個就是朋友的銀行帳戶,一個是多少錢;對應到智能合約調用時也是一樣,_to要填入對方的錢包地址,_value要填入轉帳金額,就是這麼簡單。

檢查機制-檢查匯款人餘額

在Solidity中,require是一種檢查機制,裡面要放判斷式,如果判斷式成立的話程式就會繼續往下運作;如果判斷式不成立的話,程式就會直接回傳false並停止運作。
require(balanceOf[msg.sender] >= _value);
如果匯款人要匯5000塊給對方,但是他帳戶裡只有87塊,當然不能讓他稱心如意的匯款,所以我們需要先用require來檢查餘額,檢查方法就是呼叫我們寫好的餘額查詢balanceOf啦,檢查對象是匯款人(msg.sender),檢查用的判斷式是他的餘額是否大於等於要匯出的金額 _value。

檢查機制-檢查收款人地址正確性

require(_to != address(0));
其實檢查收款人地址是否正確的意思不是保證你輸入的地址是收款人的地址,而是避免不小心沒有填入收款人地址,導致地址是空的 (_to = 0x0),我一開始以為0x0就是一個都是0的錢包地址,錢錢就會匯入這個零地址導致加密貨幣資產丟失,但是研究了一下發現似乎不是這樣,因為在Solidity官方文檔中寫了這段話:
If the target account is not set (the transaction does not have a recipient or the recipient is set to null), the transaction creates a new contract. As already mentioned, the address of that contract is not the zero address but an address derived from the sender and its number of transactions sent (the “nonce”).
看起來對於以太坊虛擬機而言,如果在做transaction時收到零地址,表示我們打算發佈新智能合約,而不是轉移資產要特別注意!

轉帳流程

轉帳就是匯款人扣錢,收款人加錢這麼簡單,用中文的寫的話就會像這樣:
換款人錢包裡的錢 = 換款人錢包裡的錢 - 匯出的金額
收款人錢包裡的錢 = 收款人錢包裡的錢 + 收到的金額
轉換成程式碼的話就會這樣寫,將對應角色錢包中的錢加上或扣除轉帳的金額。
balanceOf[msg.sender] = balanceOf[msg.sender] - _value;
balanceOf[_to] = balanceOf[_to] + _value;
或是可以利用 += 和 -= 的簡寫方式,讓程式碼看起來更簡潔。
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;

發送交易

終於來到程式碼的最後,程式能執行到這裡表示前面都是沒有異常的,所以要正式發送這筆交易紀錄到區塊鏈上了。
emit Transfer(msg.sender, _to, _value);
return true;
利用emit的方式發送交易請求到一開始寫的 Transfer 事件,最後再回傳一切正常的 true 就結束啦。

TransferToken.sol

加上前一篇寫的,整個程式碼現在應該是這樣:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;

contract Token {

string public name;
string public symbol;
uint256 public decimals;
uint256 public totalSupply;

constructor(string memory _name, string memory _symbol, uint _decimals, uint _totalSupply){
name = _name;
symbol = _symbol;
decimals = _decimals;
totalSupply = _totalSupply;
balanceOf[msg.sender] = totalSupply;
}

mapping(address => uint256) public balanceOf;

  event Transfer(address indexed from, address indexed to, uint256 value);

function transfer(address _to, uint256 _value) external returns(bool success){
require(balanceOf[msg.sender] >= _value);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}

在錢包之間走跳的錢

每次程式寫完之後就要記得編譯、發佈,再填入初始參數發幣,這裡就不再贅述了。如果忘記可以回去上一篇看看怎麼操作,接著我們就來實際操作發幣與轉帳,確保程式寫的都能夠正常運作沒有Bug。

轉帳

轉帳時我們會需要兩種角色分別是匯款人與收款人,假設合約發佈的地址是0x5B開頭,被我標籤為1的地址,那麼在合約發佈的當下,這個貨幣的總供應量會全部放入這個地址中,在任何轉帳發生前,全世界只有這個地址會有剛剛發的貨幣,所以它一定是匯款人。
收款人則是被我標籤為2,0xAb開頭的地址,請先將ACCOUNT欄位切換成2,並且按下右邊黃圈圈標示的icon,將它的地址複製起來,這時候你必須要將ACCOUNT再次切回地址1,因為我們要使用地址1去呼叫智能合約中的transfer function,它就會是msg.sender本人。
在”DEPLOY & RUN TRANSACTIONS”往下滑會看到Deployed Contracts,你會發現多了一顆橘色的transfer按紐,這就是拿來讓我們轉帳的,右邊有個向下的小箭頭點下去應該會長這樣:
_to: 是收款人,就是另一個錢包地址,這個地址就直接貼上我們剛剛在ACCOUNT欄位切換到第二個錢包0xAb開頭的地址,或是你想要貼上其他地址也可以。
_value: 就填要轉的金額數,只要不要是負的整數都可以,這裡填100的意思是要匯出0.0000000000000001顆我們發的幣,因為Decimals是小數點後18位數,所以_value欄位中填入100表示要匯出的數量是 100 x 10e-18 = 10e-16 = 0.0000000000000001顆代幣,如果你要匯出100顆的代幣,value就必須填100,000,000,000,000,000,000,就是100後面加18個0。
兩個參數設定完,就能夠按下橘色的transact,轉帳就成功啦!

驗證結果

在這裡我們使用balanceOf功能,直接輸入對應的錢包地址查詢餘額,假設在發佈合約後,我們只做了上面做的那一次轉帳,轉出了_value:100的貨幣(相當於 0.0000000000000001顆)給另一個錢包地址,則兩個錢包的餘額一個應該顯示999999999999999999999999999900,另一個應該顯示100:
📷
餘額若與前面轉帳的操作結果相同,那麼恭喜你已經成功發行了自己的加密貨幣,這個幣就像活的已經可以在各個錢包之間跳來跳去!

結語

經過這一次的更改,我們發行了一個可以交易的幣,實際轉帳應該也都沒問題了表示在本機端的測試都是可以正常運作的。
下一次我們會嘗試將幣發到測試網中,你會需要有一個Metamask錢包,敬請期待!

延伸閱讀


最後,謝謝你在百忙之中願意抽空來花時間來看我的文章,如果還喜歡這些內容的話希望能獲得你的追蹤及支持,也歡迎點此連結在其他平台找到我
下次見嚕 o((>ω< ))o~
為什麼會看到廣告
《科技隨筆 | 智能合約開發計畫》 智能合約開發計畫會深入淺出,從認識以太坊的協議開始出發,慢慢從最簡單的代幣到發行 NFT ,甚至是開發一些去中心化應用程式(Dapps),並做一些簡單的使用者介面讓任何人可以透過瀏覽器開啟 Web3.0 的大門。
留言0
查看全部
發表第一個留言支持創作者!
在本文中,我們會開始寫一些程式,讓讀者瞭解如何利用Remix開發環境來撰寫Solidity程式,以及如何編譯、發佈智能合約。還有在發佈之後怎麼看剛剛設定的參數是否都成功被執行了,一起實作發出人生第一顆發財幣吧!
2022年的農曆新年在一月底就要登場了!說到新年或多或少一定免不了要家族團聚吃個團圓飯,又到了這個時間了,身為社畜的你想好今年要包多少紅包給家人了嗎?這次過年就逼親戚下載錢包,直接把你設計的發財幣、紅包幣、坐以待幣、大學延幣通通在過年的時候射給他們吧!
在本文中,我們會開始寫一些程式,讓讀者瞭解如何利用Remix開發環境來撰寫Solidity程式,以及如何編譯、發佈智能合約。還有在發佈之後怎麼看剛剛設定的參數是否都成功被執行了,一起實作發出人生第一顆發財幣吧!
2022年的農曆新年在一月底就要登場了!說到新年或多或少一定免不了要家族團聚吃個團圓飯,又到了這個時間了,身為社畜的你想好今年要包多少紅包給家人了嗎?這次過年就逼親戚下載錢包,直接把你設計的發財幣、紅包幣、坐以待幣、大學延幣通通在過年的時候射給他們吧!
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
2023年我只設了一個大目標"穩定發文",最後挑戰成功了!然因去年底的身體警訊,今(2024)年我得同時挑戰兩個"大目標"--健康與發文兼顧! 且兩個大目標下,還有各有4個"子目標"願景..我花了1-2月這兩個月的時間,進行了各種資料收集與"先期挑戰",最終我的具體目標和預計的執行路徑會是什麼呢?
Thumbnail
農曆新年快樂,餃子有元寶的寓意,一起迎向豐盛之路。 靜心深呼吸3次,選一份與你有連結的餃子,看看如何開啟今年的豐盛之路。 透過情感與情緒的流動帶領內在的能量流動,並附有相關精油療癒與正面語句的建議,一起開啟豐盛之路。
Thumbnail
熱血沸騰的BWF年終賽彷彿昨天才剛剛結束,新年度賽季緊接從1月9日起,由超級1000等級的馬來西亞公開賽揭開序幕。本賽事作為奧運積分週期下半場的第一項大賽,各路高手齊聚。籤表一公布,各分項首輪已出現許多堪稱決賽規格的對決。
Thumbnail
亞企味屋 AJIYA 西湖店,位在捷運西湖站步行約九分鐘的距離 餐廳位置在轉角內,有點隱密需張大眼睛仔細找一下~ 亞企味屋 AJIYA 西湖店,環境挑高擺放許多電視,一邊用餐一邊看電視不怕無聊~ 座位區下方有插座可以充電,不怕手機臨時滑到沒電! 裝潢走一個溫色調,隨著耶誕節即將來臨,店內精心
Thumbnail
美國爸爸最近發了新年大紅包你領到了嗎?這個紅包行情還能持續多久呢?這周展望全都告訴你的啦!
Thumbnail
*********************************** ╬ 聖女新娘這部小說純屬虛構,請勿當真 ╬ *********************************** = 聖女新娘 94 起來!我的孩子! = 無法回轉歸去的雅典大路旁,一輛紅色跑車停在路燈下,四個人坐在車內。 三
Thumbnail
因為第41卦門就是幻想之門。世事皆可能。這是我們真正的開始。其他一切都是準備。在我們進入第41卦門的那一刻,我們真正開始了這一輪的全部內容。我們正在開始能夠真正經歷它並完成整個過程的過程。
Thumbnail
下個月就是新的一年的開始,無論是西元年或是農曆年。 在這個歲末年初的時間點,大家最喜歡的就是設定新年的目標。為自己重新定調,期待建立嶄新的一年! 我也很喜歡在12月計劃下一年度的目標,在設定目標的時候總是滿懷欣喜,開心的想著一一達成目標後的豐盛來年!
Thumbnail
新娘秘書有多麼重要?就像一場婚禮的魔術師一樣,巧手讓新人轉身一變此生最閃耀的Super star,而身為一場人生Show最為重要的新娘秘書,當然要來看看新娘秘書作品便知功力有沒有,本篇為您解析台北新娘秘書推薦之SaSa老師。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
2023年我只設了一個大目標"穩定發文",最後挑戰成功了!然因去年底的身體警訊,今(2024)年我得同時挑戰兩個"大目標"--健康與發文兼顧! 且兩個大目標下,還有各有4個"子目標"願景..我花了1-2月這兩個月的時間,進行了各種資料收集與"先期挑戰",最終我的具體目標和預計的執行路徑會是什麼呢?
Thumbnail
農曆新年快樂,餃子有元寶的寓意,一起迎向豐盛之路。 靜心深呼吸3次,選一份與你有連結的餃子,看看如何開啟今年的豐盛之路。 透過情感與情緒的流動帶領內在的能量流動,並附有相關精油療癒與正面語句的建議,一起開啟豐盛之路。
Thumbnail
熱血沸騰的BWF年終賽彷彿昨天才剛剛結束,新年度賽季緊接從1月9日起,由超級1000等級的馬來西亞公開賽揭開序幕。本賽事作為奧運積分週期下半場的第一項大賽,各路高手齊聚。籤表一公布,各分項首輪已出現許多堪稱決賽規格的對決。
Thumbnail
亞企味屋 AJIYA 西湖店,位在捷運西湖站步行約九分鐘的距離 餐廳位置在轉角內,有點隱密需張大眼睛仔細找一下~ 亞企味屋 AJIYA 西湖店,環境挑高擺放許多電視,一邊用餐一邊看電視不怕無聊~ 座位區下方有插座可以充電,不怕手機臨時滑到沒電! 裝潢走一個溫色調,隨著耶誕節即將來臨,店內精心
Thumbnail
美國爸爸最近發了新年大紅包你領到了嗎?這個紅包行情還能持續多久呢?這周展望全都告訴你的啦!
Thumbnail
*********************************** ╬ 聖女新娘這部小說純屬虛構,請勿當真 ╬ *********************************** = 聖女新娘 94 起來!我的孩子! = 無法回轉歸去的雅典大路旁,一輛紅色跑車停在路燈下,四個人坐在車內。 三
Thumbnail
因為第41卦門就是幻想之門。世事皆可能。這是我們真正的開始。其他一切都是準備。在我們進入第41卦門的那一刻,我們真正開始了這一輪的全部內容。我們正在開始能夠真正經歷它並完成整個過程的過程。
Thumbnail
下個月就是新的一年的開始,無論是西元年或是農曆年。 在這個歲末年初的時間點,大家最喜歡的就是設定新年的目標。為自己重新定調,期待建立嶄新的一年! 我也很喜歡在12月計劃下一年度的目標,在設定目標的時候總是滿懷欣喜,開心的想著一一達成目標後的豐盛來年!
Thumbnail
新娘秘書有多麼重要?就像一場婚禮的魔術師一樣,巧手讓新人轉身一變此生最閃耀的Super star,而身為一場人生Show最為重要的新娘秘書,當然要來看看新娘秘書作品便知功力有沒有,本篇為您解析台北新娘秘書推薦之SaSa老師。