Solidity教學第四集_收幣與發幣合約
區塊鏈的應用日趨廣泛,智能合約現階段也在金融、供應鏈等領域快速發展,讓許多流程高效率自動化,同時資安管控品質也大幅提升。以下將會有五篇教學文章,讓有或沒有程式背景的讀者都能先撰寫基礎智能合約,以便繼續深造或參與區塊鏈相關項目之商業開發案時能順利溝通。
上一篇章我們介紹了函式可視性與修飾語(Function Visibility、Modifiers與Time)。忘記的朋友可以回去多加複習。
這一集我們將會收幣與發幣的合約進行介紹與操作。
buyToken
現在讓我們來寫一個函式來接收Ether吧!為了展示這個fuction我會寫一個類似於ICO合約的buyToken()函式,這個合約可以讓我們接收ether也可以發送ether。此智能合約可以讓我們發行ether、追蹤我們的帳戶餘額、也可以將自己的ether轉到其他不同的錢包地址,在此跟大家講這個合約只是一個「像是ICO」的合約,並不能直接當作一個正式的ICO合約。
首先我們先建立一個mapping去追蹤我們的餘額
mapping(address => uint256) public balances;
接下來我會建立一個function buyToken() ,它可以讓我們的餘額提升
function buyToken() public {
balances[msg.sender] += 1;
}
接下來我們宣告一個wallet變數,每當我們買新的代幣就會轉到這個錢包內
address wallet;
接者我們只要呼叫buyToken()就可以將錢轉入wallet當中
function buyToken() public payable {
balances[msg.sender] += 1;
wallet.transfer(msg.value);
}
接下來我來解釋一下我們的程式碼
- 我們可以直接將ether轉到wallet裡,利用wallet.transfer()
- 我們可以利用msg.value取得enther的值就像是msg.sender
- 我們也必須使用payable modifier,這樣帳戶才可以發送ether
而因為payable的關係我們也需要將我們的address改為payable
address payable wallet;
接下來我們設定我們的wallet address在我們的constructor(而在這邊我們也需要用到payable modifier)
constructor(address payable _wallet) public {
wallet = _wallet;
}
所以你的程式碼應該會長這樣
contract MyContract {
mapping(address => uint256) public balances;
address payable wallet;
constructor(address payable _wallet) public {
wallet = _wallet;
}
function buyToken() public payable {
balances[msg.sender] += 1;
wallet.transfer(msg.value);
}
}
fallback
接下來我會教你們如何建立一個default 或是 “fallback” 函式,這個函式每當帳戶發送ether的時候都會被呼叫到,在ICO智能合約當中是非常常會被使用到的函式,我們將宣告一個fallback函式,此函式包含了buyTokens() 每當帳戶將以太幣發送到智能合約時,將會購買代幣
function() external payable {
buyToken();
}
我們可以宣告一個events在smart contract中,這樣一來外部的消費者就可以捐贈
這些消費者將可以監聽這個智能合約內發生了什麼事,而我們將在智能合約的底部宣告
event Purchase(
address _buyer,
uint256 _amount
);
此事件可以記錄我們的買家(buyer)以及token數量(amount)
function buyToken() public payable {
balances[msg.sender] += 1;
wallet.transfer(msg.value);
emit Purchase(msg.sender, 1);
}
此事件讓我們在任何時間都知道這個如果這個token有被購買,但是如果我們今天只想知道跟帳戶有關的事情怎麼辦?solidity提供我們索引值去過濾訂閱事件
event Purchase(
address indexed _buyer,
uint256 _amount
);
所以你的程式碼應該長得像這樣
contract MyContract {
mapping(address => uint256) public balances
event Purchase(
address indexed _buyer,
uint256 _amount
);
constructor(address payable _wallet) public {
wallet = _wallet;
}
function() external payable {
buyToken();
}
function buyToken() public payable {
balances[msg.sender] += 1;
wallet.transfer(msg.value);
emit Purchase(msg.sender, 1);
}
}
如果喜歡看更多與區塊鏈技術、應用、科技新知相關的內容,記得留下您的Email並追蹤我們的粉專,那麼新文章上線時,我們將在第一時間通知您,不用再擔心錯過最新消息。