# Staking

Staking in Züs Network involves **locking tokens** into a **stake pool** to support various network participants.&#x20;

The **primary objectives** of staking are:

* **Security**: Ensures only reliable and well-funded providers operate in the network.
* **Incentives**: Rewards participants for providing services.
* **Decentralization**: Enables users to participate in governance and network operation.

There are **five main types** of **staking providers** in Züs:

1. **Blobbers** - Storage providers who store and maintain user data.
2. **Validators** - Verify storage challenges and ensure data integrity.
3. **Miners** - Participate in transaction validation and block production.
4. **Sharders** - Store blockchain metadata and help retrieve historical data.
5. **Authorizers** - Manage token bridging between blockchains.

Each provider type has **unique staking requirements** and rewards based on network contribution.

### **Staking Mechanism**

Users can **stake tokens** into **stake pools** of different providers, where tokens are **locked** and used to determine rewards and penalties.

#### **Stake Pools**

Each provider has a **stake pool** where staked tokens accumulate. The total stake affects:

* The **weight** of the provider in earning rewards.
* Their **ability to participate** in network operations.
* The **penalty mechanism** for failing to meet obligations.

#### **Stake Delegation**

Users who do not run a provider node can still **delegate their tokens** to existing providers and earn a **share of the rewards**.

* **Higher stake → More rewards.**
* **Stake remains locked** for a defined period.
* **Providers take a commission** before distributing rewards.

### Staking Process

The Züs Network allows **staking** to different service providers, including **blobbers, validators, miners, sharders, and authorizers**.&#x20;

Users can lock their tokens in **stake pools** to earn rewards based on the provider’s performance and stake weight. Here are key Stake-Related Functions in Go SDK

1. **`StakePoolLock`** - Locks tokens into a stake pool.
2. **`StakePoolUnlock`** - Unlocks staked tokens when eligible.
3. **`WritePoolLock`** - Locks tokens in a **write pool** for storage payments.
4. **`WritePoolUnlock`** - Unlocks tokens from the **write pool**.

#### **1. Locking Tokens in a Stake Pool**

The **`StakePoolLock`** function locks tokens into a stake pool, allowing users to delegate their stake to providers and earn rewards.

```go
func StakePoolLock(providerType ProviderType, providerID string, value, fee uint64) (hash string, nonce int64, err error)
```

Here is how it works:

1. The function **validates** that the SDK is initialized.
2. Ensures a **valid provider type and ID**.
3. Constructs a **stake pool request** and identifies the correct **smart contract**:
   * **Blobber/Validator:** `STORAGESC_STAKE_POOL_LOCK`
   * **Miner/Sharder:** `MINERSC_LOCK`
   * **Authorizer:** `ZCNSC_LOCK`
4. Calls `transaction.SmartContractTxnValueFeeWithRetry` to **execute the staking transaction**.

#### **Example Usage**

```go
hash, nonce, err := StakePoolLock(ProviderBlobber, "blobber-123", 1000, 10)
if err != nil {
    fmt.Println("Error staking:", err)
} else {
    fmt.Println("Stake transaction successful! Hash:", hash)
}
```

#### **Unlocking Tokens from a Stake Pool**

The **`StakePoolUnlock`** function allows users to withdraw their staked tokens when eligible.

```go
func StakePoolUnlock(providerType ProviderType, providerID, clientID string, fee uint64) (unstake int64, nonce int64, err error)
```

Here is how it works:

1. The function **validates** that the SDK is initialized.
2. Ensures the **provider type and ID** are valid.
3. Calls the correct **smart contract method**:
   * **Blobber/Validator:** `STORAGESC_STAKE_POOL_UNLOCK`
   * **Miner/Sharder:** `MINERSC_UNLOCK`
   * **Authorizer:** `ZCNSC_UNLOCK`
4. Executes the **transaction** and returns the amount unstaked.

#### **Example Usage**

```go
goCopyEditunstake, nonce, err := StakePoolUnlock(ProviderBlobber, "blobber-123", "client-id", 10)
if err != nil {
    fmt.Println("Error unlocking stake:", err)
} else {
    fmt.Println("Stake unlocked:", unstake)
}
```

#### **Locking Tokens in the Write Pool**

The **`WritePoolLock`** function allows users to lock tokens into a **write pool**, which is used for **storage payments**.

```go
func WritePoolLock(allocID string, tokens, fee uint64) (hash string, nonce int64, err error)
```

Here is how it works:

1. Ensures the SDK is initialized.
2. Locks tokens for a **specific allocation** (`allocID`).
3. Calls the **`STORAGESC_WRITE_POOL_LOCK`** smart contract.

#### **Example Usage**

```go
hash, nonce, err := WritePoolLock("allocation-456", 500, 5)
if err != nil {
    fmt.Println("Error locking write pool:", err)
} else {
    fmt.Println("Write pool locked successfully! Hash:", hash)
}
```

### **4. Unlocking Tokens from the Write Pool**

The **`WritePoolUnlock`** function allows users to unlock **all tokens** from the write pool.

```go
func WritePoolUnlock(allocID string, fee uint64) (hash string, nonce int64, err error)
```

Here is how it works:

1. Ensures SDK is initialized.
2. Unlocks all **unused tokens** from the **write pool** for a given **allocation** (`allocID`).
3. Calls the **`STORAGESC_WRITE_POOL_UNLOCK`** smart contract.

#### **Example Usage**

```go
hash, nonce, err := WritePoolUnlock("allocation-456", 5)
if err != nil {
    fmt.Println("Error unlocking write pool:", err)
} else {
    fmt.Println("Write pool unlocked successfully! Hash:", hash)
}
```
