Giới thiệu Truffle Suite: Bộ công cụ nguồn mở để phát triển DApps
1. Truffle Suite
1.1 Truffle Suite là gì
- Truffle Suite là một bộ công cụ được tạo ra để phục vụ cho việc phát triền các ứng dụng phi tập trung (DApps) trên mạng Ethereum
- Truffle Suite đóng gói các module và công cụ cần thiết để viết, biên dịch, kiểm thử và triển khai hợp đồng thông minh (smart contract) trên mạng Ethereum
1.2 Truffle Suite cung cấp cho các develop những gì
Truffle:
Truffle là framework để phát triển ứng dụng phi tập trung trên Ethereum. Các chức năng bao gồm:
- Cung cấp compiler, linker cho các hợp đồng thông minh (viết bằng solidity) và công cụ để quản lý và triển khai mã nhị phân.
- Kiểm thử tự động với thư viện Mocha và Chai.
- Cấu hình build pipeline.
- Viết kịch bản migration và deploy.
- Hỗ trợ triển khai trên các mạng public và private.
- Hỗ trợ tương tác trực tiếp với hợp đồng thông minh.
- Hỗ trợ tự động rebuild trong quá trình phát triển (chức năng tương tự hot-reloading).
- Hỗ trợ chạy các script để thực thi script trong môi trường phát triển truffle.
Ganache
Ganache là công cụ cho phép thiết lập một Blockchain Ethereum cá nhân để kiểm trử các hợp đồng Solidity
Drizzle Framework
Drizzle là một Javascript framework giúp chúng ta xây dựng front-end cho một Dapp một cách dễ dàng hơn. Nó được phát hành bởi đội ngũ của Truffle framework vào đầu năm 2018.
Các chức năng chính của Drizzle bao gồm:
- Kết nối blockchain Ethereum với Web3
- Duy trì trạng thái state storing nội bộ là kết quả của chức năng gọi đến state của smart contract. State này được lưu trữ trong một redux store, phía client. Drizzle sẽ giữ cho trạng thái này được cập nhật, mà ta không cần phải làm gì cả.
- Chuyển tiếp các giao dịch đến smart contract (ghi dữ liệu)
Thành phần chính của Drizzle bao gồm:
- Drizzle là thư viện logic cốt lõi của Drizzle dựa trên store của
Redux
. Vì vậy bạn có thể truy cập vào các công cụ phát triển tuyệt với củaRedux
- Drizzle-react cho phép dễ dàng tích hợp Drizzle vào ứng dụng React của bạn. Nó cung cấp một Provider component cấp bậc cao hơn, bao bọc các thành phần khác của bạn và chuyển cho chúng xuống state của Drizzle.
- Drizzle-react-components cung cấp một số react components sẵn sàng sử dụng cho các ứng dụng của bạn, chẳng hạn như components display accounts, component read data smart contract và components recording data.
2. Thiết lập môi trường
2.1. Cài đặt các requirements
- NodeJS: version 8 trở lên
- Git
2.2. Cài đặt truffle
Truffle được tích hợp sẵn trong package manager của nodejs, ta có thể cài đặt trực tiếp thông qua công cụ npm bằng dòng lệnh sau:
npm install -g truffle
Sau khi cài đặt truffle, ta có thể xác nhận là truffle đã cài đặt thành công bằng lệnh sau
truffle version
Nếu truffle được cài đặt thành công, lệnh trên sẽ trả về thông tin của phiên bản đã được cài đặt
Truffle v5.4.27 (core: 5.4.27)
Solidity v0.5.16 (solc-js)
Node v15.14.0
Web3.js v1.5.3
2.3. Cài đặt Ganache
Ganache cung cấp 2 phiên bản độc lập là Ganache GUI hỗ trợ giao diện đồ hoạ và Ganache CLI hỗ trợ giao diện dòng lệnh
Ganache GUI
Ganache GUI được cung cấp tại địa chỉ sau:
https://trufflesuite.com/ganache/
Ganache GUI được phát triển bằng nền tảng electron, hỗ trợ cho các hệ điều hành phổ biến như linux, mac, windows.
Ganache CLI
Ganache CLI được tích hợp trong package manager của nodejs, có thể được cài đặt thông qua npm:
npm install -g ganache-cli3. Khởi tạo dự án truffle
Dự án truffle có thể được khởi tạo trong một thư mục rỗng hoặc bên trong một dự án front end (react, vue...) khác
Dự án truffle có thể được khởi tạo bằng 2 cách
3.1. Tạo mới dự án truffle trống
Dự án truffle trống có thể được tạo ra bằng dòng lệnh sau
truffle init
Sau khi dự an truffle trống được tạo ra, sẽ có sẵn một số thư mục theo cấu trúc sau
- contracts/
-
- Chứa các solidity script để định nghĩa các contract
-
- migrations/
-
- Chứa các script (javacscript) để deploy (migrate) các smart contract được build
- test/
- Thư mục chứa các script test (javascript)
- truffle-config.js
- Chứa thông tin cấu hình của dự án truffle
3.2. Unbox dự án truffle từ các box có sẵn
Truffle cung cấc các box chứa sẵn các project truffle được tạo sẵn cho nhiều mục đích khác nhau.
Thông tin về các truffle box được đăng lên địa chỉ sau:
https://trufflesuite.com/boxes/index.html
Truffle box là cách nhanh nhất để tạo ra một dapp theo nhu cầu của người phát triển.
Truffle box có thể tải về bằng câu lệnh sau:
truffle unbox [tên_box]
VD: để tạo dự án từ box metacoin, ta gọi lệnh sau: truffle unbox metacoin
Sau khi một truffle box được unbox, cấu trúc của nó sẽ khác nhau phụ thuộc vào mục đích của box đó, nhưng sẽ có các file và thư mục như dự án truffle trống.
4. Cấu hình dự án truffle
Để chỉnh sửa cấu hình cho dự án truffle, ta sẽ cần chỉnh sửa các thông tin được định nghĩa trong truffle-config.js trong thư mục gốc của dự án.
Khi dự án truffle được khởi tạo bởi <code>truffle init</code>, file truffle-config.js cũng được tạo ra và chữa sẵn các mẫu cấu hình có sẵn dưới dạng bị comment. Ta ó thể tận dụng những cấu hình này vả sửa lại cho phù hợp với môi trường của hệ thống.
Để dự án có thể compile và deploy contract, cần phải settings 2 thông tin sau:
- networks: định nghĩa cho mạng blockchain được sử dụng để deploy/migrate
- compilers: định nghĩa compiler cho dự án, truffle được tích hợp sẵn compiler là solc và định nghĩa sẵn trong file config
4.1. Cấu hình networks
Để có thể deploy/migrate các contract, ta cần cấu hình networks để truffle biết được cần kết nối đến network nào để deploy và test.
Ta có thể khai báo nhiều network cho các mục đích khác nhau, mỗi network là một object với key là tên của network đó. Khi gọi các lệnh của truffle, ta có thể dùng tuỳ chọn --network để cung cấp cho truffle thông tin về network được sử dụng. Nếu không có tuỳ chọn --network, truffle sẽ mặc định sử dụng network là development.
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*", // match any network
websockets: true
},
live: {
host: "178.25.19.88", // Random IP for example purposes (do not use)
port: 80,
network_id: 1, // Ethereum public network
// optional config values:
// gas -
// gasPrice - use gas and gasPrice if creating type 0 transactions
// maxFeePerGas -
// maxPriorityFeePerGas - use maxFeePerGas and maxPriorityFeePerGas if creating type 2 transactions (https://eips.ethereum.org/EIPS/eip-1559)
// from - default address to use for any transaction Truffle makes during migrations
// provider - web3 provider instance Truffle should use to talk to the Ethereum network.
// - function that returns a web3 provider instance (see below.)
// - if specified, host and port are ignored.
// skipDryRun: - true if you don't want to test run the migration locally before the actual migration (default is false)
// confirmations: - number of confirmations to wait between deployments (default: 0)
// timeoutBlocks: - if a transaction is not mined, keep waiting for this number of blocks (default is 50)
// deploymentPollingInterval: - duration between checks for completion of deployment transactions
// disableConfirmationListener: - true to disable web3's confirmation listener
}
}
Các thông tin được sử dụng để cấu hình network:
- gas
- Số lượng gas tối đa được sử dụng để deploym giá trị mặc định là 6721975
- gasPrice
- Giá gas được sử dụng để deploy, giá trị mặc định là 20000000000 (20 Gwei)
- from
- Địa chỉ được sử dụng để migrate. Giá trị mặc định là địa chỉ đầu tiên được cấp bởi mạng ethereum
- host
- Địa chỉ ip của bên cung cấp web3
- port
- Cổng sử dụng để liên lạc với bên cung cấp web3
- provider
- Khai báo bên cung cấp web3 thay cho host và port,cú pháp khai báo như sau:
new Web3.providers.HttpProvider("http://:")
- websockets
- deploymentPollingInterval
5. Viết Smart Contract
Các smart contract được viết bằng các solidity script có phần mở rộng là *.sol trong thư mục contracts của dự án. Khi khởi tạo dự án, truffle tạo sẵn một contract là Migrations trong file Migrations.sol. Nếu không dùng đến, ta có thể xoá contract này đi.
Để tạo một contract mới, ta có thể tạo một file .sol trong thư mục contracts và định nghĩa contract ở trong đó. Hoặc có thể dùng truffle cli để tạo contract bằng lệnh sau:
truffle create contract [Tên contract]
6. Compile Smart Contract
Để compile contract, ta dùng lệnh sau:
truffle compile
Sau khi chạy lệnh này chúng ta sẽ ra tạo ra một file build/contracts. Thư mục này chứa các file json chưa thông tin tóm tắt của smart contract:
- Contract name
- ABI (danh sách tất cả các hàm cùng với các giá trị tham số và giá trị trả về của chúng)
- Bytecode
- Deployed bytecode
- Compiler name và phiên bản của nó
- Danh sách các networks mà hợp đồng được deploy
- Địa chỉ của contract đối với từng mạng mà contract được deploy
Migrate Smart Contract
Để có thể deploy smart contract lên blockchain, chúng ta cần tạo ra các migrations script. Đây là các file javascript được chưa trong thư mục migrations.
Cũng như contracts, lệnh truffle init tạo sẵn migration script cho contract Migrations được tự động tạo bởi truffle trước đó trong file 1_initial_migration.js. Ta cũng có thể xoá migration này tương tự với contract Migrations.
Để tạo một migration mới, ta có thể tạo một file .js trong thư mục migrations. Chú ý là các migrations được chạy theo thứ tự alphabet của tên file migration nên thường có tiền tố là một chứ sỗ thể hiện thứ tự của nó.
Ngoài ra ta cũng có thể sử dụng truffle cli để tạo migration theo cú pháp sau
truffle create migration [tên migration]
Tên file migration do trufle tự động tạo ra thường có dạng timestamp_[tên miration dưới dạng snake case].js
Sau khi có script migration, ta có thể deploy contract lên mạng blockchain bằng lệnh sau
truffle migrate
Nếu migrate thành công, truffle sẽ trả về các thông tin contract được deploy lên blockchain
Starting migrations...
======================
> Network name: 'development'
> Network id: 5777
> Block gas limit: 6721975 (0x6691b7)
1_initial_migration.js
======================
Deploying 'Migrations'
----------------------
> transaction hash: 0xeac3f94d72fbba05e6b874a631fe523a9259aa1d45553e2ee3e02b179d783414
> Blocks: 0 Seconds: 0
> contract address: 0xf8cdC23739E16a1c4341C8Be8341a570Cb7718B2
> block number: 23
> block timestamp: 1641811844
> account: 0x97b104a7A0629565911dB6976EC0A4290FbF790d
> balance: 810000000000000.62460206
> gas used: 248854 (0x3cc16)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00497708 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.00497708 ETH
Summary
=======
> Total deployments: 1
> Final cost: 0.00497708 ETH