본문으로 건너뛰기

규칙

규칙은 TokenPolicy에서 모든 액션에 적용할 수 있는 프로그래머블 제한 사항이다. closed-loop 시스템에서 특정 비즈니스 로직의 컴플라이언스, 규제, 집행을 위한 도구이다.

규칙 구조​

규칙은 drop ability를 가진 type으로 표현된다. 이 타입을 witness라고 부른다. 이를 애플리케이션 로직에 encode하거나 더 모듈화된 접근을 위해 별도 모듈에 포함할 수 있다.

/// The Rule type
struct Rule has drop {}

TokenPolicy에서 액션에 규칙을 추가한 후에는 해당 액션이 확정을 통과하기 위해 규칙의 stamp가 필요하다.

액션 승인 방법에 관한 자세한 내용은 액션 승인 섹션을 참조한다.

모듈식 규칙​

규칙을 별도의 재사용 가능한 모듈로 게시할 수 있다. 이는 서로 다른 토큰 정책에서 사용할 수 있는 규칙 라이브러리를 만들 수 있게 하여, 코드 재사용을 극대화하고 오류 위험을 최소화한다.

Rule 모듈은 verify와 유사한 일반 모듈이며, 이 함수는 일반적으로 TokenPolicy, ActionRequest, TxContext를 인수로 받는다. 이 함수는 액션을 검증하고 ActionRequest에 규칙 타입을 stamp하는 책임이 있다.

module example::pass_rule {
use sui::tx_context;
use sui::token::{Self, ActionRequest, TokenPolicy};

/// The Rule type
struct Pass has drop {}

/// Add approval from the Pass rule to the ActionRequest
public fun verify<T>(
_policy: &TokenPolicy<T>,
action_request: &mut ActionRequest<T>,
ctx: &mut TxContext,
) {
// ...
token::add_approval(Pass {}, action_request, ctx)
}
}

규칙 configuration​

denylist 또는 allowlist와 같은 일부 규칙은 구성이 필요하다. 예를 들어, denylist은 특정 액션을 수행할 수 없는 주소 목록을 요구할 수 있다. Rule 모듈은 구성 구조를 정의하고 구성을 추가, 수정, 조회, 제거하기 위한 함수를 제공할 수 있다.

정보

단일 규칙은 여러 액션에 할당되더라도 단일 configuration을 가진다. 액션별 configuration이 필요하다면, 규칙 모듈은 여러 configuration을 보관하고 관리할 수 있는 storage structure를 정의해야 한다.

구성 시스템에는 규칙 모듈 개발자의 악의적 액션(또는 업그레이드)으로부터 토큰 소유자를 보호하기 위한 일련의 보장 사항이 포함되어 있다:

  1. rule 모듈은 구성의 타입과 구조를 정의한다.
  2. 구성의 추가 또는 수정 및 제거는 TokenPolicy 소유자에게만 허용된다.
  3. 규칙만 구성을 읽을 수 있다.
  4. 규칙은 TokenPolicy 소유자의 승인 없이 구성을 수정할 수 없다.

Rule 생성자에게 가능한 유일한 attack vector는 모듈을 업그레이드하고 제한을 우회하는 함수를 만드는 것이다. 신뢰할 수 있는 개발자가 제공하는 규칙을 사용해야 한다.

구성 API​

sui::token 모듈은 구성 API를 정의하며 다음 함수 집합을 가진다.

새 구성 추가​

새 구성은 규칙이 승인해야 하며(규칙 witness), TokenPolicy 소유자도 승인해야 한다. 구성의 타입은 store ability만 있으면 어떤 것이든 될 수 있다.

// module: sui::token
public fun add_rule_config<T, Rule: drop, Config: store>(
_rule: Rule,
policy: &mut TokenPolicy<T>,
policy_cap: &TokenPolicyCap<T>,
config: Config,
_ctx: &mut TxContext
);

구성 읽기​

규칙은 TokenPolicy에 저장된 구성을 읽을 수 있다.

// module: sui::token
public fun rule_config<T, Rule: drop, Config: store>(
_rule: Rule, policy: &TokenPolicy<T>
): &Config;

구성 수정​

구성 수정은 규칙 witness로서의 규칙과 TokenPolicy 소유자가 모두 승인해야 한다.

// module: sui::token
public fun rule_config_mut<T, Rule: drop, Config: store>(
_rule: Rule, policy: &mut TokenPolicy<T>, policy_cap: &TokenPolicyCap<T>
): &mut Config;

configuration 제거​

규칙에 대한 좋은 관행은 규칙이 이를 위해 커스텀 타입을 사용할 수 있으므로 구성을 제거하는 방법을 제공하는 것이다. 그러나 토큰 소유자는 언제나 remove_rule_config 함수를 호출하여 구성을 제거할 수 있다.

// module: sui::token
public fun remove_rule_config<T, Rule, Config: store>(
policy: &mut TokenPolicy<T>,
policy_cap: &TokenPolicyCap<T>,
_ctx: &mut TxContext
): Config;

구성에 store가 있으므로 토큰 소유자는 구성을 wrap and transfer 하거나 다른 곳에 저장할 수 있다. 만약 Config 타입에 drop이 있으면 그 값은 무시할 수 있다.

cheat sheet: 규칙 configuration API​

Method name설명비고
add_rule_config규칙에 대한 새 config를 추가한다규칙 witness와 토큰 소유자의 승인이 필요하다
remove_rule_config정책에서 config 객체를 제거한다Token Owner는 언제든지 수행할 수 있다
rule_configconfig에 불변으로 접근한다규칙에서만 사용할 수 있다
rule_config_mutconfig에 대한 가변 참조를 가져온다규칙 witness와 토큰 소유자의 승인이 필요하다
has_rule_config규칙에 config가 설정되었는지 확인한다-
has_rule_config_with_type규칙에 특정 타입의 config가 있는지 확인한다-