Juan Cruz Martinez sẽ hướng dẫn chúng ta tạo một smart contract (hợp đồng thông minh) nhỏ để lưu trữ và truy xuất dữ liệu trên Ethereum blockchain và tạo một web app cho phép truy cập và thay đổi dữ liệu trên smart contract này.
Hãy thực hành cùng Gambaru nhé!
Đầu tiên, tôi sẽ trình bày về smart contract mà ta sẽ sử dụng để xây dựng các ứng dụng web.
Vì bài viết tập trung vào việc liên kết JavaScript với blockchain, nên tôi tạo contract càng đơn giản càng tốt:
Hợp đồng CoolNumberContract
chứa một biến trên blockchain được gọi là coolNumber
với giá trị ban đầu là 10.
Biến này là public
, nghĩa là ta có thể truy cập giá trị của nó từ blockchain mà không cần tạo hàm getter.
Ngoài ra, contract này chứa một hàm public
là setCoolNumber
, sẽ thay đổi giá trị của biến trên blockchain.
Điều quan trọng cần nhớ ở đây là bất kỳ thay đổi nào trong dữ liệu blockchain đều cần được thể hiện bằng một giao dịch.
Có nghĩa là việc gọi phương thức setCoolNumber
sẽ yêu cầu một giao dịch và giao dịch đó sẽ có phí gas đi kèm.
Hãy triển khai hợp đồng trên một test network trước khi tiếp tục.
Để tương tác với bất kỳ Ethereum blockchain nào từ JavaScript, bạn sẽ cần một library.
Trong trường hợp này, hãy sử dụng web3 https://web3js.readthedocs.io/en/v1.3.0/
Web3 sẽ cho phép tương tác với bất kỳ Ethereum network nào thông qua MetaMask hoặc provider của web3 như Ganache.
Hãy bắt đầu một project mới. Tôi sẽ sử dụng JavaScript và HTML, nhưng mọi người có thể sử dụng bất kỳ framework nào mình muốn như React hoặc Vue.
Tất cả code sẽ đi vào một file là index.html
và hãy bắt đầu với cấu trúc sau:
Hãy xem thử thẻ body
.
Đây là một giao diện người dùng đơn giản với hai button và một khoảng biểu thị trạng thái.
Cả hai button đều gọi các hàm JavaScript mà hiện tại vẫn chưa được định nghĩa.
Trên thẻ head
, thẻ quan trọng là script ta đang import. Đó là thành phần phụ thuộc vào web3.
Hãy thêm thành phần phụ thuộc này vào code như tôi đã làm hoặc nếu đang sử dụng một framework, chỉ cần import package này với:
Nếu chưa cài đặt library, bạn có thể thông qua NPM:
Cuối cùng, trước khi tiếp tục, lời khuyên là hãy cài đặt tiện ích mở rộng MetaMask.
Nếu muốn sử dụng bất kỳ provider nào khác, bạn có thể phải thay đổi các phần của code cho phù hợp, vì các sample được cung cấp sử dụng provider web3 được MetaMask đưa vào.
Khi cấu trúc cơ bản và các thành phần phụ thuộc sẵn sàng, ta có thể thêm code để kết nối ứng dụng với blockchain.
Bên trong script tag ở body, hãy thêm:
Các đoạn code trên khá đơn giản ngoại trừ hàm loadWeb3
.
Chức năng này chịu trách nhiệm thiết lập kết nối và cấp quyền tương tác với blockchain.
Để làm việc với smart contract này, ta sẽ cần một instance Web3
mới. Khi tạo instance này, cần chỉ định provider ta muốn sử dụng.
Vì đang sử dụng MetaMask làm proxy nên hãy dùng provider window.ethereum
được đưa vào bởi tiện ích mở rộng MetaMask.
Khi truy cập trình duyệt và tải trang (bằng file hoặc trình duyệt web), ta sẽ thấy luồng ủy quyền MetaMask như sau:
Hãy nhấn Next và Connect.
Đến lúc này, code đã có quyền truy cập để tương tác với blockchain.
Tạo một chức năng mới để tạo một contract instance phù hợp với giao diện contract.
Để có được một instance của bất kỳ contract nào trên blockchain, tất cả những gì chúng ta cần là: thông số ABI của contract và địa chỉ contract, cả hai đều có thể trích xuất từ Remix.
Để có thông số kỹ thuật ABI của contract, hãy đến Remix trên tab Compile. Compile và nhấp vào ABI.
Nút này sẽ sao chép thông số ABI cho contract dưới dạng một JSON array trên clipboard mà ta có thể sử dụng trực tiếp như một phần của tham số đầu tiên.
Tham số thứ hai là địa chỉ contract đã triển khai, có thể lấy từ Remix tại thời điểm triển khai hoặc Etherscan.
Code chức năng hoàn chỉnh cho contract này sẽ như sau:
Sau khi hoàn tất, ta có thể chỉ cần gọi loadContract
từ hàm loader:
Nay ta đã sẵn sàng để bắt đầu gọi các chức năng của smart contract và sẽ bắt đầu bằng cách lấy coolNumber
từ contract này.
Có thể lấy dữ liệu từ contract rất nhanh nhờ web3. Đây là một ví dụ để lấy giá trị của biến public coolNumber
:
Siêu dễ đúng không?
Sử dụng instance contract
từ phần trước, hãy lấy các phương thức và gọi một hàm với tên biến (đây là getter đã được đề cập ở phần đầu), và cuối cùng, sử dụng lệnh call
để bắt đầu yêu cầu từ xa.
Cuối cùng, cần đảm bảo rằng ta cũng có thể giao dịch với smart contract.
Do đó, hãy hiển thị một instance bằng cách truy cập hàm setter để thay đổi coolNumber
được lưu trữ trong contract.
Chức năng change sẽ chỉ định một số ngẫu nhiên mới và lưu nó trên blockchain:
Có hai điều cần chú ý:
getCurrentAccount()
hiện chưa được định nghĩa. Ta sẽ làm việc này sau. setCoolNumber
từ contract, nó trông hơi khác so với những gì đã làm cho caller:Thay vì sử dụng phương thức call
, ta đang sử dụng phương thức send
. Ta cần xác định tài khoản người gửi. Tại sao? Phải cần một giao dịch để thay đổi các giá trị trên blockchain. Như đã nói, một giao dịch yêu cầu tài khoản từ và đến phải hợp lệ – từ người khởi tạo giao dịch và trong trường hợp này, là địa chỉ của smart contract này.
Có thể sử dụng bất kỳ tài khoản nào làm từ giá trị không? Không! Đó phải là tài khoản bạn có quyền truy cập (và trong trường hợp này, tài khoản được đăng ký trên ví MetaMask của bạn), vì bạn sẽ cần ủy quyền giao dịch và xác nhận hóa đơn tiền gas.
Vấn đề đã được giải quyết, hãy xây dựng phương thức getCurrentAccount()
:
Web3 thực sự tuyệt vời. Mọi người có thể tương tác với blockchain và ví của mình, vì vậy có thể thông qua Web3 để yêu cầu thông tin về các tài khoản đã đăng ký trên ví. Trong trường hợp này, chỉ cần lấy tất cả và sử dụng tài khoản đầu tiên để thực hiện các giao dịch.
Tôi đã tải code lên GitHub gist để bạn so sánh và tham khảo. Hãy thử xây dựng dự án nhỏ nhưng thú vị này nào!
Nếu thành công, bạn hãy comment phía dưới cho Gambaru biết nhé!
Theo Juan Cruz Martinez