Rust 스마트 컨트랙트 개발일지 (8)
BlockSec
2022-04-01 11:38
本文约2449字,阅读全文需要约10分钟
이 기사는 다음 두 가지 관점에서 Rust 스마트 계약의 권한 제어 관련 문제를 구체적으로 소개합니다.

    이 기사는 다음 두 가지 관점에서 Rust 스마트 계약의 권한 제어 관련 문제를 구체적으로 소개합니다.

    계약 방법(기능) 액세스/호출 가시성

    보조 제목

    1. 계약 기능(방법) 가시성

    스마트 계약을 작성할 때 계약 기능의 가시성을 지정하여 누가 호출할 수 있는 기능을 제어할 수 있습니다. 이를 통해 계약의 특정 중요 부분을 우발적인 액세스나 조작으로부터 쉽게 보호할 수 있습니다.

    계약 기능의 가시성을 올바르게 설정하는 것의 중요성을 반영하기 위해 이 기사에서는 Bancor 네트워크 거래소를 예로 들겠습니다. 빠르면 2020년 6월 18일, 계약의 주요 기능에 대한 액세스 제어 권한을 잘못 설정하여 거래소에서 계약 자산 보안 사고가 발생했습니다. 계약은 Solidity 언어로 작성됩니다. 이 언어에서 계약 기능의 가시성은 크게 공개/외부 및 비공개/내부로 나뉩니다. 전자는 계약 인터페이스의 일부로 간주될 수 있는 외부 호출자가 계약 함수를 호출할 수 있도록 합니다.

    그러나 Bancor Network 거래소가 부주의로 인해 특정 보안 허점을 수정했을 때 실수로 계약의 일부 주요 전송 기능을 공개 속성으로 설정했습니다(아래 참조).

    이를 기반으로 일반 사용자를 포함한 누구나 계약 외부에서 이러한 기능을 호출하여 자신 또는 타인을 위한 해당 전송 작업을 수행할 수 있습니다.

    이 중대한 취약점의 존재로 인해 $590,000에 달하는 사용자 자산이 심각한 위험에 노출되었습니다.


    마찬가지로 Rust 스마트 계약에서는 계약 기능의 가시성 제어에도 주의를 기울여야 합니다.

    다이어리를 개발하기 위한 일련의 스마트 컨트랙트에서Rust 스마트 컨트랙트 개발일지 (1), NEAR SDK: #[near_bindgen]:에서 정의한 매크로를 도입했습니다.

    #[near_bindgen]은 near-sdk-macros-version 패키지의 near_bindgen 함수에 의해 정의됩니다. 여기서 매크로는 주입 코드(Macros-Auto-Generated Injected Code, 줄여서 MAGIC)를 자동으로 생성하는 데 사용됩니다.

    NEAR에서 제공하는 공식 설명 문서를 참조하면 #[near_bindgen] 매크로에 의해 정의된 Rust 스마트 계약 함수에 여러 가지 가시적인 속성이 있음을 알 수 있습니다.

    • pub fn: 계약 메서드가 공개되고 계약 인터페이스의 일부임을 나타냅니다. 즉, 계약 외부에서 누구나 호출할 수 있습니다.

    • fn: 컨트랙트의 메서드 함수가 pub을 명시적으로 지정하지 않은 경우 해당 함수를 컨트랙트 외부에서 직접 호출할 수 없으며 컨트랙트 내 다른 함수에 의해서만 내부적으로만 호출할 수 있음을 의미합니다.

    • pub(crate) fn: pub(in crate)와 동일하며 fn과 유사합니다. 이 가시성 수정자는 특정 계약 메서드가 크레이트 범위 내에서 호출되도록 제한할 수 있습니다.

    계약 방법을 내부로 설정하는 또 다른 방법은 계약에서 별도의 impl 계약 코드 블록을 정의하는 것입니다.

    그러나 구현은 #[near_bindgen]에 의해 수정되지 않는다는 점에 유의해야 합니다.

    콜백(Callbacks) 기능에 대한 액세스 제어:

    계약에서 콜백 함수의 정의는 public 속성으로 설정해야 함수 호출을 통해 호출할 수 있습니다.

    계약에서 콜백 함수를 정의할 때 다른 사람이 콜백 함수를 임의로 호출할 수 없도록 해야 합니다. 즉, 콜백 함수 env::current_account_id()의 호출자는 계약 자체의 env::current_account_id()여야 합니다.

    NEAR SDK는 동등한 Rust 매크로 #[private]를 정의합니다. 이 매크로를 사용하면 계약의 콜백 함수는 위 코드의 4-5행에서 구현한 것과 동일한 기능을 수행할 수 있습니다.

    기본적으로 Rust 언어의 모든 것은 비공개입니다.예를 들어 위의 공개 속성을 설정하지 않은 fn 함수는 기본 가시성이 비공개입니다.

    여기에서 solidity를 구별해야 하는 것은 일부 이전 버전의 solidty 컴파일러에서 계약 함수의 정의에 수정자가 추가되지 않으면 기본적으로 공개로 간주된다는 것입니다.

    그러나 Rust 언어에는 두 가지 예외가 있습니다.

    • pub Trait의 하위 항목은 기본적으로 공개됩니다.

    • pub Enum의 Enum 변수도 기본적으로 공개됩니다.


    2. 권한 있는 기능의 액세스 제어(화이트리스트 메커니즘)

    Rust 스마트 계약을 작성할 때 특정 기능 가시성을 아는 것 외에도 계약의 의미론적 수준에서 깊이 생각해야 합니다. 즉, 완전한 액세스 제어 화이트리스트 메커니즘을 설정해야 합니다.

    Solidity 스마트 계약 라이브러리 openzeppelin-contracts에서 정의되고 사용되는 contract/access/Ownable.sol 계약과 유사하게 일부 기능은 계약 초기화, 계약 열기/일시 중지, 통합 전송 등과 같은 특권 기능입니다. ... 계약 소유자만 호출할 수 있으며 이러한 함수는 일반적으로 소유자 함수만 호출됩니다.

    그러나 소유자는 본질적으로 계약의 외부 호출자이며 호출하려면 이러한 키 기능을 공용 속성으로 설정해야 합니다. 그렇다면 이러한 기능은 공용 속성이므로 다른 모든 일반 사용자도 와서 호출할 수 있다는 의미입니까?

    대답은 '예'이지만 소유자가 아닌 일반 사용자는 곧 자신이 조정할 수 있지만 완전히는 아님을 알게 될 것입니다.

    이는 스마트 계약에서 계약 기능에 대해 일부 액세스 제어 규칙을 정의할 수 있으며 해당 규칙이 충족되어야 실행 권한이 완전히 부여되기 때문입니다. 예를 들어, 견고성 계약에서 다음과 같이 일반적으로 사용되는 수정자가 있습니다.

    이 수정자에 의해 수정된 계약 함수가 호출되면 먼저 이 트랜잭션의 호출자 msg.sender가 계약 초기화 시 설정된 소유자인지 여부를 확인하고 일치하지 않으면 함수의 후속 실행이 중단되거나 되돌려집니다. , 권한이 없는 사용자의 액세스 및 실행을 방지합니다.

    마찬가지로 NEAR Rust의 스마트 계약에서 다음과 유사한 사용자 지정 특성을 구현할 수도 있습니다.

    이 특성을 사용하면 계약의 특정 권한 있는 기능에 대한 액세스 제어를 구현할 수도 있습니다. 즉, 이 트랜잭션에서 계약의 호출자 env::predecessor_account_id()는 계약 소유자와 동일해야 합니다.

    위에서 우리는 소유할 수 있는 권한 있는 기능에 대해서만 간단한 화이트리스트 예제를 설정했습니다. 이 원칙에 따라 더 복잡한 수정자 또는 특성을 사용자 지정하여 화이트리스트에 여러 사용자를 설정하거나 여러 화이트리스트를 설정하여 우수하고 세분화된 그룹 액세스 제어 효과를 얻을 수 있습니다.

    3. 더 많은 액세스 제어 방법

    다음과 같은 다른 Rust 스마트 계약의 액세스 제어 방법:

    • 계약 통화 타이밍 제어

    • 계약 기능의 다중 서명 호출 메커니즘, 거버넌스 구현(DAO)

    • ...

    이번 스마트 컨트랙트 개발일지 시리즈의 후속 푸시도 많은 관심 부탁드립니다😊

    BlockSec
    作者文库