Tổng quan

Trong lập trình, interface là một kiểu trừu tượng quan trọng để xác định hành vi của các kiểu triển khai interface. Các interface công bố các hàm và trường cần thiết, quyền kiểm soát truy cập cho các khai báo này, cũng như điều kiện tiên quyết và hậu quả mà các kiểu triển khai cần cung cấp. Trong bài viết này, chúng ta sẽ tập trung vào resource interface – một kiểu interface được sử dụng rộng rãi trong Cadence – và tìm hiểu cách sử dụng nó để hiển thị các thông tin cụ thể từ resource.

Lập trình Cadence

Interface

Interface công bố các hàm và trường cần thiết, quyền kiểm soát truy cập cho các khai báo này, cũng như điều kiện tiên quyết và hậu quả mà các kiểu triển khai cần cung cấp.

  • Nó chỉ định một tập hợp các yêu cầu cho một cái gì đó để thực hiện
  • Nó cho phép bạn chỉ tiết lộ những thứ nhất định cho những người nhất định

Có ba loại interface:

  1. Structure interface: được triển khai bởi các structure
  2. Resource interface: được triển khai bởi các resource
  3. Contract interface: được triển khai bởi các contract

Các kiểu structure, resource và contract có thể triển khai nhiều interface.

Không có hỗ trợ cho event và enum interface.

flow interface
flow interface

Cách sử dụng Resource Interface

Trong bài này, ta sẽ chỉ sử dụng resource interface , tuy nhiên, struct interface hoàn toàn giống nhau.

Trong Cadence, resource interface/ struct interface về cơ bản là “yêu cầu” hoặc cách để bạn hiển thị dữ liệu từ resource/struct. Về bản thân, các interface không làm bất cứ điều gì. Nhưng khi chúng được áp dụng cho một resource/struct, đó là khi chúng làm điều gì đó.

Resource interface được xác định bằng từ khóa giao resource interface(đối với cấu trúc, đó là struct interface):

pub contract Stuff {

    pub resource interface ITest {

    }

    pub resource Test {
      init() {
      }
    }
}

Trong ví dụ trên, bạn có thể thấy rằng chúng tôi đã làm hai việc:

Chúng ta đã xác định resource interface trống có tên ITest.
Chúng ta đã xác định một resource trống có tên Test.
Cá nhân tôi luôn đặt tên cho các giao diện có chữ “I” ở phía trước, vì nó giúp tôi xác định nó thực sự là gì.

Trong ví dụ trên, ITest không thực sự làm bất cứ điều gì. Nó chỉ ngồi đó. Hãy thêm một số thứ vào nó.

pub contract Stuff {

    pub resource interface ITest {
      pub let name: String
    }

    pub resource Test {
      init() {
      }
    }
}

Bây giờ, ITest chứa một trường tên. Nhưng ITest vẫn không làm gì cả. Nó chỉ ngồi đó trong không gian. Vì vậy, hãy làm cho Test triển khai giao diện tài nguyên ITest.

pub contract Stuff {

    pub resource interface ITest {
      pub let name: String
    }

    // ERROR: 
    // `resource Stuff.Test does not conform
    // to resource interface Stuff.ITest`
    pub resource Test: ITest {
      init() {

      }
    }
}

Chú ý những gì chúng ta vừa làm đã Test triển khai ITest bằng cách thêm cú pháp : ITest. Điều đó có nghĩa là “Resource này triển khai các resource interface sau dấu :“.

Nhưng bạn sẽ nhận thấy có lỗi: “tài nguyên Stuff.Test không phù hợp với resource interface Stuff.ITest”. Hãy nhớ những gì chúng tôi đã nói ở trên? Giao diện tài nguyên là yêu cầu. Nếu một tài nguyên triển khai giao diện tài nguyên, nó PHẢI xác định những thứ trong giao diện. Hãy sửa nó.

pub contract Stuff {

    pub resource interface ITest {
      pub let name: String
    }

    pub resource Test: ITest {
      pub let name: String
      init() {
        self.name = "Spongebob" 
      }
    }
}

Sử dụng Interface để hiển thị những thứ cụ thể

Ở trên, chúng ta đã học được rằng các resource interface làm cho tài nguyên thực hiện một số thứ nhất định. Nhưng các giao diện tài nguyên thực sự quan trọng hơn thế nhiều. Hãy nhớ điều thứ 2 họ làm? Chúng tôi đã nói: “Nó cho phép bạn chỉ tiết lộ một số thứ nhất định cho những người nhất định”. Hãy xem bên dưới:

pub contract Stuff {

    pub resource interface ITest {
      pub let name: String
    }

    pub resource Test: ITest {
      pub let name: String
      pub let number: Int
      init() {
        self.name = "Spongebob"
        self.number = 1
      }
    }

    pub fun noInterface() {
      let test: @Test <- create Test()
      log(test.number) // 1

      destroy test
    }

    pub fun yesInterface() {
      let test: @Test{ITest} <- create Test()
      log(test.number) // ERROR: `member of restricted type is not accessible: number`

      destroy test
    }
}
  • Chúng ta đã tạo một chức năng gọi là noInterface. Hàm này tạo một resource mới (với loại @Test) và ghi lại number của nó. Điều này hoạt động hoàn hảo.
  • Chúng ta đã tạo một chức năng gọi là yesInterface. Hàm này tạo một resource mới được giới hạn trong giao diện ITest (có loại @Test{ITest}) và cố gắng ghi lại number nhưng không thành công.

Trong Cadence, bạn “giới hạn loại” tài nguyên bằng cách sử dụng ký hiệu {RESOURCE_INTERFACE}. Bạn sử dụng dấu ngoặc {} và đặt tên của giao diện tài nguyên ở giữa. Điều đó có nghĩa là: “loại này là tài nguyên chỉ có thể sử dụng những thứ được giao diện hiển thị.” Nếu bạn hiểu điều này, bạn sẽ hiểu rất rõ về giao diện tài nguyên.

Vậy tại sao logyesInterface không thành công? Chà, đó là vì ITest KHÔNG hiển thị number! Vì vậy, nếu chúng ta nhập biến test@Test{ITest}, chúng ta không thể truy cập biến đó.

Một số ví dụ phức tạp

pub contract Stuff {

    pub resource interface ITest {
      pub var name: String
      pub var number: Int
      pub fun updateNumber(newNumber: Int): Int
    }

    pub resource Test: ITest {
      pub var name: String
      pub var number: Int

      pub fun updateNumber(newNumber: Int): Int {
        self.number = newNumber
        return self.number // returns the new number
      }

      init() {
        self.name = "Spongebob"
        self.number = 1
      }
    }

    pub fun noInterface() {
      let test: @Test <- create Test()
      test.updateNumber(newNumber: 5)
      log(test.number) // 5

      destroy test
    }

    // Works totally fine now! :D
    pub fun yesInterface() {
      let test: @Test{ITest} <- create Test()
      let newNumber = test.updateNumber(newNumber: 5)
      log(newNumber) // 5

      destroy test
    }
}

Cộng đồng hệ sinh thái Flow Việt Nam