ตอนนี้เราจะเปลี่ยนสัญญา Item
ธรรมดาของเราให้เป็นสัญญา Marketplace
ที่ซับซ้อนมากขึ้น สัญญา Marketplace
จะเก็บรักษารายการสินค้าที่จะขาย จัดเตรียมช่องทางให้ผู้ใช้สามารถลงรายการสินค้าใหม่เพื่อขาย และจัดเตรียมช่องทางให้ผู้ใช้สามารถซื้อสินค้าได้
เพื่อดำเนินการนี้ เราจะเพิ่มคุณสมบัติใหม่บางประการให้กับสัญญาของเรา:
ตอนนี้แต่ละรายการจะมีที่อยู่ seller
ซึ่งเป็นตัวแทนของเจ้าของสินค้า
เราจะแนะนำฟังก์ชั่นใหม่ listItemForSale
ที่ให้ผู้ใช้สามารถแสดงรายการสินค้าใหม่เพื่อขาย
เราจะแนะนำฟังก์ชัน buyItem
ใหม่ที่ช่วยให้ผู้ใช้สามารถซื้อสินค้าได้
Marketplace
มีลักษณะดังนี้:ความแข็งแกร่ง
// SPDX-License-Identifier: ความแข็งแกร่งของ MIT
pragma ^0.8.6;
สัญญาตลาด {
// กำหนดโครงสร้างใหม่สำหรับรายการ
โครงสร้างรายการ {
string name;
uint price;
address payable seller;
bool forSale;
}
// อาร์เรย์เพื่อเก็บรายการทั้งหมด
รายการ[] รายการสาธารณะ;
// เหตุการณ์ที่จะถูกส่งเมื่อมีการสร้างรายการใหม่
เหตุการณ์ NewItem(uint itemId, string itemName, uint itemPrice, ที่อยู่ผู้ขาย);
// เหตุการณ์ที่จะถูกส่งออกมาเมื่อมีการขายสินค้า
เหตุการณ์ ItemListed(uint itemId, string itemName, uint itemPrice, address vendor);
// เหตุการณ์ที่จะถูกส่งออกมาเมื่อมีการซื้อสินค้า
เหตุการณ์ ItemBought(uint itemId, string itemName, uint itemPrice, ที่อยู่ผู้ขาย, ที่อยู่ผู้ซื้อ);
// ฟังก์ชั่นสร้างรายการใหม่แต่ไม่ลงรายการขายทันที
ฟังก์ชั่น 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);
}
// ฟังก์ชั่นแสดงรายการสินค้าเพื่อขาย
ฟังก์ชั่น 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);
}
// ฟังก์ชั่นซื้อสินค้า
ฟังก์ชั่น buyItem(uint _itemId) เจ้าหนี้สาธารณะ {
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
แล้ว ขั้นตอนต่อไปคือการคอมไพล์และปรับใช้ คุณสามารถใช้ปลั๊กอิน Solidity Compiler ใน Remix เพื่อคอมไพล์สัญญาได้ เช่นเดียวกับที่เราทำในบทที่ 1
หากต้องการปรับใช้สัญญา ให้ไปที่ปลั๊กอิน Deploy & Run Transactions (อันที่มีไอคอนคิวบ์) บนแผงด้านขวา เลือกสภาพแวดล้อมที่เหมาะสม (JavaScript VM สำหรับการจำลอง) เลือกสัญญา Marketplace
จากดรอปดาวน์สัญญา แล้วคลิกปุ่มปรับใช้
เมื่อปรับใช้สัญญาแล้ว สัญญาจะปรากฏใต้ส่วนสัญญาที่ปรับใช้ คุณสามารถขยายเพื่อดูตัวแปรและฟังก์ชันสถานะสาธารณะได้ คุณสามารถสร้าง แสดงรายการ และซื้อสินค้าได้โดยการเรียกใช้ฟังก์ชันเหล่านี้
หากต้องการสร้างรายการ ให้ป้อนชื่อและราคา แล้วคลิกปุ่ม createItem
หากต้องการลงรายการขาย ให้ป้อนรหัสรายการแล้วคลิกปุ่ม listItemForSale
หากต้องการซื้อไอเท็ม ให้ป้อน ID ไอเท็ม ส่ง Ether ในปริมาณที่ถูกต้อง แล้วคลิกปุ่ม buyItem
ยินดีด้วย! ตอนนี้คุณรู้วิธีสร้างตลาดกระจายอำนาจพื้นฐานบนบล็อกเชน Ethereum แล้ว
ในบทเรียนถัดไป เราจะปรับปรุงตลาดของเราโดยการเพิ่มฟังก์ชันในการลบสินค้าออกจากการขายและการอัปเดตราคาของสินค้า คอยติดตาม!
ตอนนี้เราจะเปลี่ยนสัญญา Item
ธรรมดาของเราให้เป็นสัญญา Marketplace
ที่ซับซ้อนมากขึ้น สัญญา Marketplace
จะเก็บรักษารายการสินค้าที่จะขาย จัดเตรียมช่องทางให้ผู้ใช้สามารถลงรายการสินค้าใหม่เพื่อขาย และจัดเตรียมช่องทางให้ผู้ใช้สามารถซื้อสินค้าได้
เพื่อดำเนินการนี้ เราจะเพิ่มคุณสมบัติใหม่บางประการให้กับสัญญาของเรา:
ตอนนี้แต่ละรายการจะมีที่อยู่ seller
ซึ่งเป็นตัวแทนของเจ้าของสินค้า
เราจะแนะนำฟังก์ชั่นใหม่ listItemForSale
ที่ให้ผู้ใช้สามารถแสดงรายการสินค้าใหม่เพื่อขาย
เราจะแนะนำฟังก์ชัน buyItem
ใหม่ที่ช่วยให้ผู้ใช้สามารถซื้อสินค้าได้
Marketplace
มีลักษณะดังนี้:ความแข็งแกร่ง
// SPDX-License-Identifier: ความแข็งแกร่งของ MIT
pragma ^0.8.6;
สัญญาตลาด {
// กำหนดโครงสร้างใหม่สำหรับรายการ
โครงสร้างรายการ {
string name;
uint price;
address payable seller;
bool forSale;
}
// อาร์เรย์เพื่อเก็บรายการทั้งหมด
รายการ[] รายการสาธารณะ;
// เหตุการณ์ที่จะถูกส่งเมื่อมีการสร้างรายการใหม่
เหตุการณ์ NewItem(uint itemId, string itemName, uint itemPrice, ที่อยู่ผู้ขาย);
// เหตุการณ์ที่จะถูกส่งออกมาเมื่อมีการขายสินค้า
เหตุการณ์ ItemListed(uint itemId, string itemName, uint itemPrice, address vendor);
// เหตุการณ์ที่จะถูกส่งออกมาเมื่อมีการซื้อสินค้า
เหตุการณ์ ItemBought(uint itemId, string itemName, uint itemPrice, ที่อยู่ผู้ขาย, ที่อยู่ผู้ซื้อ);
// ฟังก์ชั่นสร้างรายการใหม่แต่ไม่ลงรายการขายทันที
ฟังก์ชั่น 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);
}
// ฟังก์ชั่นแสดงรายการสินค้าเพื่อขาย
ฟังก์ชั่น 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);
}
// ฟังก์ชั่นซื้อสินค้า
ฟังก์ชั่น buyItem(uint _itemId) เจ้าหนี้สาธารณะ {
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
แล้ว ขั้นตอนต่อไปคือการคอมไพล์และปรับใช้ คุณสามารถใช้ปลั๊กอิน Solidity Compiler ใน Remix เพื่อคอมไพล์สัญญาได้ เช่นเดียวกับที่เราทำในบทที่ 1
หากต้องการปรับใช้สัญญา ให้ไปที่ปลั๊กอิน Deploy & Run Transactions (อันที่มีไอคอนคิวบ์) บนแผงด้านขวา เลือกสภาพแวดล้อมที่เหมาะสม (JavaScript VM สำหรับการจำลอง) เลือกสัญญา Marketplace
จากดรอปดาวน์สัญญา แล้วคลิกปุ่มปรับใช้
เมื่อปรับใช้สัญญาแล้ว สัญญาจะปรากฏใต้ส่วนสัญญาที่ปรับใช้ คุณสามารถขยายเพื่อดูตัวแปรและฟังก์ชันสถานะสาธารณะได้ คุณสามารถสร้าง แสดงรายการ และซื้อสินค้าได้โดยการเรียกใช้ฟังก์ชันเหล่านี้
หากต้องการสร้างรายการ ให้ป้อนชื่อและราคา แล้วคลิกปุ่ม createItem
หากต้องการลงรายการขาย ให้ป้อนรหัสรายการแล้วคลิกปุ่ม listItemForSale
หากต้องการซื้อไอเท็ม ให้ป้อน ID ไอเท็ม ส่ง Ether ในปริมาณที่ถูกต้อง แล้วคลิกปุ่ม buyItem
ยินดีด้วย! ตอนนี้คุณรู้วิธีสร้างตลาดกระจายอำนาจพื้นฐานบนบล็อกเชน Ethereum แล้ว
ในบทเรียนถัดไป เราจะปรับปรุงตลาดของเราโดยการเพิ่มฟังก์ชันในการลบสินค้าออกจากการขายและการอัปเดตราคาของสินค้า คอยติดตาม!