> ## Documentation Index
> Fetch the complete documentation index at: https://stablelabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Staking

> EVM 스마트 계약에서 검증자 참여 및 위임을 위한 x/staking 노출 Staking 프리컴파일.

## 개요

`staking` precompile 컨트랙트는 Stable SDK의 `x/staking` 모듈 기능을 EVM 환경에서 사용할 수 있도록 브리지 역할을 합니다.

## 목차

1. **[개념](#concepts)**
2. **[구성](#configuration)**
3. **[메서드](#methods)**
4. **[이벤트](#events)**

## 개념

Stable SDK의 `x/staking` 모듈에서는 스테이킹을 위해 체인 초기화 시 bond denom이 등록되어야 합니다.
Validator와 delegator는 bond denom 스테이킹 토큰만 사용할 수 있습니다.
`staking` precompile 컨트랙트에서는 validator 또는 delegator가 호출자인지 확인하는 추가 검증이 수행됩니다.

## 구성

컨트랙트 주소와 가스 비용은 사전에 정의되어 있습니다.

### 컨트랙트 주소

* `0x0000000000000000000000000000000000000800`

## 메서드

### `createValidator`

Validator가 생성됩니다.
Validator는 운영자의 초기 delegation과 함께 생성되어야 합니다.
잠재적인 delegator를 위해 validator는 자신의 정보와 수수료율 계획을 제공해야 합니다.
Delegator는 시장 메커니즘의 자연스러운 규제를 통해 공개된 정보를 바탕으로 자신의 토큰을 위임할 validator를 선택할 수 있습니다.

Validator가 성공적으로 등록되면 `CreateValidator` 이벤트가 발생합니다.

#### Inputs

| Name              | Type            | Description                       |
| ----------------- | --------------- | --------------------------------- |
| description       | Description     | validator의 정보                     |
| commissionRates   | CommissionRates | validator가 보상받는 스테이킹 토큰의 수수료율     |
| minSelfDelegation | uint256         | validator의 최소 자체 위임 금액            |
| validatorAddress  | address         | validator의 주소                     |
| pubkey            | string          | validator의 공개 키                   |
| value             | uint256         | validator에게 초기 자체 위임되는 스테이킹 토큰의 양 |

`Description`은 다음 필드를 가진 구조체입니다:

| Name            | Type   | Description         |
| --------------- | ------ | ------------------- |
| moniker         | string | validator의 이름       |
| identity        | string | validator의 신원       |
| website         | string | validator 웹사이트의 URL |
| securityContact | string | 보안 연락처 정보           |
| details         | string | validator의 추가 설명    |

`CommissionRates`는 다음 필드를 가진 구조체입니다:

| Name          | Type    | Description                     |
| ------------- | ------- | ------------------------------- |
| rate          | uint256 | validator가 받는 현재 수수료율           |
| maxRate       | uint256 | 최대 수수료율 (이보다 높게 설정할 수 없음)       |
| maxChangeRate | uint256 | validator가 하루에 변경할 수 있는 최대 수수료율 |

`rate`는 시장에서 수용 가능한 적절한 값으로 설정해야 합니다.

* Validator의 수수료율이 높으면 delegator의 수익이 낮아집니다.
* Validator의 수수료율이 낮으면 validator의 수익이 낮아지고 운영이 어려워집니다.

높은 `maxRate`는 validator의 예상치 못한 높은 수수료율에 대한 delegator의 우려를 야기할 수 있으므로 `maxRate`는 신중하게 설정해야 합니다. `maxChangeRate`는 초기화 후 변경할 수 없습니다.

#### Outputs

| Name    | Type | Description                |
| ------- | ---- | -------------------------- |
| success | bool | validator가 성공적으로 등록되면 true |

### `editValidator`

Validator가 정보를 업데이트합니다.
Validator는 `CommissionRates` 구조체의 `maxRate` 및 `maxChangeRate`와 같이 변경 불가능한 필드를 제외한 정보만 업데이트할 수 있습니다.

Validator가 성공적으로 업데이트되면 `EditValidator` 이벤트가 발생합니다.

#### Inputs

| Name              | Type        | Description                   |
| ----------------- | ----------- | ----------------------------- |
| description       | Description | validator의 정보                 |
| validatorAddress  | address     | validator의 주소                 |
| commissionRate    | int256      | validator가 보상받는 스테이킹 토큰의 수수료율 |
| minSelfDelegation | int256      | validator의 최소 자체 위임 금액        |

#### Outputs

| Name    | Type | Description                  |
| ------- | ---- | ---------------------------- |
| success | bool | validator가 성공적으로 업데이트되면 true |

### `delegate`

Delegator가 validator에게 위임할 토큰의 양을 설정합니다.

Delegation이 성공적으로 완료되면 `Delegate` 이벤트가 발생합니다.

#### Inputs

| Name             | Type    | Description                 |
| ---------------- | ------- | --------------------------- |
| delegatorAddress | address | delegator의 주소               |
| validatorAddress | address | validator의 주소               |
| amount           | uint256 | validator에게 위임되는 스테이킹 토큰의 양 |

#### Outputs

| Name    | Type | Description                 |
| ------- | ---- | --------------------------- |
| success | bool | delegation이 성공적으로 완료되면 true |

#### Events

`newShares`는 delegator의 소유 비율을 나타냅니다.
동일한 양의 토큰이 위임되더라도 시간에 따라 계산되는 shares는 달라질 수 있습니다.

### `undelegate`

Delegator가 validator에게 위임한 토큰의 양을 인출합니다.

언델리게이션이 성공적으로 완료되면 `Unbond` 이벤트가 발생합니다.

#### Inputs

| Name             | Type    | Description                       |
| ---------------- | ------- | --------------------------------- |
| delegatorAddress | address | delegator의 주소                     |
| validatorAddress | address | validator의 주소                     |
| amount           | uint256 | validator로부터 언델리게이트하려는 스테이킹 토큰의 양 |

#### Outputs

| Name    | Type | Description             |
| ------- | ---- | ----------------------- |
| success | bool | 언델리게이션이 성공적으로 완료되면 true |

### `redelegate`

Delegator가 validator에게 위임한 토큰의 양을 다른 validator에게 재위임합니다.

재위임이 성공적으로 완료되면 `Redelegate` 이벤트가 발생합니다.

#### Inputs

| Name             | Type    | Description       |
| ---------------- | ------- | ----------------- |
| delegatorAddress | address | delegator의 주소     |
| validatorSrc     | string  | 출발지 validator의 주소 |
| validatorDst     | string  | 목적지 validator의 주소 |
| amount           | uint256 | 재위임할 스테이킹 토큰의 양   |

#### Outputs

| Name    | Type | Description          |
| ------- | ---- | -------------------- |
| success | bool | 재위임이 성공적으로 완료되면 true |

### `delegation`

Delegator와 validator 간의 delegation 정보를 반환합니다.
Delegation을 찾을 수 없으면 `shares`와 `balance`는 `0`이 됩니다.

#### Inputs

| Name             | Type    | Description   |
| ---------------- | ------- | ------------- |
| delegatorAddress | address | delegator의 주소 |
| validatorAddress | address | validator의 주소 |

#### Outputs

| Name    | Type    | Description      |
| ------- | ------- | ---------------- |
| shares  | uint256 | 위임된 shares       |
| balance | Coin    | 위임된 토큰의 양과 denom |

`Coin`은 다음 필드를 가진 구조체입니다:

| Name   | Type    | Description |
| ------ | ------- | ----------- |
| denom  | string  | 보상의 denom   |
| amount | uint256 | 보상의 양       |

### `unbondingDelegation`

Delegator와 validator 간의 언본딩 delegation 정보를 반환합니다.
언본딩 delegation을 찾을 수 없으면 빈 `UnbondingDelegationOutput`이 반환됩니다.

#### Inputs

| Name             | Type    | Description   |
| ---------------- | ------- | ------------- |
| delegatorAddress | address | delegator의 주소 |
| validatorAddress | address | validator의 주소 |

#### Outputs

| Name                | Type                      | Description        |
| ------------------- | ------------------------- | ------------------ |
| unbondingDelegation | UnbondingDelegationOutput | 언본딩 delegation의 정보 |

`UnbondingDelegationOutput`은 다음 필드를 가진 구조체입니다:

| Name             | Type                        | Description         |
| ---------------- | --------------------------- | ------------------- |
| validatorAddress | address                     | validator의 주소       |
| delegatorAddress | address                     | delegator의 주소       |
| entries          | UnbondingDelegationEntry\[] | 언본딩 delegation의 항목들 |

`UnbondingDelegationEntry`는 다음 필드를 가진 구조체입니다:

| Name           | Type   | Description |
| -------------- | ------ | ----------- |
| creationHeight | uint64 | 항목의 생성 높이   |
| completionTime | uint64 | 항목의 완료 시간   |
| initialBalance | Coin   | 항목의 초기 잔액   |
| balance        | Coin   | 항목의 잔액      |

### `validator`

Validator 정보를 반환합니다.
Validator를 찾을 수 없으면 빈 `ValidatorOutput`이 반환됩니다.

#### Inputs

| Name             | Type    | Description   |
| ---------------- | ------- | ------------- |
| validatorAddress | address | validator의 주소 |

#### Outputs

| Name      | Type      | Description   |
| --------- | --------- | ------------- |
| validator | Validator | validator의 정보 |

`Validator`는 다음 필드를 가진 구조체입니다:

| Name              | Type    | Description                   |
| ----------------- | ------- | ----------------------------- |
| operatorAddress   | address | validator의 주소                 |
| consensusPubkey   | string  | validator의 공개 키               |
| jailed            | bool    | validator가 jailed 상태인지 여부     |
| status            | int32   | validator의 상태                 |
| tokens            | uint256 | validator에게 위임된 스테이킹 토큰의 양    |
| delegatorShares   | uint256 | delegation shares의 양          |
| description       | string  | validator의 설명                 |
| unbondingHeight   | int64   | validator가 언본딩 중인 높이          |
| unbondingTime     | int64   | validator가 언본딩 중인 시간          |
| commission        | uint256 | validator가 보상받는 스테이킹 토큰의 수수료율 |
| minSelfDelegation | uint256 | validator의 최소 자체 위임 금액        |

### `validators`

상태와 일치하는 모든 validator를 반환합니다.
Validator를 찾을 수 없으면 빈 `ValidatorsOutput`이 반환됩니다.

`x/staking` 모듈에서 선언된 상태는 다음 중 하나일 수 있습니다:

* 0 : "BOND\_STATUS\_UNSPECIFIED", 지정되지 않은 상태
* 1 : "BOND\_STATUS\_UNBONDING", validator가 언본딩 중
* 2 : "BOND\_STATUS\_UNBONDED", validator가 언본딩됨
* 3 : "BOND\_STATUS\_BONDED", validator가 본딩됨

#### Inputs

| Name        | Type    | Description   |
| ----------- | ------- | ------------- |
| status      | string  | validator의 상태 |
| pageRequest | PageReq | 페이지네이션 요청     |

`PageReq`는 다음 필드를 가진 구조체입니다:

| Name       | Type  | Description          |
| ---------- | ----- | -------------------- |
| key        | bytes | 페이지의 키               |
| offset     | int64 | 페이지의 오프셋             |
| limit      | int64 | 페이지의 제한              |
| countTotal | bool  | 결과의 총 개수를 세어야 하는지 여부 |
| reverse    | bool  | 결과를 역순으로 정렬할지 여부     |

#### Outputs

| Name         | Type         | Description    |
| ------------ | ------------ | -------------- |
| validators   | Validator\[] | validator들의 배열 |
| pageResponse | PageResp     | 페이지네이션 응답      |

`PageResp`는 다음 필드를 가진 구조체입니다:

| Name    | Type   | Description |
| ------- | ------ | ----------- |
| nextKey | bytes  | 다음 페이지의 키   |
| total   | uint64 | 결과의 총 개수    |

### `redelegation`

Delegator, 출발지 validator, 목적지 validator의 재위임 정보를 반환합니다.
재위임을 찾을 수 없으면 빈 `RedelegationOutput`이 반환됩니다.

#### Inputs

| Name                | Type    | Description       |
| ------------------- | ------- | ----------------- |
| delegatorAddress    | address | delegator의 주소     |
| srcValidatorAddress | address | 출발지 validator의 주소 |
| dstValidatorAddress | address | 목적지 validator의 주소 |

#### Outputs

| Name         | Type               | Description |
| ------------ | ------------------ | ----------- |
| redelegation | RedelegationOutput | 재위임의 정보     |

`RedelegationOutput`은 다음 필드를 가진 구조체입니다:

| Name                | Type                 | Description       |
| ------------------- | -------------------- | ----------------- |
| delegatorAddress    | address              | delegator의 주소     |
| validatorSrcAddress | address              | 출발지 validator의 주소 |
| validatorDstAddress | address              | 목적지 validator의 주소 |
| entries             | RedelegationEntry\[] | 재위임의 항목들          |

`RedelegationEntry`는 다음 필드를 가진 구조체입니다:

| Name           | Type   | Description |
| -------------- | ------ | ----------- |
| creationHeight | uint64 | 항목의 생성 높이   |
| completionTime | uint64 | 항목의 완료 시간   |
| initialBalance | Coin   | 항목의 초기 잔액   |
| balance        | Coin   | 항목의 잔액      |

### `redelegations`

Delegator, 출발지 validator, 목적지 validator의 모든 재위임을 반환합니다.
재위임을 찾을 수 없으면 빈 `RedelegationResponse`와 `PageResp`가 반환됩니다.

#### Inputs

| Name                | Type    | Description       |
| ------------------- | ------- | ----------------- |
| delegatorAddress    | address | delegator의 주소     |
| srcValidatorAddress | address | 출발지 validator의 주소 |
| dstValidatorAddress | address | 목적지 validator의 주소 |
| pageRequest         | PageReq | 페이지네이션 요청         |

#### Outputs

| Name         | Type                    | Description |
| ------------ | ----------------------- | ----------- |
| response     | RedelegationResponse\[] | 재위임들의 정보    |
| pageResponse | PageResp                | 페이지네이션 응답   |

## 이벤트

### CreateValidator

| Name     | Type    | Indexed | Description                       |
| -------- | ------- | ------- | --------------------------------- |
| valiAddr | address | Y       | validator의 주소                     |
| value    | uint256 | N       | validator에게 초기 자체 위임되는 스테이킹 토큰의 양 |

### EditValidator

| Name              | Type    | Indexed | Description                         |
| ----------------- | ------- | ------- | ----------------------------------- |
| valiAddr          | address | Y       | validator의 주소                       |
| commissionRate    | int256  | N       | validator가 보상받는 스테이킹 토큰의 업데이트된 수수료율 |
| minSelfDelegation | int256  | N       | validator의 업데이트된 최소 자체 위임 금액        |

### Delegate

| Name          | Type    | Indexed | Description                         |
| ------------- | ------- | ------- | ----------------------------------- |
| delegatorAddr | address | Y       | delegator의 주소                       |
| validatorAddr | string  | Y       | validator의 주소                       |
| amount        | uint256 | N       | validator에게 위임되는 스테이킹 토큰의 양         |
| newShares     | uint256 | N       | delegation 이후의 delegation shares의 양 |

### Unbond

| Name           | Type    | Indexed | Description                     |
| -------------- | ------- | ------- | ------------------------------- |
| delegatorAddr  | address | Y       | delegator의 주소                   |
| validatorAddr  | string  | Y       | validator의 주소                   |
| amount         | uint256 | N       | validator로부터 언델리게이트된 스테이킹 토큰의 양 |
| completionTime | uint256 | N       | 언델리게이션의 완료 시간                   |

### Redelegate

| Name                | Type    | Indexed | Description       |
| ------------------- | ------- | ------- | ----------------- |
| delegatorAddr       | address | Y       | delegator의 주소     |
| validatorSrcAddress | address | Y       | 출발지 validator의 주소 |
| validatorDstAddress | address | Y       | 목적지 validator의 주소 |
| amount              | uint256 | N       | 재위임할 스테이킹 토큰의 양   |
| completionTime      | uint256 | N       | 재위임의 완료 시간        |
