2. 實況主捐款合約 (ep.16)

閱讀時間約 5 分鐘

讓直播主本人成為合約擁有者

合約定義

  1. 建立時, 須將合約的建立者設定成owner(constructor, msg.sender)
  2. 須記錄每個觀眾的捐款總額(mapping)
  3. 每次收到捐款時, 需要觸發捐款事件(event)
  4. 列出捐款者, 列出捐款者, 捐款金額(indexed)
  5. 提供函式可以查詢觀眾的總捐款金額(returns)
  6. 提供函示可以查詢觀眾的VIP等級(string, if)
  • 沒捐款過 -> "None"
  • > 0 ETH -> "N"
  • > 1 ETH -> "R"
  • > 5 ETH -> "SR"
  • > 10 ETH -> "UR"
  1. 提供函示讓實況主可以提領金額, 且觸發提領事件(payable, address, balance, transfer)
  2. 列出提款者, 提款金額
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

contract Donation {
address public owner; // 1. 將合約的擁有者設定成建立合約的人
// 2. 對應每個觀眾的位址, 到捐款的金額列表
mapping(address => uint256) donationList;
// 3. 捐款事件, 會有捐款人, 以及捐了多少錢?
event Donate(address indexed sender, uint256 value);
// 7. 提領事件
event Withdraw(address indexed owner, uint256 value);
// 7. 只有擁有者可以提領
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can access this function");
_;
}

constructor() {
// 1. 將合約的擁有者設定成建立合約的人
owner = msg.sender;

}

// 3. 收受捐款的函式, 讓觀眾可以呼叫
function donate() public payable {
// 4. 更新列表, 將捐款的金額加上去
donationList[msg.sender] += msg.value;
emit Donate(msg.sender, msg.value);
}

// 5. 查詢捐款總金額
function getHistory() public view returns (uint256){
return donationList[msg.sender];
}

// 6. 查詢VIP等級
function getRank() public view returns (string memory) {
if (donationList[msg.sender] > 10 ether) {
return "UR";
} else if (donationList [msg.sender] > 5 ether) {
return "SR";
} else if (donationList[msg.sender] > 1 ether){
return "R";
} else if (donationList[msg.sender] > 0) {
return "N";
} else {
return "None";
}
}

// 7.提領餘額
function withdraw() onlyOwner public {
address payable receiver = payable(owner);
uint256 value = address(this).balance;
receiver.transfer(value);
// 8. 列出提款者, 提款金額
emit Withdraw(receiver, value);
}
}

在 2022 年,我們該如何寫智能合約

尋大神腳印, 亦步亦趨。
留言0
查看全部
發表第一個留言支持創作者!
從 Google News 追蹤更多 vocus 的最新精選內容