컨트랙트 클래스
컨트랙트의 로직 및 상태(스토리지)는 핵심 클래스에 의해 정의됩니다.
컨트랙트 정의
컨트랙트는 고유한 특성과 메서드가 있는 또 다른 클래스입니다. 이를 다른 내부 클래스와 구별하려면, NEAR Bindgen
데코레이터/매크로를 사용해보세요.
- 🌐 JavaScript
- 🦀 Rust
loading...
loading...
실제로 내부에선, NEAR Bindgen
데코레이터/매크로가 클래스를 훑은 다음 아래와 같은 용도로 사용될 코드를 생성합니다.
- 코드를 유효한 NEAR 컨트랙트로 변환합니다.
- 외부에서 호출될 수 있도록 퍼블릭 메서드를 공개합니다.
- 내부 저장 및 외부와의 통신을 위해 개체를 직렬화합니다.
상태
각 계정에는 고유한 상태(스토리지)가 있으며, 해당 계정만이 수정할 수 있지만 누구나 볼 수 있습니다.
상태는 핵심 클래스의 속성을 통해 정의되고 수정됩니다.
컨트랙트는 잔고의 일부를 잠그는 방식으로 스토리지 비용을 지불합니다 . 현재 100kb를 저장하는 데 ~1 Ⓝ의 비용이 듭니다.
컨트랙트는 실제로 키-값
스토리지를 사용하여 값을 저장합니다. 그러나 이는 SDK에 의한 직렬화를 통해 추상화되어 제공됩니다.
Initializing the State
계정 상태를 초기화하는 방법에는 두 가지가 있으며, 둘은 공존할 수 있습니다.
- 상태에 필요한 속성을 받는 초기화 메서드
init
이 호출되거나 메서드가 상태에 기록될 때까지 사용되는 기본 상태
초기화 방법
초기화 메서드 정의하려면, 이를 간단히 초기화 매크로라고 표기하면 됩니다.
이 메서드는 이제 초기 상태의 값을 정의할 수 있으며, 상태가 이미 초기화된 상태에서 호출하면 오류가 발생합니다.
- 🌐 JavaScript
- 🦀 Rust
loading...
To make the initialization mandatory use @NearBindgen({requireInit: true})
In JavaScript you must always define a default state
loading...
To make the initialization mandatory use #[derive(PanicOnDefault)]
in the contract's structure
기본 상태
컨트랙트는 초기화 메서드가 호출되지 않은 경우 사용할 기본 상태를 정의할 수 있습니다. 즉, init
이벤트가 발생하기 전에 메서드가 호출되면, 컨트랙트는 기본값을 사용합니다.
메서드가 상태에 기록되면, 상태가 초기화된 것으로 간주됩니다.
- 🌐 JavaScript
- 🦀 Rust
loading...
🌐 JavaScript에서 기본 상태는 클래스 정의 내 초기화 매개변수에 의해 정의됩니다.
Javascript에서는 항상 모든 클래스의 매개변수에 값을 할당해야 합니다. 이렇게 하면 의도한 형식으로 올바르게 역직렬화됩니다 .
loading...
인터페이스
모든 퍼블릭 메서드는 컨트랙트의 인터페이스로 네트워크에 공개됩니다.
- 🌐 JavaScript
- 🦀 Rust
@NearBindgen({})
class Contract {
@initialize({ ... })
init({ ... }) { /* public `init` method */ }
@view({})
get_message({ ... }) { /* public `view` method */ }
@call({})
add_message({ ... }) { /* public `call` method */ }
private internal_search( ... ) { /* private internal method */ }
@call({privateFunction: true})
set_owner({ ... }) { /* public, panics when caller is not the contract's account */ }
}
#[near_bindgen]
impl Contract {
#[init]
pub fn init( ... ) -> Self { /* public `init` method */ }
pub fn get_message(&self, ... ) { /* public `view` method */ }
pub fn add_message(&mut self, ... ) { /* public `call` method */ }
fn internal_search(&self, ... ) { /* private internal method */ }
#[private]
pub fn set_owner(&mut self, ... ) { /* public, panics when caller is not the contract's account */ }
}
퍼블릭 메서드
퍼블릭 메서드는 init
메서드, view
메서드, 그리고 call
메서드의 세 가지 유형으로 분류할 수 있습니다:
- Init 메서드 : 컨트랙트 상태를 초기화하는 방법을 정의합니다.
- View 메서드: 상태를 변경하거나 다른 컨트랙트를 호출하지 않습니다. NEAR 계정이 없어도 누구나 무료로 호출할 수 있습니다.
- Call 메서드: 상태를 변경하거나 다른 컨트랙트를 호출하는 것과 같은 작업을 수행할 수 있습니다.
view
methods have 200TGas
to execute, to increase this you can simply invoke them as call
methods. :::프라이빗 메서드
때로는 일부 메서드를 공개 상태로 유지하되, 컨트랙트 계정에서만 호출할 수 있기를 원할 것입니다. 예를 들자면 교차 컨트랙트 콜백이 그러한 경우입니다.
이를 위해 private
매크로/데코레이터를 사용할 수 있습니다.
- 🌐 JavaScript
- 🦀 Rust
@call({privateFunction: true})
callback( ... ){
// this method can only be called by the contract's account
}
#[private]
pub fn callback(&mut self, ... ){
// this method can only be called by the contract's account
}
지불 가능 메서드
기본적으로 사용자가 메서드를 호출할 때, 돈을 첨부하면 모든 메서드가 패닉 상태가 됩니다. 돈을 받는 방법을 활성화하려면, 지불 가능 데코레이터를 사용하십시오.
- 🌐 JavaScript
- 🦀 Rust
@call({payableFunction: true})
deposit_and_stake( ... ){
// this method can receive money from the user
}
#[payable]
pub fn deposit_and_stake(&mut self, ... ){
// this method can receive money from the user
}
입력 및 반환 자료형
컨트랙트는 복잡한 구조를 포함하여 모든 기본 자료형
을 수신하고 반환할 수 있습니다. 그러나 계약은 JSON을 사용한 인터페이스를 통해 통신하기 때문에:
- 항상 입력 및 자료형으로
SDK Collections
보다기본 자료형
을 선호합니다. strings
을u64
/u128
로 교체합니다(Rust SDK에서는U64
/U128
).