現在,我們將把我們基礎的Item
合約轉化爲更覆雜的Marketplace
合約。Marketplace
合約將維護一個待售商品列錶,爲用戶提供上架新商品和購買商品的方式。
爲此,我們將在合約中添加一些新功能:
每個商品都會有一個賣家
地址,代錶商品的所有者。
我們將引入新函數listItemForSale
,允許用戶上架新商品進行出售。
我們還將引入新函數buyItem
,允許用戶購買商品。Marketplace
合約代碼如下:
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
contract Marketplace {
// Define a new structure for Items
struct Item {
string name;
uint price;
address payable seller;
bool forSale;
}
// Array to hold all the items
Item[] public items;
// Event that will be emitted when a new item is created
event NewItem(uint itemId, string itemName, uint itemPrice, address seller);
// Event that will be emitted when an item is listed for sale
event ItemListed(uint itemId, string itemName, uint itemPrice, address seller);
// Event that will be emitted when an item is bought
event ItemBought(uint itemId, string itemName, uint itemPrice, address seller, address buyer);
// Function to create a new item but not list it for sale immediately
function createItem(string memory _name, uint _price) public {
items.push(Item(_name, _price, payable(msg.sender), false)); // We need to explicitly convert msg.sender to 'address payable'
emit NewItem(items.length - 1, _name, _price, msg.sender);
}
// Function to list an item for sale
function listItemForSale(uint _itemId) public {
Item storage item = items[_itemId];
require(msg.sender == item.seller, "Only the owner can list the item for sale");
item.forSale = true;
emit ItemListed(_itemId, item.name, item.price, item.seller);
}
// Function to buy an item
function buyItem(uint _itemId) public payable {
Item storage item = items[_itemId];
require(msg.sender != item.seller, "Seller cannot buy their own item");
require(item.forSale, "Item is not for sale");
require(msg.value == item.price, "Incorrect price sent");
item.seller.transfer(msg.value);
item.forSale = false;
emit ItemBought(_itemId, item.name, item.price, item.seller, msg.sender);
}
}
這份合約包含:
一個Item
結構,包含一個seller
地址和一個forSale
布爾值。seller
是商品的所有者,forSale
錶示該商品當前是否上架出售。
一個createItem
函數,用於創建新商品併將msg.sender
指定爲賣家。msg.sender
是Solidity中的全局變量,錶示調用當前函數的人或智能合約的地址。然而,該商品不會立即上架出售。
一個listItemForSale
函數,允許商品的賣家將其上架出售。我們使用require
函數來確保隻有賣家可以將商品上架出售。
一個buyItem
函數,允許其他人購買商品。該函數會就以下信息進行檢查確認:商品是否上架出售、買家不是賣家、髮送的金額正確。如果滿足這些條件,函數將曏賣家髮送款項,併將商品標記爲非出售狀態。
在完成Marketplace
合約的編寫後,下一步就是編譯和部署該合約。您可以使用Remix中的Solidity Compiler插件來編譯合約,可參考我們在第1課中所講的步驟。
要部署合約,請轉到右側麵闆上的“Deploy & Run Transactions”插件(立方體圖標)。選擇合適的環境(如用於模擬的JavaScript VM),從合約下拉列錶中選擇Marketplace
合約,然後單擊“Deploy”按鈕。
合約部署完成後,它將出現在“Deployed Contracts”闆塊中。展開該合約可以查看其公共狀態變量和函數。您可以通過調用這些函數來創建、上架和購買商品。
要創建商品,請輸入名稱和價格,然後單擊createItem
按鈕。要將商品上架出售,請輸入商品ID併單擊listItemForSale
按鈕。要購買商品,請輸入商品ID,髮送正確數量的以太幣,然後單擊buyItem
按鈕。
恭喜大家!您現在已經熟練掌握了如何在以太坊區塊鏈上創建一個基礎的去中心化市場。
在下一課中,我們將爲合約添加一些新功能,包括從出售列錶中移除商品和更新商品價格,以便對該市場進行升級。請持續關註!
現在,我們將把我們基礎的Item
合約轉化爲更覆雜的Marketplace
合約。Marketplace
合約將維護一個待售商品列錶,爲用戶提供上架新商品和購買商品的方式。
爲此,我們將在合約中添加一些新功能:
每個商品都會有一個賣家
地址,代錶商品的所有者。
我們將引入新函數listItemForSale
,允許用戶上架新商品進行出售。
我們還將引入新函數buyItem
,允許用戶購買商品。Marketplace
合約代碼如下:
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
contract Marketplace {
// Define a new structure for Items
struct Item {
string name;
uint price;
address payable seller;
bool forSale;
}
// Array to hold all the items
Item[] public items;
// Event that will be emitted when a new item is created
event NewItem(uint itemId, string itemName, uint itemPrice, address seller);
// Event that will be emitted when an item is listed for sale
event ItemListed(uint itemId, string itemName, uint itemPrice, address seller);
// Event that will be emitted when an item is bought
event ItemBought(uint itemId, string itemName, uint itemPrice, address seller, address buyer);
// Function to create a new item but not list it for sale immediately
function createItem(string memory _name, uint _price) public {
items.push(Item(_name, _price, payable(msg.sender), false)); // We need to explicitly convert msg.sender to 'address payable'
emit NewItem(items.length - 1, _name, _price, msg.sender);
}
// Function to list an item for sale
function listItemForSale(uint _itemId) public {
Item storage item = items[_itemId];
require(msg.sender == item.seller, "Only the owner can list the item for sale");
item.forSale = true;
emit ItemListed(_itemId, item.name, item.price, item.seller);
}
// Function to buy an item
function buyItem(uint _itemId) public payable {
Item storage item = items[_itemId];
require(msg.sender != item.seller, "Seller cannot buy their own item");
require(item.forSale, "Item is not for sale");
require(msg.value == item.price, "Incorrect price sent");
item.seller.transfer(msg.value);
item.forSale = false;
emit ItemBought(_itemId, item.name, item.price, item.seller, msg.sender);
}
}
這份合約包含:
一個Item
結構,包含一個seller
地址和一個forSale
布爾值。seller
是商品的所有者,forSale
錶示該商品當前是否上架出售。
一個createItem
函數,用於創建新商品併將msg.sender
指定爲賣家。msg.sender
是Solidity中的全局變量,錶示調用當前函數的人或智能合約的地址。然而,該商品不會立即上架出售。
一個listItemForSale
函數,允許商品的賣家將其上架出售。我們使用require
函數來確保隻有賣家可以將商品上架出售。
一個buyItem
函數,允許其他人購買商品。該函數會就以下信息進行檢查確認:商品是否上架出售、買家不是賣家、髮送的金額正確。如果滿足這些條件,函數將曏賣家髮送款項,併將商品標記爲非出售狀態。
在完成Marketplace
合約的編寫後,下一步就是編譯和部署該合約。您可以使用Remix中的Solidity Compiler插件來編譯合約,可參考我們在第1課中所講的步驟。
要部署合約,請轉到右側麵闆上的“Deploy & Run Transactions”插件(立方體圖標)。選擇合適的環境(如用於模擬的JavaScript VM),從合約下拉列錶中選擇Marketplace
合約,然後單擊“Deploy”按鈕。
合約部署完成後,它將出現在“Deployed Contracts”闆塊中。展開該合約可以查看其公共狀態變量和函數。您可以通過調用這些函數來創建、上架和購買商品。
要創建商品,請輸入名稱和價格,然後單擊createItem
按鈕。要將商品上架出售,請輸入商品ID併單擊listItemForSale
按鈕。要購買商品,請輸入商品ID,髮送正確數量的以太幣,然後單擊buyItem
按鈕。
恭喜大家!您現在已經熟練掌握了如何在以太坊區塊鏈上創建一個基礎的去中心化市場。
在下一課中,我們將爲合約添加一些新功能,包括從出售列錶中移除商品和更新商品價格,以便對該市場進行升級。請持續關註!