Phiên bản 2 của trình biên dịch Cairo giới thiệu các thay đổi đối với cú pháp Starknet để làm cho mã rõ ràng và an toàn hơn. Giao diện công khai của hợp đồng thông minh được xác định bằng cách sử dụng các đặc điểm và quyền truy cập vào bộ lưu trữ được thực hiện thông qua đặc điểm ContractState. Các phương thức riêng tư phải được xác định với cách triển khai khác với giao diện chung. Các sự kiện hiện được định nghĩa là enums, trong đó mỗi biến thể là một cấu trúc có cùng tên.
Tuyên bố miễn trừ trách nhiệm: Các thuật ngữ được sử dụng ở đây đề cập đến các phiên bản khác nhau của trình biên dịch Cairo và cú pháp là tạm thời vì cộng đồng Starknet vẫn đang tranh luận đâu là thuật ngữ tốt nhất để sử dụng. Sau khi xác định, bài viết này sẽ được cập nhật cho phù hợp.
Trình biên dịch v2
Mới tuần trước, một phiên bản chính mới 2.0.0-rc0 của trình biên dịch Cairo đã được phát hành trên Github. Trình biên dịch mới cung cấp những cải tiến đáng kể cho plugin Starknet, giúp mã của chúng tôi an toàn hơn, rõ ràng hơn và có thể tái sử dụng nhiều hơn. Lưu ý rằng phiên bản mới này của trình biên dịch chưa được hỗ trợ trên Starknet testnet hoặc mainnet vì nó vẫn đang được phát triển trong môi trường tích hợp.
Mục tiêu của bài viết này là chỉ cho bạn cách viết lại hợp đồng thông minh Starknet được tạo cho trình biên dịch Cairo phiên bản 1.x thành một hợp đồng thông minh tương thích với trình biên dịch phiên bản 2.x. Điểm xuất phát của chúng ta là hợp đồng thông minh Ownable được tạo trong bài viết trước, hợp đồng này tương thích với trình biên dịch Cario phiên bản 1.x.
[contract] mod Có thể sở hữu {dùng starknet::ContractAddress;dùng starknet::get_caller_address;
[event] fn Quyền sở hữu được chuyển giao(trước_chủ sở hữu: Địa chỉ hợp đồng, mới_chủ sở hữu: Địa chỉ hợp đồng) {}
lưu trữ cấu trúc {chủ sở hữu: ContractAddress,}
[constructor] fn constructor() {hãy triển khai = get_caller_address();owner::write(deployer);}
fn only_owner() { let caller = get_caller_address();assert(caller == owner::read(), 'Người gọi không phải là chủ sở hữu');
Thiết lập dự án
Vì Protostar chưa hỗ trợ trình biên dịch v2 nên bài viết này sẽ dựa vào bản phát hành trước Scarb (phiên bản 0.5.0-alpha.1) hỗ trợ nó. Để cài đặt phiên bản Scarb cụ thể đó, bạn có thể sử dụng lệnh sau.
Sau khi thiết lập hoàn tất, chúng ta có thể truy cập src/lib.cairo và bắt đầu viết hợp đồng thông minh.
Lưu trữ và xây dựng
Trong phiên bản 2 của trình biên dịch Cairo, hợp đồng thông minh vẫn được xác định bởi các mô-đun được chú thích bằng thuộc tính hợp đồng, chỉ là lần này thuộc tính được đặt tên theo plugin xác định nó, trong trường hợp này là starknet.
#[starknet::contract]mod Có thể sở hữu {}
Bộ nhớ trong vẫn được định nghĩa là một cấu trúc phải được gọi là Bộ nhớ, chỉ lần này nó phải được chú thích bằng thuộc tính lưu trữ.
#[starknet::contract]mod Có thể sở hữu { sử dụng super::ContractAddress; # [storage] lưu trữ cấu trúc {chủ sở hữu: ContractAddress,
Để định nghĩa hàm tạo, chúng ta chú thích hàm bằng thuộc tính hàm tạo, giống như chúng ta đã làm trong v1, ưu điểm là bây giờ hàm có thể có bất kỳ tên nào, nó không cần phải gọi là "hàm tạo" như trong v1. Mặc dù không bắt buộc, nhưng tôi vẫn gọi hàm này là "hàm tạo" ngoài quy ước, nhưng bạn có thể gọi nó theo cách khác.
Một thay đổi quan trọng khác là bây giờ hàm tạo sẽ tự động chuyển một tham chiếu đến ContractState, đóng vai trò trung gian để lưu trữ các biến, trong trường hợp này là "chủ sở hữu".
#[starknet::contract]mod Có thể sở hữu { sử dụng super::ContractAddress; # [storage] lưu trữ cấu trúc {chủ sở hữu: ContractAddress,} # [constructor] fn constructor(ref self: ContractState) {let Deployer = get_caller_address();self.owner.write(deployer);
Lưu ý rằng cú pháp ghi và đọc bộ nhớ đã thay đổi kể từ v1. Trước đây chúng tôi đã làm chủ sở hữu::write(), bây giờ chúng tôi làm self.owner.write(). Điều tương tự cũng áp dụng cho việc đọc từ bộ nhớ.
Nhân tiện, loại ContractState không cần phải được đưa vào phạm vi theo cách thủ công, nó được bao gồm trong khúc dạo đầu.
Phương thức công khai
Một điểm khác biệt quan trọng so với phiên bản 1 của trình biên dịch Cairo là bây giờ chúng ta cần xác định rõ ràng giao diện công khai của hợp đồng thông minh bằng cách sử dụng các đặc điểm được chú thích bằng thuộc tính starknet::interface.
Nếu bạn nhớ mã ban đầu từ phiên bản 1, hợp đồng thông minh của chúng tôi có hai phương thức "công khai" (nhận_chủ sở hữu và chuyển giao quyền sở hữu) và một phương thức "riêng tư" (chỉ_chủ sở hữu). Tính năng này chỉ xử lý các phương thức công khai và không dựa vào các thuộc tính "bên ngoài" hoặc "chế độ xem" để chỉ ra phương thức nào có thể sửa đổi trạng thái của hợp đồng và phương thức nào không thể. Thay vào đó, điều này hiện được làm rõ bằng loại tham số self.
Nếu một phương thức yêu cầu tham chiếu đến ContractStorage (mà sau khi được triển khai, T chung sẽ thực hiện), thì phương thức đó có thể sửa đổi trạng thái bên trong của hợp đồng thông minh. Đây là những gì chúng tôi thường gọi là một phương pháp "bên ngoài". Mặt khác, nếu một phương thức yêu cầu ảnh chụp nhanh của ContractStorage, thì phương thức đó chỉ có thể đọc chứ không thể sửa đổi nó. Đây là những gì chúng tôi thường gọi là phương pháp "xem".
Bây giờ chúng ta có thể tạo triển khai cho đặc điểm mà chúng ta vừa xác định bằng cách sử dụng từ khóa impl. Hãy nhớ rằng, Cairo khác với Rust ở chỗ việc triển khai có tên.
fn get_owner(self: @ContractState) -> Địa chỉ hợp đồng { self.owner.read() }
Chúng tôi tạo triển khai cho đặc điểm của mình bên trong mô-đun xác định hợp đồng thông minh, chuyển loại Hợp đồng trạng thái dưới dạng loại T chung để có thể truy cập bộ lưu trữ như một hàm tạo.
Việc triển khai của chúng tôi được chú thích bằng thuộc tính bên ngoài (v0). Phiên bản 0 trong thuộc tính có nghĩa là bộ chọn chỉ được lấy từ tên phương thức, như trường hợp trước đây. Nhược điểm là nếu bạn xác định một triển khai khác của một đặc điểm khác cho hợp đồng thông minh của mình và hai đặc điểm tình cờ sử dụng cùng một tên cho một trong các phương thức của chúng, thì trình biên dịch sẽ đưa ra lỗi do bộ chọn trùng lặp.
Phiên bản tương lai của thuộc tính này có thể thêm một cách mới để đánh giá các bộ chọn nhằm tránh xung đột, nhưng cách đó chưa hoạt động. Hiện tại, chúng tôi chỉ có thể sử dụng phiên bản 0 của các thuộc tính bên ngoài.
Phương pháp Riêng tư
Chúng tôi cũng cần xác định một phương thức khác cho hợp đồng thông minh, chỉ_owner. Phương pháp này kiểm tra xem người gọi nó có phải là chủ sở hữu của hợp đồng thông minh hay không.
Bởi vì đây là một phương thức riêng tư không được phép gọi từ bên ngoài, nên nó không thể được định nghĩa là một phần của OwnableTrait (giao diện công khai của hợp đồng thông minh). Thay vào đó, chúng ta sẽ sử dụng thuộc tính generate_trait để tạo một triển khai mới cho đặc điểm được tạo tự động.
...#[starknet::contract]mod Ownable { ... #[generate_trait] impl PrivateMethods of PrivateMethodsTrait { fn only_owner(self: @ContractState) { let caller = get_caller_address(); khẳng định (người gọi == self.owner.read(), 'Người gọi không phải là chủ sở hữu'); }
Phương thức only_owner hiện có thể được sử dụng bằng cách gọi self.only_owner() khi cần.
Ở Cairo v1, một sự kiện chỉ là một hàm không có phần thân và được chú thích bằng thuộc tính sự kiện, trong khi ở phiên bản 2, một sự kiện là một enum được chú thích bằng cùng một thuộc tính, nhưng hiện được triển khai bằng cách sử dụng một số tính năng bổ sung.
...#[starknet::contract]mod Có thể sở hữu { ... # [event] #[derive(Drop, starknet::Event)] enum Sự kiện { OwnershipTransferred: OwnershipTransferred, }
#[derive(Drop, starknet::Event)] struct Quyền sở hữu được chuyển { # [key] trước_chủ sở hữu: Địa chỉ hợp đồng, # [key] mới_chủ sở hữu: Địa chỉ hợp đồng,
Mỗi biến thể của sự kiện enum phải là một cấu trúc có cùng tên. Trong cấu trúc này, chúng tôi sử dụng thuộc tính khóa tùy chọn để xác định tất cả các giá trị chúng tôi muốn phát ra, để thông báo cho hệ thống những giá trị nào chúng tôi muốn Starknet lập chỉ mục, để người lập chỉ mục có thể tìm kiếm và truy xuất nhanh hơn. Trong trường hợp này, chúng tôi muốn lập chỉ mục hai giá trị (prev_owner và new_owner).
Đặc điểm Hợp đồng xác định một phương thức phát ra có thể được sử dụng để phát ra các sự kiện.
Với tính năng cuối cùng này, chúng tôi đã hoàn thành quá trình di chuyển hợp đồng thông minh Có thể sở hữu từ v1 sang v2. Mã đầy đủ được hiển thị bên dưới.
#[starknet::contract]mod Có thể sở hữu { sử dụng super::ContractAddress; sử dụng starknet::get_caller_address;
[event] #[derive(Drop, starknet::Event)] enum Sự kiện { OwnershipTransferred: OwnershipTransferred, }
#[derive(Drop, starknet::Event)] struct Quyền sở hữu được chuyển { # [key] trước_chủ sở hữu: Địa chỉ hợp đồng, # [key] mới_chủ sở hữu: Địa chỉ hợp đồng, }
[storage] Lưu trữ cấu trúc { chủ sở hữu: Địa chỉ hợp đồng, }
[constructor] fn constructor(ref self: ContractState) { let Deployer = get_caller_address(); self.owner.write(người triển khai); }
fn get_owner(self: @ContractState) -> Địa chỉ hợp đồng { self.owner.read() } }
#[generate_trait] impl PrivateMethods của PrivateMethodsTrait { fn only_owner(self: @ContractState) { let caller = get_caller_address(); khẳng định (người gọi == self.owner.read(), 'Người gọi không phải là chủ sở hữu'); }
Bạn cũng có thể tìm mã này trên Github.
Tóm lại là
Phiên bản 2 của trình biên dịch Cairo mang đến một cú pháp mới cho Starknet, làm cho mã hợp đồng thông minh trông nhất quán hơn với chính Cairo và bằng cách mở rộng giống với Rust hơn. Ngay cả khi phải trả giá bằng mã rườm rà hơn, các lợi ích bảo mật vẫn đáng để đánh đổi.
Trong bài viết này, chúng tôi chưa đề cập đến mọi thứ về cú pháp mới, đặc biệt là cách nó tương tác với các hợp đồng thông minh khác, nhưng bạn có thể đọc nhật ký thay đổi của trình biên dịch, đọc bài đăng này trên diễn đàn hoặc xem video trên kênh YouTube của StarkWare để tìm hiểu thêm về nó.để biết thêm thông tin.
Phiên bản mới này của trình biên dịch sẽ có sẵn trên mạng thử nghiệm của Starknet sau vài tuần nữa và mạng chính sau vài tuần nữa, vì vậy đừng cố triển khai mã này ngay, nó sẽ chưa hoạt động.
Cairo chỉ tiếp tục trở nên tốt hơn.
nguồn
Cú pháp hợp đồng - Hướng dẫn di chuyển
Cairo 1: cú pháp hợp đồng đang phát triển
Xem bản gốc
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
Diễn giải đầy đủ ngữ pháp cải tiến của Starknet
Bản gốc: Cú pháp Starknet được cải tiến
Dịch và hiệu đính: "Starknet Chinese Community"
Tổng quan
Phiên bản 2 của trình biên dịch Cairo giới thiệu các thay đổi đối với cú pháp Starknet để làm cho mã rõ ràng và an toàn hơn. Giao diện công khai của hợp đồng thông minh được xác định bằng cách sử dụng các đặc điểm và quyền truy cập vào bộ lưu trữ được thực hiện thông qua đặc điểm ContractState. Các phương thức riêng tư phải được xác định với cách triển khai khác với giao diện chung. Các sự kiện hiện được định nghĩa là enums, trong đó mỗi biến thể là một cấu trúc có cùng tên.
Tuyên bố miễn trừ trách nhiệm: Các thuật ngữ được sử dụng ở đây đề cập đến các phiên bản khác nhau của trình biên dịch Cairo và cú pháp là tạm thời vì cộng đồng Starknet vẫn đang tranh luận đâu là thuật ngữ tốt nhất để sử dụng. Sau khi xác định, bài viết này sẽ được cập nhật cho phù hợp.
Trình biên dịch v2
Mới tuần trước, một phiên bản chính mới 2.0.0-rc0 của trình biên dịch Cairo đã được phát hành trên Github. Trình biên dịch mới cung cấp những cải tiến đáng kể cho plugin Starknet, giúp mã của chúng tôi an toàn hơn, rõ ràng hơn và có thể tái sử dụng nhiều hơn. Lưu ý rằng phiên bản mới này của trình biên dịch chưa được hỗ trợ trên Starknet testnet hoặc mainnet vì nó vẫn đang được phát triển trong môi trường tích hợp.
Mục tiêu của bài viết này là chỉ cho bạn cách viết lại hợp đồng thông minh Starknet được tạo cho trình biên dịch Cairo phiên bản 1.x thành một hợp đồng thông minh tương thích với trình biên dịch phiên bản 2.x. Điểm xuất phát của chúng ta là hợp đồng thông minh Ownable được tạo trong bài viết trước, hợp đồng này tương thích với trình biên dịch Cario phiên bản 1.x.
[contract] mod Có thể sở hữu {dùng starknet::ContractAddress;dùng starknet::get_caller_address;
[event] fn Quyền sở hữu được chuyển giao(trước_chủ sở hữu: Địa chỉ hợp đồng, mới_chủ sở hữu: Địa chỉ hợp đồng) {}
lưu trữ cấu trúc {chủ sở hữu: ContractAddress,}
[constructor] fn constructor() {hãy triển khai = get_caller_address();owner::write(deployer);}
[view] fn get_owner() -> ContractAddress {chủ sở hữu::read()}
[external] fn transfer_ownership(new_owner: ContractAddress) {chỉ_owner();let previous_owner = owner::read();owner::write(new_owner);Quyền sở hữu được chuyển(previous_owner, new_owner) ;}
fn only_owner() { let caller = get_caller_address();assert(caller == owner::read(), 'Người gọi không phải là chủ sở hữu');
Thiết lập dự án
Vì Protostar chưa hỗ trợ trình biên dịch v2 nên bài viết này sẽ dựa vào bản phát hành trước Scarb (phiên bản 0.5.0-alpha.1) hỗ trợ nó. Để cài đặt phiên bản Scarb cụ thể đó, bạn có thể sử dụng lệnh sau.
$ --proto '=https' --tlsv1.2 -sSf | bash -s -- -v 0.5.0-alpha.1
Sau khi cài đặt hoàn tất, hãy xác minh rằng bạn có phiên bản chính xác.
$ Scarb --version>>>Scarb 0.5.0-alpha.1 (546dad33d 2023-06-19)cairo:2.0.0-rc3()
Bây giờ có thể tạo một dự án Scarb.
$ sẹo mới cairo1_v2$cdcairo1_v2
Bạn sẽ nhận được một cấu trúc thư mục như dưới đây.
cây $.>>>.├── Scarb.toml└── src└──lib.cairo
Để Scarb biên dịch các hợp đồng thông minh của Starknet, plugin Starknet cần được bật dưới dạng phần phụ thuộc.
// Sẹo.toml... [dependencies] starknet="2.0.0-rc3"
Sau khi thiết lập hoàn tất, chúng ta có thể truy cập src/lib.cairo và bắt đầu viết hợp đồng thông minh.
Lưu trữ và xây dựng
Trong phiên bản 2 của trình biên dịch Cairo, hợp đồng thông minh vẫn được xác định bởi các mô-đun được chú thích bằng thuộc tính hợp đồng, chỉ là lần này thuộc tính được đặt tên theo plugin xác định nó, trong trường hợp này là starknet.
#[starknet::contract]mod Có thể sở hữu {}
Bộ nhớ trong vẫn được định nghĩa là một cấu trúc phải được gọi là Bộ nhớ, chỉ lần này nó phải được chú thích bằng thuộc tính lưu trữ.
#[starknet::contract]mod Có thể sở hữu { sử dụng super::ContractAddress; # [storage] lưu trữ cấu trúc {chủ sở hữu: ContractAddress,
Để định nghĩa hàm tạo, chúng ta chú thích hàm bằng thuộc tính hàm tạo, giống như chúng ta đã làm trong v1, ưu điểm là bây giờ hàm có thể có bất kỳ tên nào, nó không cần phải gọi là "hàm tạo" như trong v1. Mặc dù không bắt buộc, nhưng tôi vẫn gọi hàm này là "hàm tạo" ngoài quy ước, nhưng bạn có thể gọi nó theo cách khác.
Một thay đổi quan trọng khác là bây giờ hàm tạo sẽ tự động chuyển một tham chiếu đến ContractState, đóng vai trò trung gian để lưu trữ các biến, trong trường hợp này là "chủ sở hữu".
#[starknet::contract]mod Có thể sở hữu { sử dụng super::ContractAddress; # [storage] lưu trữ cấu trúc {chủ sở hữu: ContractAddress,} # [constructor] fn constructor(ref self: ContractState) {let Deployer = get_caller_address();self.owner.write(deployer);
Lưu ý rằng cú pháp ghi và đọc bộ nhớ đã thay đổi kể từ v1. Trước đây chúng tôi đã làm chủ sở hữu::write(), bây giờ chúng tôi làm self.owner.write(). Điều tương tự cũng áp dụng cho việc đọc từ bộ nhớ.
Nhân tiện, loại ContractState không cần phải được đưa vào phạm vi theo cách thủ công, nó được bao gồm trong khúc dạo đầu.
Phương thức công khai
Một điểm khác biệt quan trọng so với phiên bản 1 của trình biên dịch Cairo là bây giờ chúng ta cần xác định rõ ràng giao diện công khai của hợp đồng thông minh bằng cách sử dụng các đặc điểm được chú thích bằng thuộc tính starknet::interface.
sử dụng starknet::ContractAddress;
#[starknet::interface]trait OwnableTrait { fn transfer_ownership(ref self: T, new_owner: ContractAddress); fn get_owner(self: @T) -> ContractAddress;}
#[starknet::contract]mod Có thể sở hữu { ...}
Nếu bạn nhớ mã ban đầu từ phiên bản 1, hợp đồng thông minh của chúng tôi có hai phương thức "công khai" (nhận_chủ sở hữu và chuyển giao quyền sở hữu) và một phương thức "riêng tư" (chỉ_chủ sở hữu). Tính năng này chỉ xử lý các phương thức công khai và không dựa vào các thuộc tính "bên ngoài" hoặc "chế độ xem" để chỉ ra phương thức nào có thể sửa đổi trạng thái của hợp đồng và phương thức nào không thể. Thay vào đó, điều này hiện được làm rõ bằng loại tham số self.
Nếu một phương thức yêu cầu tham chiếu đến ContractStorage (mà sau khi được triển khai, T chung sẽ thực hiện), thì phương thức đó có thể sửa đổi trạng thái bên trong của hợp đồng thông minh. Đây là những gì chúng tôi thường gọi là một phương pháp "bên ngoài". Mặt khác, nếu một phương thức yêu cầu ảnh chụp nhanh của ContractStorage, thì phương thức đó chỉ có thể đọc chứ không thể sửa đổi nó. Đây là những gì chúng tôi thường gọi là phương pháp "xem".
Bây giờ chúng ta có thể tạo triển khai cho đặc điểm mà chúng ta vừa xác định bằng cách sử dụng từ khóa impl. Hãy nhớ rằng, Cairo khác với Rust ở chỗ việc triển khai có tên.
sử dụng starknet::ContractAddress;
#[starknet::interface]trait OwnableTrait { fn transfer_ownership(ref self: T, new_owner: ContractAddress); fn get_owner(self: @T) -> ContractAddress;}
#[starknet::contract]mod Ownable { ... #[external(v0)] impl OwnableImpl of super::OwnableTrait { fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { let prev_owner = self.owner.read(); self.owner.write(new_owner); }
fn get_owner(self: @ContractState) -> Địa chỉ hợp đồng { self.owner.read() }
Chúng tôi tạo triển khai cho đặc điểm của mình bên trong mô-đun xác định hợp đồng thông minh, chuyển loại Hợp đồng trạng thái dưới dạng loại T chung để có thể truy cập bộ lưu trữ như một hàm tạo.
Việc triển khai của chúng tôi được chú thích bằng thuộc tính bên ngoài (v0). Phiên bản 0 trong thuộc tính có nghĩa là bộ chọn chỉ được lấy từ tên phương thức, như trường hợp trước đây. Nhược điểm là nếu bạn xác định một triển khai khác của một đặc điểm khác cho hợp đồng thông minh của mình và hai đặc điểm tình cờ sử dụng cùng một tên cho một trong các phương thức của chúng, thì trình biên dịch sẽ đưa ra lỗi do bộ chọn trùng lặp.
Phiên bản tương lai của thuộc tính này có thể thêm một cách mới để đánh giá các bộ chọn nhằm tránh xung đột, nhưng cách đó chưa hoạt động. Hiện tại, chúng tôi chỉ có thể sử dụng phiên bản 0 của các thuộc tính bên ngoài.
Phương pháp Riêng tư
Chúng tôi cũng cần xác định một phương thức khác cho hợp đồng thông minh, chỉ_owner. Phương pháp này kiểm tra xem người gọi nó có phải là chủ sở hữu của hợp đồng thông minh hay không.
Bởi vì đây là một phương thức riêng tư không được phép gọi từ bên ngoài, nên nó không thể được định nghĩa là một phần của OwnableTrait (giao diện công khai của hợp đồng thông minh). Thay vào đó, chúng ta sẽ sử dụng thuộc tính generate_trait để tạo một triển khai mới cho đặc điểm được tạo tự động.
...#[starknet::contract]mod Ownable { ... #[generate_trait] impl PrivateMethods of PrivateMethodsTrait { fn only_owner(self: @ContractState) { let caller = get_caller_address(); khẳng định (người gọi == self.owner.read(), 'Người gọi không phải là chủ sở hữu'); }
Phương thức only_owner hiện có thể được sử dụng bằng cách gọi self.only_owner() khi cần.
#[starknet::contract]mod Ownable { ... #[external(v0)] impl OwnableImpl of super::OwnableTrait { fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { self.only_owner (); ... } ... }
#[generate_trait] impl PrivateMethods của PrivateMethodsTrait { fn only_owner(self: @ContractState) { ... }
sự kiện
Ở Cairo v1, một sự kiện chỉ là một hàm không có phần thân và được chú thích bằng thuộc tính sự kiện, trong khi ở phiên bản 2, một sự kiện là một enum được chú thích bằng cùng một thuộc tính, nhưng hiện được triển khai bằng cách sử dụng một số tính năng bổ sung.
...#[starknet::contract]mod Có thể sở hữu { ... # [event] #[derive(Drop, starknet::Event)] enum Sự kiện { OwnershipTransferred: OwnershipTransferred, }
#[derive(Drop, starknet::Event)] struct Quyền sở hữu được chuyển { # [key] trước_chủ sở hữu: Địa chỉ hợp đồng, # [key] mới_chủ sở hữu: Địa chỉ hợp đồng,
Mỗi biến thể của sự kiện enum phải là một cấu trúc có cùng tên. Trong cấu trúc này, chúng tôi sử dụng thuộc tính khóa tùy chọn để xác định tất cả các giá trị chúng tôi muốn phát ra, để thông báo cho hệ thống những giá trị nào chúng tôi muốn Starknet lập chỉ mục, để người lập chỉ mục có thể tìm kiếm và truy xuất nhanh hơn. Trong trường hợp này, chúng tôi muốn lập chỉ mục hai giá trị (prev_owner và new_owner).
Đặc điểm Hợp đồng xác định một phương thức phát ra có thể được sử dụng để phát ra các sự kiện.
...#[starknet::contract]mod Ownable { ... #[external(v0)] impl OwnableImpl of super::OwnableTrait { fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { .. .self.emit(Sự kiện::OwnershipTransferred(OwnershipTransferred { prev_owner: prev_owner, new_owner: new_owner, })); } ... } ...}
Với tính năng cuối cùng này, chúng tôi đã hoàn thành quá trình di chuyển hợp đồng thông minh Có thể sở hữu từ v1 sang v2. Mã đầy đủ được hiển thị bên dưới.
sử dụng starknet::ContractAddress;
#[starknet::interface]trait OwnableTrait { fn transfer_ownership(ref self: T, new_owner: ContractAddress); fn get_owner(self: @T) -> ContractAddress;}
#[starknet::contract]mod Có thể sở hữu { sử dụng super::ContractAddress; sử dụng starknet::get_caller_address;
[event] #[derive(Drop, starknet::Event)] enum Sự kiện { OwnershipTransferred: OwnershipTransferred, }
#[derive(Drop, starknet::Event)] struct Quyền sở hữu được chuyển { # [key] trước_chủ sở hữu: Địa chỉ hợp đồng, # [key] mới_chủ sở hữu: Địa chỉ hợp đồng, }
[storage] Lưu trữ cấu trúc { chủ sở hữu: Địa chỉ hợp đồng, }
[constructor] fn constructor(ref self: ContractState) { let Deployer = get_caller_address(); self.owner.write(người triển khai); }
#[external(v0)] impl OwnableImpl of super::OwnableTrait { fn transfer_ownership(ref self: ContractState, new_owner: ContractAddress) { self.only_owner(); để prev_owner = self.owner.read(); self.owner.write(new_owner); self.emit(Sự kiện::OwnershipTransferred(OwnershipTransferred { prev_owner: prev_owner, new_owner: new_owner, })); }
fn get_owner(self: @ContractState) -> Địa chỉ hợp đồng { self.owner.read() } }
#[generate_trait] impl PrivateMethods của PrivateMethodsTrait { fn only_owner(self: @ContractState) { let caller = get_caller_address(); khẳng định (người gọi == self.owner.read(), 'Người gọi không phải là chủ sở hữu'); }
Bạn cũng có thể tìm mã này trên Github.
Tóm lại là
Phiên bản 2 của trình biên dịch Cairo mang đến một cú pháp mới cho Starknet, làm cho mã hợp đồng thông minh trông nhất quán hơn với chính Cairo và bằng cách mở rộng giống với Rust hơn. Ngay cả khi phải trả giá bằng mã rườm rà hơn, các lợi ích bảo mật vẫn đáng để đánh đổi.
Trong bài viết này, chúng tôi chưa đề cập đến mọi thứ về cú pháp mới, đặc biệt là cách nó tương tác với các hợp đồng thông minh khác, nhưng bạn có thể đọc nhật ký thay đổi của trình biên dịch, đọc bài đăng này trên diễn đàn hoặc xem video trên kênh YouTube của StarkWare để tìm hiểu thêm về nó.để biết thêm thông tin.
Phiên bản mới này của trình biên dịch sẽ có sẵn trên mạng thử nghiệm của Starknet sau vài tuần nữa và mạng chính sau vài tuần nữa, vì vậy đừng cố triển khai mã này ngay, nó sẽ chưa hoạt động.
Cairo chỉ tiếp tục trở nên tốt hơn.
nguồn