Tải bản đầy đủ (.pdf) (26 trang)

BÁO cáo môn học KIẾN TRÚC PHÁT TRIỂN HPT đề tài xây dựng marketplace trên nền tảng ethereum

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (530.54 KB, 26 trang )

ĐẠI HỌC ĐÀ NẴNG

TRƯỜNG ĐẠI HỌC BÁCH KHOA

KHOA KHOA HỌC CÔNG NGHỆ TIÊN TIẾN

BÁO CÁO MÔN HỌC
KIẾN TRÚC & PHÁT TRIỂN HPT
ĐỀ TÀI :

Xây dựng Marketplace trên nền tảng Ethereum

GVHD:
Lớp:
SVTH:

PGS. TS Nguyễn Tấn Khơi
18PFIEV3
Nhóm 4
Võ Trần Anh Khoa
Đào Thị Thúy Ngân
Kiều Thị Phượng

Đà Nẵng, tháng 12 năm 2022


MỤC LỤC
>> Chú ý: Trong mục lục chỉ nên liệt kê Heading 1, 2, 3
CHƯƠNG 1: CƠ SỞ LÝ THUYẾT
1.1. website website?
1.2. BLOCKCHAIN


1.2.1. BLOCKCHAIN
1.3. PHÁT BIỂU BÀI TOÁN
1.4. KẾT CHƯƠNG

2
3
3
3
3
3

CHƯƠNG 2: PHÂN TÍCH THIẾT KẾ HỆ THỐNG
2.1. PHÂN TÍCH HIỆN TRẠNG
2.2. PHÂN TÍCH YÊU CẦU
2.3. PHÂN TÍCH CHỨC NĂNG
2.3.1. Đối tượng sử dụng
2.3.2. Công nghệ sử dụng:
2.4. TỔ CHỨC CHƯƠNG TRÌNH
2.4.1. Tổ chức thư mục
2.4.2. Tập tin 01
2.4.3. Tập tin 02
2.4.4. Tập tin 03
2.5. KẾT CHƯƠNG

3
4
4
4
4
4

4
4
4
4
4
4

CHƯƠNG 3: TRIỂN KHAI VÀ ĐÁNH GIÁ KẾT QUẢ
3.1. MƠ HÌNH TRIỂN KHAI
3.1.1. Mơ hình triển khai
3.1.2. Cấu hình hệ thống:
3.1.2.1. Chức năng bán sản phẩm:
3.1.2.2. Chức năng mua sản phẩm:
3.1.2.3. Xây dựng trang web Marketplace: (Frontend)
3.2. KẾT QUẢ THỰC NGHIỆM
3.2.1. Khởi động hệ thống
3.2.2. Chức năng kết nối với MetaMask:
3.2.3. Kịch bản 3 – Chức năng tìm kiếm, thống kê
3.2.4. Kịch bản 4 – Chức năng truy vấn, báo cáo
3.3. NHẬN XÉT ĐÁNH GIÁ KẾT QUẢ
3.4. KẾT CHƯƠNG

4
5
5
5
5
6
7
16

16
18
18
18
18
18

1


DANH SÁCH HÌNH ẢNH
>> Canh dịng: 1.5 line

DANH SÁCH TỪ VIẾT TẮT
Từ viết tắt

Diễn giải

IP

Internet Protocol

MD5

Message-Degist Algorithm 5

SHA

Secure Hash Algorithm


API

Application Programming Interface

URL

Uniform Resource Locator

2


MỞ ĐẦU
1. Tổng quan về đề tài
Công nghệ blockchain đang đóng vai trị to lớn đến nền kinh tế tồn cầu,
thương mại điện tử cũng đang đón nhận nhiều sự chú ý trong những năm gần đây.
Hiện nay đã có hơn 22,000 cửa hàng nhỏ lẻ trên toàn thế giới cho phép khách hàng
thanh toán bằng tiền điện tử (crypto). Khi ứng dụng blockchain vào thương mại
điện tử, blockchain không chỉ tạo ra cơ hội cho doanh nghiệp rút gọn quy trình kinh
doanh, tiết kiệm chi phí mà cịn nâng cao bảo mật dữ liệu và trải nghiệm khách
hàng.
Do đó, nhóm thực hiện/ triển khai …
Phần này trình bày tổng quan, tính cấp thiết của đề tài, các vấn đề quan trọng
cần giải quyết.
2. Mục đích và ý nghĩa của đề tài
2.1. Mục đích
Đề tài này được thực hiện với mục đích xây dựng một kênh mua bán sản phẩm
trên nền tảng web và có thể thực hiện thanh tốn bằng Ethereum.
2.2. Ý nghĩa
-


