現在我們對以太坊區塊鏈有更多的認識,今天我們繼續回來看看程式語言的部分吧!
跟之前一樣,我們用Remix IDE (https://remix.ethereum.org/),首先,新增一個檔案,我叫他coin.sol。
我們打開Solidity官方文件中左邊第一個Introduction to Smart Contracts(https://solidity.readthedocs.io/en/v0.5.11/),裡面的第二個例子,我們把它複製過來。
這個智能合約叫Coin,它裡面有address(地址)和mapping(映射)。
我們之前提過以太坊區塊鏈中帳戶的概念,address(地址)就像是我們帳戶的帳號,地址中包含帳戶餘額,並且能支付和接受以太幣(我們會透過函數傳輸值到特定的地址),我們現在有一個叫minter的地址(帳戶)。
mapping(映射)是一種很常見的數據結構,我想映射這個詞對大部分商管學生來說都不太好懂,讓我用簡單的例子說明: 映射其實就是一種對應的準則,今天考試小鈞考了90分,小瑜考了59分,老師只列出小鈞及格,小瑜不及格,這樣就是一個映射的例子。使用60分以上及格,59分以下不及格這樣的準則,將人名(小鈞、小瑜)映射到考試結果(及格、不及格)。回到coin智能合約的例子,是將帳戶地址映射到我們擁有的餘額(uint)。
contract Coin {
address public minter;
mapping (address => uint) public balances;
接著我們使用event(事件)定義:錢從哪個地址發送出來、錢發送到哪個地址以及發送的金額。
event Sent(address from, address to, uint amount);
我們使用constructor()函數,msg.sender是發送消息的地址,我們叫它minter。
constructor() public {
minter = msg.sender;
}
我們有一個創造貨幣(mint)的函數,只有發送的地址(minter),可以創造貨幣。
function mint(address receiver, uint amount) public {
require(msg.sender == minter);
require(amount < 1e60);
balances[receiver] += amount;
}
最後,我們有一個發送(send)函數,將我們創造出來的貨幣發送到特定的地址,因此你會有一個接收的地址(receiver)和發送的貨幣數量(amount),如果發送方的帳戶餘額小於要發送的金額,則告訴你餘額不足,如果餘額足夠,發送的帳戶餘額減少貨幣數量,接收的帳戶餘額增加貨幣數量。這裡的emit會觸發我們前面定義的事件(event)。
function send(address receiver, uint amount) public {
require(amount <= balances[msg.sender], "Insufficient balance.");
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}
現在我們來編譯並部署這個智能合約。
我們先創造貨幣2000塊,複製帳戶地址到mint中,並且在地址後面打上2000,點選mint,再點選balance。
現在,我們有2000塊了,接著我們複製另一個帳戶到send中,並且在地址後面打上500,點選send,現在我們可以看到另一個帳戶有收到我們的500塊貨幣,而我們的minter的帳戶,因為發送了500塊,所以現在帳戶會顯示1500塊。
透過這個簡單的智能合約coin來創造和發送貨幣,幫助大家了解Solidity中的地址(address)、映射(mapping)和消息(msg),接著下一篇我帶大家了解Solidity中的voting(投票)的例子,那我們明天見~
程式碼
pragma solidity >=0.5.0 <0.7.0;
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() public {
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);
require(amount < 1e60);
balances[receiver] += amount;
}
// Sends an amount of existing coins
// from any caller to an address
function send(address receiver, uint amount) public {
require(amount <= balances[msg.sender], "Insufficient balance.");
balances[msg.sender] -= amount;
balances[receiver] += amount;
emit Sent(msg.sender, receiver, amount);
}
}