现在,我们将把我们基础的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
按钮。
恭喜大家!您现在已经熟练掌握了如何在以太坊区块链上创建一个基础的去中心化市场。
在下一课中,我们将为合约添加一些新功能,包括从出售列表中移除商品和更新商品价格,以便对该市场进行升级。请持续关注!