Giúp bảo mật ..

3. Phương pháp thực hiện
Đồ án này xây dựng một website với:
-

Ngôn ngữ lập trình: HTML, CSS, JavaScript, Solidity

-

Thư viện hỗ trợ: Bootstrap, Web3.js, React.js

-

Framework: Truffle, Ethereum

-

Cơng cụ lập trình: Visual Studio Code

-

Cơng cụ hỗ trợ: Ganache, Node Package Manager

4. Bố cục của đồ án
1


Đồ án bao gồm các nội dung sau:
-


Mở đầu: gồm phần tổng quan về đề tài, mục đích, ý nghĩa và phương pháp
thực hiện đề tài.

-

Chương 1: trình bày nội dung cơ sở lý thuyết chính liên quan đến nội dung
của đồ án.

-

Chương 2: trình bày trình bày về phân tích và thiết kế hệ thống.

-

Chương 3: trình bày về kết quả triển khai hệ thống và các thành phần chức
năng.

-

Kết luận và hướng phát triển.

2


CHƯƠNG 1:

CƠ SỞ LÝ THUYẾT

Chương này trình bày các nội dung cơ sở lý thuyết chính liên quan đến nội

dung của đồ án. Nội dung cơ sở lý thuyết này sẽ được sử dụng trong phần phân tích
và triển khai chương trình. Phần phát biểu bài tốn sẽ mơ tả nội dung và các vấn
đề đặt ra. Ngoài ra cũng liệt kê và đánh giá các giải pháp đã có.
1.1. website website?
Hình 1.1 xxx
1.2. BLOCKCHAIN
1.2.1. Blockchain
Blockchain là một hệ thống sổ cái an toàn và bảo mật tuyệt đối giúp lưu trữ
tồn bộ thơng tin giao dịch được thực hiện tại một thời gian cụ thể.
Công nghệ blockchain giúp người dùng có thể chia sẻ và lưu trữ các tài sản số
hố, ngồi ra có thể ứng dụng để xử lý thanh tốn hay tìm kiếm sản phẩm.
1.2.2. Ethereum
Sau sự thành công của Bitcoin, một loại tiền điện tử khác cũng gây tiếng vang
trong thị trường số hiện nay là Ethereum. Ethereum cho phép mọi người xây dựng
và sử dụng các ứng dụng phi tập trung dựa trên công nghệ Blockchain. Nó là dự án
mã nguồn mở, có thể chuyển đổi và linh hoạt hơn Bitcoin.
Ethereum có các đặc điểm sau:
-

Là mạng mở;

-

Sử dụng mơ hình đồng thuận bằng chứng cơng việc;

-

Có lượng người theo dõi trên Github cao;

-


Hỗ trợ các ngôn ngữ như C++, Go và Python

1.3. PHÁT BIỂU BÀI TỐN

1.4. KẾT CHƯƠNG
Chương này trình bày ....
3


4


CHƯƠNG 2:

PHÂN TÍCH THIẾT KẾ HỆ THỐNG

Chương này trình bày về phân tích và triển khai hệ thống, bao gồm phân tích
hiện trạng, phân tích u cầu của bài tốn. Phần tiếp theo trình bày các nội dung
thiết kế hệ thống bao gồm ....
2.1. PHÂN TÍCH HIỆN TRẠNG
2.2. PHÂN TÍCH U CẦU
Hình 2.1 xxx
2.3. PHÂN TÍCH CHỨC NĂNG
2.3.1. Đối tượng sử dụng
Đối tượng sẽ sử dụng trang web s

2.3.2. Công nghệ sử dụng:

2.4. TỔ CHỨC CHƯƠNG TRÌNH

2.4.1. Tổ chức thư mục
2.4.2. Tập tin 01
2.4.3. Tập tin 02


2.4.4. Tập tin 03
2.5. KẾT CHƯƠNG
Chương này trình bày ....

5


CHƯƠNG 3:

TRIỂN KHAI VÀ ĐÁNH GIÁ KẾT QUẢ

