Bài viết này không nói về tiền điện tử hay tài chính phi tập trung. Thay vào đó, chúng ta sẽ khám phá blockchain EVM công khai và cách chúng có thể được sử dụng trong dự án tiếp theo của bạn, tùy thuộc vào nhu cầu và mục tiêu cụ thể của bạn. Tôi sẽ đi sâu vào ưu, nhược điểm và ví dụ thực tế, sử dụng thư viện 0xweb mà tôi đang làm việc.
Nó đã được thiết lập và chạy. Chỉ cần định nghĩa mô hình dữ liệu của bạn dưới dạng hợp đồng và triển khai nó.
Sau khi dữ liệu của bạn được tải lên, nó vẫn có thể truy cập được miễn là blockchain vẫn hoạt động. Tôi có thể cho rằng nó sẽ lâu hơn nhiều so với đăng ký lưu trữ khác của bạn.
Việc tách biệt các quy trình đọc và ghi trong blockchain đảm bảo thời gian hoạt động 100% cho các hoạt động đọc, đặc biệt là khi tận dụng nhiều nhà cung cấp RPC để dự phòng.
Blockchain vốn cung cấp mức độ bảo mật cao hơn các giải pháp lưu trữ thông thường. Việc khai thác dữ liệu chỉ có thể xảy ra nếu có lỗ hổng trong logic của mô hình dữ liệu của bạn.
Trừ khi được mã hóa, dữ liệu của bạn vẫn luôn mở, có thể truy cập và xác minh được bởi bất kỳ ai, giúp tăng cường tính minh bạch.
Tên miền không cần thiết cho loại backend này. Thay vào đó, có thể sử dụng danh sách các nhà cung cấp nút phi tập trung, cho phép thư viện máy khách lựa chọn tùy chọn hiệu quả nhất cho người dùng cuối.
Nhờ các tính năng trên, các hệ thống phụ trợ dựa trên blockchain có thể xây dựng lòng tin của người dùng bằng cách đảm bảo an ninh dữ liệu và khả dụng 24/7, ngay cả khi việc bảo trì và phát triển dự án dừng lại.
Bạn có thể tích hợp các mô hình dữ liệu khác được lưu trữ trên blockchain hoặc các dự án khác có thể xây dựng dựa trên mô hình dữ liệu của bạn.
Người dùng có thể tận dụng nhiều dự án của bên thứ ba để giám sát hoặc tự động hóa các hành động, mở rộng đáng kể khả năng của mô hình dữ liệu của bạn.
Có thể truy cập dữ liệu từ bất kỳ thời điểm nào trong quá khứ.
Tải các sự kiện tùy chỉnh trong lịch sử hoặc sử dụng WebSockets để lắng nghe các sự kiện đến theo thời gian thực, cho phép phản hồi ứng dụng động.
Khái niệm “ví” cho phép người dùng xác thực bản thân bằng cách ký tin nhắn, cung cấp khả năng nhận dạng người dùng liền mạch và phi tập trung.
Người dùng có thể sửa đổi hoặc mở rộng dữ liệu trong bộ lưu trữ của bạn dựa trên các quyền mà bạn xác định. Điều quan trọng là chi phí cho những sửa đổi này do chính người dùng chi trả. Bằng cách lựa chọn một blockchain chi phí thấp, các khoản phí này có thể không đáng kể, thường chỉ lên tới vài xu cho mỗi giao dịch.
Mặc dù nó tuân theo mô hình trả tiền khi sử dụng thực sự, bạn chỉ trả tiền cho các SLOT mà bạn lưu trữ. Mỗi SLOT có 32 byte, tốn 20000 GAS để ghi dữ liệu mới hoặc 5000 GAS để cập nhật dữ liệu. Hãy lấy Polygon làm ví dụ, với giá GAS 30 gwei và giá POL 0,60 đô la.
20000GAS × 30gwei = 0,008 POL × 0,60 đô la = 0,00032 đô la
Đây là một con số lớn, vì vậy biểu tượng cảm xúc “Đĩa mềm“ thể hiện số lượng lưu trữ theo cách tốt nhất, nghĩa là nó phù hợp nhất với các tập dữ liệu nhỏ hơn nếu bạn tự trả tiền. Tuy nhiên, một lợi thế độc đáo là người dùng có thể tự chi trả chi phí lưu trữ và hành động của mình, một tính năng không có trong các công nghệ khác. Mặc dù cách tiếp cận này có thể cản trở việc áp dụng rộng rãi ứng dụng của bạn, nhưng nó được chấp nhận rộng rãi trong cộng đồng blockchain.
Các mô hình dữ liệu Blockchain hỗ trợ các chức năng tương tác với dữ liệu, nhưng khả năng tính toán của chúng có những hạn chế. Những hạn chế này phụ thuộc vào các nút RPC mà bạn sử dụng cho các hành động đọc và các giới hạn GAS nghiêm ngặt áp dụng cho các hành động ghi (giao dịch). Trong khi các hoạt động cơ bản, vòng lặp và ngăn xếp cuộc gọi sâu hơn thường có thể quản lý được, thì blockchain không phù hợp với khối lượng công việc tính toán nặng.
Tuy nhiên, xét đến kích thước dữ liệu thường tương đối nhỏ, các giới hạn hiện tại thường đủ cho hầu hết các trường hợp sử dụng.
Nếu bạn mới tham gia phát triển blockchain, bạn có thể đã nghe nói rằng nó phức tạp và khó để bắt đầu. Tuy nhiên, điều này không đúng. Phát triển blockchain sử dụng các khái niệm, ngữ nghĩa và cú pháp quen thuộc, giúp việc học dễ dàng hơn bạn nghĩ.
https://github.com/0xweb-org/examples-backend
Đối với bài viết này, chúng ta hãy tạo một hợp đồng quản lý phiên bản ứng dụng. Hãy tưởng tượng bạn có một ứng dụng máy tính để bàn yêu cầu một backend để kiểm tra các phiên bản mới và lấy liên kết tải xuống bất cứ khi nào một phiên bản mới được phát hành. Dưới đây là hợp đồng cuối cùng, trình bày hầu hết các khái niệm chính:
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; struct Package { uint version; uint timestamp; string url; bytes32 sha256; } contract AppVersionManager is Ownable { // Events that are emitted on data updates event NewApplicationInfo(); event NewPackage(uint version, uint timestamp); // Custom error, when title for the application is empty error TitleIsEmpty(); // Some application information string public title; // @TODO: add further application related properties if required // Latest package Package public package; // Track all versions and their packages mapping (uint => Package) public packages; // List of all previous versions uint[] public versions; constructor () Ownable(msg.sender) { } function updateInfo(string calldata newTitle) external onlyOwner { if (bytes(newTitle).length == 0) { revert TitleIsEmpty(); } title = newTitle; emit NewApplicationInfo(); } function updatePackage(Package calldata newPackage) external onlyOwner { require(newPackage.version > package.version, "Newer package already published"); packages[package.version] = package; package = newPackage; versions.push(package.version); emit NewPackage(package.version, block.timestamp); } function findPackageAtTimestamp (uint timestamp) external view returns (Package memory) { if (package.timestamp <= timestamp) { return package; } // the countdown loop to find the latest package for the timestamp int i = int(versions.length); while (--i > -1) { Package memory pkg = packages[versions[uint(i)]]; if (pkg.timestamp <= timestamp) { return pkg; } } revert("No package found"); } function getPackage (uint version) external view returns (Package memory) { if (version == package.version) { return package; } return packages[version]; } }
Mọi nhà phát triển đều có thể đọc và hiểu mã này với nỗ lực tối thiểu. Nếu bạn quen thuộc với TypeScript, hầu hết các khái niệm ở đây sẽ có ý nghĩa. Để làm cho nó rõ ràng hơn nữa, tôi đã tạo một ví dụ TypeScript tương đương: AppVersionManager.ts 🔗 .
Nói một cách đơn giản, một hợp đồng trong Solidity có thể được coi là một thể hiện lớp có trạng thái . Các khái niệm về thuộc tính, phương thức, kiểu và kế thừa đã được biết đến rộng rãi trong lập trình hướng đối tượng. Khái niệm chính cần giải thích ở đây là trình sửa đổi onlyOwner
(tương tự như trình trang trí trong TypeScript).
Mỗi tài khoản blockchain về cơ bản là một cặp khóa riêng tư và công khai. ID của tài khoản, được gọi là địa chỉ , được lấy từ khóa công khai. Khi giao dịch được thực hiện, địa chỉ của người gửi được truyền dưới dạng msg.sender
. Sử dụng điều này, chúng ta có thể lưu trữ địa chỉ của bạn trong trình xây dựng (trong quá trình triển khai hợp đồng). Sau đó, trình sửa đổi onlyOwner
đảm bảo rằng chỉ bạn, với tư cách là chủ sở hữu hợp đồng, mới có thể thực thi các hàm updateInfo
và updatePackage
. Nếu người khác cố gắng thực hiện các hành động này, giao dịch sẽ bị hoàn nguyên. Trình sửa đổi onlyOwner
được cung cấp bởi hợp đồng Ownable
, là một phần của thư viện OpenZeppelin được sử dụng rộng rãi. Thư viện này bao gồm nhiều hợp đồng hữu ích khác để hợp lý hóa quá trình phát triển blockchain.
Một chủ đề quan trọng khác cần thảo luận là khái niệm Proxy , chia lưu trữ và triển khai thành hai hợp đồng riêng biệt. Triển khai hợp đồng trong Solidity là bất biến, nghĩa là bạn không thể thêm các chức năng hoặc thuộc tính mới sau khi triển khai. Để giải quyết vấn đề này, bạn có thể triển khai hợp đồng "Proxy". Proxy xử lý lưu trữ và chỉ chứa một hàm fallback
, hàm này chuyển giao các lệnh gọi đến hợp đồng triển khai trong khi vẫn duy trì ngữ cảnh lưu trữ của Proxy.
Khái niệm này nghe có vẻ phức tạp, nhưng nó tương tự như cách this
hoạt động trong JavaScript. Sau đây là một phép so sánh nhanh để giúp làm rõ:
const foo = new Proxy({ bar: 'Lorem' }, { get (obj, prop) { return fooImplementation[prop].bind(obj) }, }); const fooImplementation = { logValue () { console.log('Bar value:', this.bar) } } foo.logValue();
Hợp đồng proxy giữ tham chiếu đến hợp đồng triển khai. Nếu bạn muốn thêm các hàm mới, bạn chỉ cần triển khai một hợp đồng triển khai mới và cập nhật proxy để tham chiếu đến hợp đồng mới này, chuyển tiếp các lệnh gọi hàm đến phiên bản đã cập nhật. Đây là một quy trình đơn giản, nhưng có một trường hợp ngoại lệ cần xem xét: các hàm tạo.
Khi triển khai hợp đồng triển khai, hàm tạo của nó hoạt động trong bộ lưu trữ của chính hợp đồng triển khai. Điều này có nghĩa là các trình thiết lập như title = "Hello World"
sẽ không sửa đổi bộ lưu trữ của proxy. Để giải quyết vấn đề này, chúng tôi sử dụng khái niệm hàm khởi tạo :
initialize
.initialize
được gọi trong ngữ cảnh của hợp đồng proxy.
Do đó, việc cập nhật thuộc tính title
chẳng hạn sẽ cập nhật chính xác thuộc tính đó trong bộ lưu trữ của proxy.
Sau đây là phiên bản nâng cấp của AppVersionManager của chúng tôi: AppVersionManagerUpgradeable.sol .
Bản thân hợp đồng proxy khá phổ biến và độc lập với việc triển khai. Một số tiêu chuẩn nổi tiếng cho proxy có sẵn trong thư viện OpenZeppelin.
Với kiến thức về các khái niệm này và các ví dụ trên, bạn đã sẵn sàng phát triển hợp đồng thông minh cho các trường hợp kinh doanh của mình.
Đầu tiên, chúng ta cần chọn blockchain mà chúng ta muốn triển khai hợp đồng của mình. Đối với ví dụ này, tôi đã chọn Polygon. Nó cung cấp chi phí giao dịch thấp, đã tồn tại trong một thời gian dài và luôn hoạt động tốt. Cơ sở hạ tầng ổn định và hiệu quả của nó, kết hợp với Tổng giá trị bị khóa (TVL) là 0,9 tỷ đô la, khiến nó trở thành một lựa chọn đáng tin cậy. Triển khai hợp đồng của bạn lên blockchain công khai có nghĩa là cùng tồn tại với các tổ chức tài chính. Chỉ số TVL phản ánh sự tin tưởng mà các tổ chức này đặt vào độ tin cậy của blockchain.
Hơn nữa, nếu điều kiện thay đổi, bạn luôn có thể triển khai lại hợp đồng sang một blockchain khác trong tương lai.
Dự án demo cũng đóng vai trò là kho lưu trữ thử nghiệm CI, do đó, tất cả các lệnh có thể được tìm thấy tại đây: https://github.com/0xweb-org/examples-backend/blob/master/deploy-cli.sh
# Install 0xweb library from NPM into the prject folder npm i 0xweb # Install required dependencies to compile/deploy *.sol files npx 0xweb init --hardhat --openzeppelin # Create or import the account. Private key will be encrypted with pin AND machine key. npx 0xweb accounts new --name foo --pin test --login # Save the private key securly and ensure the account has some POL tokens # Deploy. The foo account is selected as default. npx 0xweb deploy ./contracts/AppVersionManager.sol --chain polygon --pin test # Set title npx 0xweb c write AppVersionManager updateInfo --newTitle MySuperApp --pin test # Set latest package information npx 0xweb c write AppVersionManager updatePackage --arg0 'load(./data/package.json)' --pin test
Chỉ với một vài lệnh, bạn đã triển khai hợp đồng và cập nhật dữ liệu. Vậy là xong phần backend—giờ đây nó đã hoạt động "mãi mãi" mà không cần bất kỳ hành động nào khác từ phía bạn. Chi phí cho lần triển khai này, với giá GAS là 70 gwei và giá POL là 0,51 đô la, sẽ là:
| KHÍ | POL | $ |
---|---|---|---|
Triển khai | 850352 | 0,059 | 0,03 |
Lưu Tiêu đề | 47517 | 0,0033 | 0,001 |
Lưu dữ liệu gói | 169549 | 0,0118 | 0,006 |
Tổng cộng | | | 0,037 |
Bạn chỉ mất 4 xu để thiết lập một dịch vụ phi tập trung , an toàn và hoạt động lâu dài mà không cần bảo trì .
Để truy vấn dữ liệu hợp đồng của bạn, bạn sẽ cần các nhà cung cấp nút RPC. Có hàng chục nhà cung cấp miễn phí tại https://chainlist.org . Bạn có thể chọn nhiều nhà cung cấp và một thư viện Web3 tốt có thể sử dụng chiến lược vòng tròn khi chạy để chọn nhà cung cấp hiệu quả nhất cho người dùng cuối của bạn. Với 0xweb, các lớp TypeScript hoặc JavaScript được tạo ra không chỉ chọn các điểm cuối tốt nhất mà còn trừu tượng hóa mọi giao tiếp blockchain. Các máy khách chứa các phương thức cấp cao để truy xuất dữ liệu, giúp quá trình này liền mạch và hiệu quả.
# The deploy command also generates the class, but manual install is also possible npx 0xweb i 0x<address> --name AppVersionManager --chain polygon
import { AppVersionManager } from './0xc/polygon/AppVersionManager/AppVersionManager' const manager = new AppVersionManager(); console.log(`Title`, await manager.title()); console.log(`Package`, await manager.package());
Đối với các ngôn ngữ lập trình khác, có nhiều thư viện có sẵn để đơn giản hóa việc truy vấn blockchain. Sau khi triển khai, bạn sẽ có địa chỉ hợp đồng và ABI (giao diện).
Ngoài ra, bạn có thể khởi chạy máy chủ trung gian để truy vấn dữ liệu hợp đồng bằng 0xweb.
npx 0xweb server start --port 3000 curl http://localhost:3000/api/c/read/AppVersionManager/package?chain=polygon
Một lợi thế là bạn không cần phải đưa bất kỳ thư viện nào vào ứng dụng của mình - các yêu cầu HTTP thô. Tuy nhiên, cách tiếp cận này dựa vào một máy chủ bổ sung mà bạn sẽ cần quản lý. Thường thì tốt hơn là truy vấn blockchain trực tiếp bằng các lớp do 0xweb tạo ra hoặc các thư viện blockchain khác có sẵn.
Bài viết này giới thiệu cách blockchain vừa đơn giản vừa mạnh mẽ, mang lại những lợi thế độc đáo so với các giải pháp lưu trữ truyền thống.
Trong bài viết tiếp theo, tôi dự định khám phá các mạng lưu trữ BLOB phi tập trung như Greenfield và Arweave, đồng thời nêu bật các tính năng và lợi ích của chúng.
Nếu bạn có bất kỳ đề xuất hoặc ý tưởng nào về các tính năng bổ sung để đưa vào thư viện 0xweb, vui lòng chia sẻ trong phần bình luận hoặc liên hệ trực tiếp qua địa chỉ [email protected] .