Chương này trình bày về kết quả triển khai hệ thống, cấu hình hệ thống và các
thành phần chức năng. Kết quả được đánh giá thông qua các kịch bản thực nghiệm
khác nhau nhằm thể hiện các ưu/nhược của giải pháp đề xuất.
3.1. MƠ HÌNH TRIỂN KHAI
3.1.1. Mơ hình triển khai
3.1.2. Cấu hình hệ thống:
3.1.2.1. Chức năng bán sản phẩm:
Để tạo dựng được Marketplace thì chúng tơi cần 2 thứ cơ bản đó là người giao dịch
và sản phẩm giao dịch. Chúng tôi có tính năng đầu tiên, đó là tạo sản phẩm, tính năng này
sẽ cho phép người tạo một mặt hàng của mình để bán trên thị trường. Để làm được điều đó,
chúng tơi cần tạo mơ hình product với cấu trúc như sau:
struct Product {
uint id;
string name;

uint price;
address owner;
bool purchased;
}
Solidity cho phép bạn tạo cấu trúc dữ liệu của riêng mình, với bất kỳ thuộc tính tùy
ý nào. chúng tơi đã làm bằng cách tạo một cấu trúc Product. Nó lưu trữ tất cả các thuộc
tính của Product cần như id, name, price, owner, và purchased.
Chúng tôi tạo một hàm để tạo sản phẩm mới để thực hiện một số việc:
● Tạo một sản phẩm mới với một cấu trúc
● Thêm cấu trúc vào ánh xạ và lưu trữ trên chuỗi khối
● Kích hoạt sự kiện cho ai đó biết sản phẩm đã được tạo
function createProduct(string memory _name, uint _price) public {
// Require a valid name
require(bytes(_name).length > 0);
// Require a valid price
require(_price > 0);
// Increment product count
productCount ++;
6


// Create the product
products[productCount] = Product(productCount, _name, _price, msg.sender, false);
// Trigger an event
emit ProductCreated(productCount, _name, _price, msg.sender, false);
}
Chúng tôi thêm định nghĩa sự kiện để nó có thể được kích hoạt:
event ProductCreated(
uint id,
string name,

uint price,
address owner,
bool purchased
);
Những người khác có thể lắng nghe sự kiện này để xác minh rằng một sản phẩm đã
được tạo trên chuỗi khối.
3.1.2.2. Chức năng mua sản phẩm:
Ngoài chức năng tạo và bán sản phẩm thì chúng tơi cũng có chức năng mua sản
phẩm từ người khác với các thao tác đơn giản.
Chúng tôi sẽ thiết lập chức năng để làm điều này như sau:
function purchaseProduct(uint _id) public payable {
// Fetch the product
Product memory _product = products[_id];
// Fetch the owner
address payable _seller = _product.owner;
// Make sure the product has a valid id
require(_product.id > 0 && _product.id <= productCount);
// Require that there is enough Ether in the transaction
require(msg.value >= _product.price);
// Require that the product has not been purchased already
require(!_product.purchased);
// Require that the buyer is not the seller
require(_seller != msg.sender);
// Transfer ownership to the buyer
_product.owner = msg.sender;
// Mark as purchased
_product.purchased = true;
// Update the product
products[_id] = _product;
// Pay the seller by sending them Ether

7


address(_seller).transfer(msg.value);
// Trigger an event
emit ProductPurchased(productCount, _product.name, _product.price, msg.sender,
true);
}
Chúng tôi đã làm cho chức năng này phải trả tiền, có nghĩa là nó sẽ chấp nhận tiền
điện tử Ethereum. Bởi vì chúng tôi muốn trả tiền cho chủ sở hữu, chúng tơi phải xây dựng
cấu trúc và sự kiện hiện có để sử dụng loại địa chỉ phải trả như thế này:
struct Product {
uint id;
string name;
uint price;
address payable owner;
bool purchased;
}
event ProductCreated(
uint id,
string name,
uint price,
address payable owner,
bool purchased
);
Chúng tôi cần tạo một sự kiện mới để bán sản phẩm. Nó sẽ hoạt động gần giống
như sự kiện tạo mới Product mà chúng ta đã tạo ở mục 3.2, ta sẽ có như sau:
event ProductPurchased(
uint id,
string name,

uint price,
address payable owner,
bool purchased
);
3.1.2.3. Xây dựng trang web Marketplace: (Frontend)
3.1.2.3.1. Kết nối với ví Metamask:
Tạo một giao diện card để hiển thị các thông tin khi kết nối với ví Metamask gồm 2
thơng tin: Địa chỉ (Address) và số dư của ví (Balance).
Chúng tơi tạo hàm connectWalletHandler để kết nối với Wei của ví Metamask như
sau:
const connectWalletHandler = () => {
if (window.ethereum && window.ethereum.isMetaMask) {
window.ethereum.request({ method: 'eth_requestAccounts'})
8


.then(result => {
accountChangedHandler(result[0]);
setConnButtonText('Wallet Connected');
getAccountBalance(result[0]);
})
.catch(error => {
setErrorMessage(error.message);
});
} else {
console.log('Need to install MetaMask');
setErrorMessage('Please install MetaMask browser extension to
interact');
}
}

Chúng tôi xây dựng thêm các hàm cập nhật địa chỉ và số dư tài khoản mặc định để
nó hiển thị ở Address và Balance. Kết quả sẽ trả về cho hàm accountChangedHandler:
// update account, will cause component re-render
const accountChangedHandler = (newAccount) => {
setDefaultAccount(newAccount);
getAccountBalance(newAccount.toString());
}
const getAccountBalance = (account) => {
window.ethereum.request({method: 'eth_getBalance', params: [account,
'latest']})
.then(balance => {
setUserBalance(ethers.utils.formatEther(balance));
})
.catch(error => {
setErrorMessage(error.message);
});
};
Tuy nhiên khi thay đổi tài khoản trên ví Metamask thì dữ liệu khơng thể tự thay đổi
sang tài khoản mới nên chúng tôi đã thêm một số lệnh để có sự thay đổi trên ví thì các
thơng tin trong card sẽ tự update lại.
const chainChangedHandler = () => {
// reload the page to avoid any errors with chain change mid use of
application
window.location.reload();
}
// listen for account changes
window.ethereum.on('accountsChanged', accountChangedHandler);
window.ethereum.on('chainChanged', chainChangedHandler);
Cuối cùng là return để hiển thị toàn bộ giao diện của card:
return (

9


<div className='walletCard'>

{"Connection to MetaMask"}


onClick={connectWalletHandler}>{connButtonText}</Button>
<div className='accountDisplay'>

Address: {defaultAccount}


</div>
<div className='balanceDisplay'>

Balance: {userBalance}


</div>
{errorMessage}
</div>
);
3.1.2.3.2. Giao diện tạo sản phẩm:
Chúng tôi tạo một hàm mới sẽ được gọi bất cứ khi nào thành phần React của chúng
ta được tải. Bên trong đây, chúng ta sẽ gọi một hàm khởi tạo web3. Và tạo hàm
loadWeb3() sẽ tạo kết nối như thế này:
async componentWillMount() {
await this.loadWeb3()
}
async loadWeb3() {
if (window.ethereum) {
window.web3 = new Web3(window.ethereum)
await window.ethereum.enable()
}
else if (window.web3) {
window.web3 = new Web3(window.web3.currentProvider)

}
else {
window.alert('Non-Ethereum browser detected. You should consider trying
MetaMask!')
}
}
Chúng tôi tạo một chức năng tải dữ liệu từ chuỗi khối. Chúng tơi sẽ gọi nó đầu tiên
như thế này:
async componentWillMount() {
await this.loadWeb3()
await this.loadBlockchainData()
}
Chúng tôi đã kết nối đã lưu kết nối web3 vào một biến. Bây giờ, hãy tìm nạp các tài
khoản từ Metamask và đăng nhập chúng vào bảng điều khiển như sau:
async loadBlockchainData() {
const web3 = window.web3
10


// Load account
const accounts = await web3.eth.getAccounts()
this.setState({ account: accounts[0] })
const networkId = await web3.eth.net.getId()
const networkData = Marketplace.networks[networkId]
if(networkData) {
const marketplace = web3.eth.Contract(Marketplace.abi, networkData.address)
console.log(marketplace)
} else {
window.alert('Marketplace contract not deployed to detected network.')
}


Ở đây, chúng tôi đã kết nối với Metamask, tức là Ganache. Chúng tôi sẽ sử dụng ID
mạng này để kết nối với hợp đồng thông minh được triển khai trên mạng Ganache, thay vì
mạng Ethereum chính chẳng hạn. Tiếp theo, chúng tôi khởi tạo hợp đồng thông minh với
Web3.js bằng web3.eth.Contract(). Chúng tôi cần 2 thông tin để thực hiện việc này: hợp
đồng thông minh ABI và địa chỉ. Chúng tơi tìm nạp cả hai thứ đó từ tệp mà chúng tôi vừa
nhập. Cuối cùng, nếu chúng tôi không thể tìm thấy hợp đồng thơng minh trên mạng, chúng
tơi sẽ thơng báo cho người dùng. Bạn có thể kiểm tra điều này bằng cách chuyển sang
mạng Ethereum chính trong Metamask (đừng quên chuyển ngược lại).
Ta để hiển thị ra giao diện cuối cùng thì:
purchaseProduct(id, price) {
this.setState({ loading: true })
this.state.marketplace.methods.purchaseProduct(id).send({ from: this.state.account,
value: price })
.once('receipt', (receipt) => {
this.setState({ loading: false })
})
}
render() {
return (
<div>
<Navbar account={this.state.account} />
<div className="container-fluid mt-5">
<div className="row">
<main role="main" className="col-lg-12">
{ this.state.loading
? <div id="loader" className="text-center mt-5">

Loading...


<Button onClick={() => window.location.reload(false)}>Click to reload!
</Button>

</div>
: account={this.state.account}
11


products={this.state.products}
createProduct={this.createProduct}
purchaseProduct={this.purchaseProduct}
/>
}
</main>
</div>
</div>
</div>
);
}
3.1.2.3.3. Giao diện danh sách các sản phẩm:
Chúng tôi tạo một cách để bán sản phẩm từ trang web Marketplace. Chúng tôi sẽ
thực hiện các nhiệm vụ sau:
● Tạo một thành phần phản ứng giữ giàn giáo cho mã của chúng tôi, bao gồm một
biểu mẫu cho phép người dùng liệt kê các sản phẩm mới, một bảng hiển thị các sản
phẩm để bán và một bảng khác để hiển thị các sản phẩm thuộc sở hữu của mình.
● Chúng tôi sẽ kết nối biểu mẫu để người dùng thực sự có thể liệt kê sản phẩm của họ
để bán trên chuỗi khối.
Để thực hiện được thì chúng tơi cần thêm một số dữ liệu khác vào hàm
loadBlockchainData() của chúng tôi.
Đầu tiên, chúng tôi tạo một hàm JavaScript chấp nhận các tham số giống như chức
năng hợp đồng thông minh của chúng tơi. Sau đó, trước khi gọi chức năng hợp đồng thơng
minh, chúng tơi nói với React rằng ứng dụng của chúng tôi đang "Loading" để người dùng

biết rằng chức năng đã được gửi. Sau đó, chúng tơi gọi chức năng hợp đồng thông minh
với Web3.js với this.state.marketplace.methods.createProduct(name, price).send({ from:
this.state.account }). Thao tác này gọi hàm và cho Web3 biết rằng tài khoản hiện tại là
người dùng đang gọi nó. Cuối cùng, khi đã nhận được biên lai giao dịch, chúng tơi xóa ứng
dụng khỏi trạng thái "đang tải" để người dùng biết lệnh gọi hàm đã hoàn tất.
async loadBlockchainData() {
const web3 = window.web3
// Load account
const accounts = await web3.eth.getAccounts()
this.setState({ account: accounts[0] })
const networkId = await web3.eth.net.getId()
const networkData = Marketplace.networks[networkId]
if(networkData) {
const marketplace = web3.eth.Contract(Marketplace.abi, networkData.address)
this.setState({ marketplace })
const productCount = await marketplace.methods.productCount().call()
console.log(productCount.toString())
this.setState({ loading: false})
12


} else {
window.alert('Marketplace contract not deployed to detected network.')
}
}
Tạo một chức năng thêm sản phẩm vào chuỗi khối bằng cách gọi hàm
createProduct() với Web3.js và chúng tơt liên kết nó với thành phần bên trong hàm tạo như
sau:
createProduct(name, price) {
this.setState({ loading: true })

this.state.marketplace.methods.createProduct(name, price).send({ from:
this.state.account })
.once('receipt', (receipt) => {
this.setState({ loading: false })
})
constructor(props) {
// ...
this.createProduct = this.createProduct.bind(this)
}
Thành phần này bổ sung khung cho giao diện người dùng Marketplace. Nó cũng
tạo ra một biểu mẫu sẽ thêm sản phẩm vào chuỗi khối bằng cách gọi hàm createProduct().
render() {
return (
<div id="content" style={{marginTop: '15px'}}>
<Row className='text-center'>
style={{ marginLeft: '15px', marginRight: '4rem' }}
className="col mb-2 text-center"
>
<WalletCard/>
</Card>
<div className="col mb-2">

Add Product


<Form onSubmit={(event) => {
event.preventDefault()
const name = this.productName.value
const price = window.web3.utils.toWei(this.productPrice.value.toString(),
'Ether')
this.props.createProduct(name, price)
}}>

<div className="form-group mr-sm-2">
id="productName"
type="text"
ref={(input) => { this.productName = input }}
className="form-control"
13


placeholder="Product Name"
required />
</div>
<InputGroup className="form-group mr-sm-2 mb-2">
id="productPrice"
type="text"
ref={(input) => { this.productPrice = input }}
className="form-control"
placeholder="Product Price"
required
/>
<InputGroup.Text>Ether</InputGroup.Text>
</InputGroup>
<button type="submit" className="btn btn-primary">Add Product</button>
</Form>

 


</div>
</Row>
<div style={{marginTop: '15px'}}>

Buy Product



striped bordered hover
variant="dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Owner</th>
<th scope="col">Buy</th>
</tr>
</thead>
<tbody id="productList">
{ this.props.products.map((product, key) => {
if(!(product.owner === this.props.account)){
return(
<tr key={key}>
<th scope="row">{product.id.toString()}</th>
<td>{product.name}</td>
<td>{window.web3.utils.fromWei(product.price.toString(), 'Ether')}
Eth</td>
<td>{product.owner}</td>
<td>
name={product.id}
value={product.price}
onClick={(event) => {
this.props.purchaseProduct(event.target.name, event.target.value)
14



}}
>
Buy
</button>
</td>
</tr>
)
}
else{
return null
}
})}
</tbody>
</Table>
</div>
<div style={{marginTop: '15px'}}>

Owner Product


striped bordered hover
variant="dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Owner</th>
</tr>
</thead>
<tbody id="productList">

{ this.props.products.map((product, key) => {
if (product.owner === this.props.account) {
return(
<tr key={key}>
<th scope="row">{product.id.toString()}</th>
<td>{product.name}</td>
<td>{window.web3.utils.fromWei(product.price.toString(), 'Ether')}
Eth</td>
<td>{product.owner}</td>
</tr>
)
}
else{
return null
}
})}
</tbody>
</Table>
</div>
</div>
15


);
}
Để sử dụng thành phần này thì ta cần khai báo trong App.js và thêm đoạn HTML
để thực thi:
<main role="main" className="col-lg-12 d-flex">
{ this.state.loading
? <div id="loader" className="text-center">

Loading...

</div>

: <Main createProduct={this.createProduct} />
}
</main>
Chúng tôi cho phép người dùng mua sản phẩm trên thị trường. Chúng ta sẽ làm hai
việc trong phần này:
● Liệt kê tất cả các sản phẩm trên trang
● Cho phép người dùng mua sản phẩm được đăng bán chỉ bằng một nút bấm
Chúng tôi sử dụng bộ đệm bộ đếm mà chúng tôi đã tạo bên trong hợp đồng thông
minh để xác định có bao nhiêu sản phẩm tồn tại, sau đó chúng tơi sử dụng vịng lặp for để
tìm nạp từng sản phẩm riêng lẻ và lưu trữ nó vào đối tượng trạng thái phản ứng. Với thông
tin này, chúng tơi có thể hiển thị các sản phẩm trên trang trong giây lát.
const productCount = await marketplace.methods.productCount().call()
this.setState({ productCount })
// Load products
for (var i = 1; i <= productCount; i++) {
const product = await marketplace.methods.products(i).call()
this.setState({
products: [...this.state.products, product]
})
}
Chúng tôi tạo chức năng mua sản phẩm và liên kết hàm bên trong hàm tạo:
purchaseProduct(id, price) {
this.setState({ loading: true })
this.state.marketplace.methods.purchaseProduct(id).send({ from: this.state.account,
value: price })
.once('receipt', (receipt) => {
this.setState({ loading: false })
})
}
constructor(props) {

// ...
this.createProduct = this.createProduct.bind(this)
this.purchaseProduct = this.purchaseProduct.bind(this)
}
16


Chúng tôi chuyển hai props mới xuống Main component:
● Tất cả các sản phẩm có thể được liệt kê trên trang
● Hàm buyProduct() để nó có thể được gọi trong thành phần phụ
Chúng tơi sẽ cập nhật mã của mình để nó trơng để:
● Lặp lại tất cả các sản phẩm và tạo các hàng bảng duy nhất cho từng sản phẩm
● Thêm một nút để có thể mua sản phẩm chỉ bằng một cú nhấp chuột, gọi hàm
buyProduct() mà chúng ta vừa tạo.
<main role="main" className="col-lg-12 d-flex">
{ this.state.loading
? <div id="loader" className="text-center">

Loading...

</div>
: products={this.state.products}
createProduct={this.createProduct}
purchaseProduct={this.purchaseProduct} />
}
</main>

3.2. KẾT QUẢ THỰC NGHIỆM
3.2.1. Khởi động hệ thống
Đầu tiên, ta cần khởi động Ganache kích hoạt Workspaces của Marketplace:

17



Sau đó ta chạy lệnh “npm start” để khởi động localhost:3000 hiển thị giao diện
của Marketplace.

18


3.2.2. Chức năng kết nối với ví MetaMask

Click vào button Connect Wallet để kết nối:

19


3.2.3. Chức năng tạo mới sản phẩm để bán:

Điền thông tin sản phẩm trong mục Add Product:
Product Name: tên của sản phẩm muốn bán
Product Price: giá của sản phẩm muốn bán, tính

-

3.2.4. Kịch bản 4 – Chức năng truy vấn, báo cáo
….

3.3. NHẬN XÉT ĐÁNH GIÁ KẾT QUẢ
Qua kết quả thực nghiệm, tác giả có những nhận xét như sau:


Vấn đề XXX




Vấn đề YYY

Thống kê kết quả bằng bảng, đồ thị....
3.4. KẾT CHƯƠNG
Chương này trình bày ....

KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
1. KẾT QUẢ ĐẠT ĐƯỢC

Trong thời gian tìm hiểu, nghiên cứu cơ sở lý thuyết và triển khai ứng dụng
công nghệ, đồ án đã đạt được những kết quả sau:
Về mặt lý thuyết, đồ án đã đạt được …
20


Về mặt thực tiễn ứng dụng, đồ án đã đạt được …
Kết quả đóng góp của đồ án được thể hiện như sau (trình bày các đoạn có
đánh số ngắn gọn sắp xếp theo mức độ quan trọng giảm dần). Cần làm rõ những nội
dung kế thừa, những nội dung mà tác giả đóng góp trong luận văn.


Phát triển một thuật toán nhanh hơn nhiều cho vấn đề xxx



Xây dựng được XYZ. Chứng tỏ được XXX




Xác định được YYY

Tuy nhiên, vẫn còn tồn tại các vấn đề như sau:


Vấn đề XXX



Vấn đề YYY

2. KIẾN NGHỊ VÀ HƯỚNG PHÁT TRIỂN

Một số số hướng nghiên cứu và phát triển của đề tài như sau:


Bổ sung và hoàn thiện một số chức năng của hệ thống …



Đánh giá hiệu năng trên các môi trường khác nhau …



Kiểm thử các chức năng của chương trình …




Bổ sung các giải pháp bảo mật và an toàn cho hệ thống …



….

TÀI LIỆU THAM KHẢO
Tiếng Việt

[1] Đặng Văn Đức (2001), Hệ thống thông tin địa lý, Nhà xuất bản Khoa học và Kỹ
Thuật Hà Nội.

21


[2] Phạm Hữu Đức (2005), Cơ sở dữ liệu và hệ thống thông tin địa lý GIS, Nhà
xuất bản Xây dựng.
Tiếng Anh

[3] Senthil Shanmugan (2004). “Digital urban management programme Evolution of Bangalore GIS model”, Proceedings of the third International
Conference on Environment and Health, India.

[4] Teemu Nuortio, Harri Niska (2003), “Improved route planning and scheduling
of waste collection and transport”, Department of Environmental Sciences,
University of Kuopio, Finland.
Internet

[5] />[6] http:// www.mapreduce.org

22



×