OnlyPaws：Proof of Liquidity のすべてを明かす [Berachain Blog]


:::note info
本記事は下記の翻訳となります。
[『OnlyPaws: Bearing it all for Proof of Liquidity』](https://blog.berachain.com/blog/onlypaws-bearing-it-all-for-proof-of-liquidity)
:::

![](https://blog.berachain.com/_next/image?url=https%3A%2F%2Fberachain.ghost.io%2Fcontent%2Fimages%2F2024%2F11%2FGroup-1246--1--1.png&w=1920&q=75)

OnlyFans のコンテンツクリエイターに課金する代わりに、**OnlyPaws** という**ベアパウ**（クマの足）🐾 のマーケットプレイスをご紹介します。

クリエイターのお気に入りのパウを購入できるだけでなく、OnlyPaws での各購入は Berachain の Proof of Liquidity (PoL) を通じて自動的に報酬を獲得できます。ただし、他の人よりもずっと早く購入した人が、永続的にあの魅力的な **BGT** を獲得し続けるのは公平ではありませんよね？

✨ OnlyPaws は **期限付き PoL 報酬**という概念を導入することでこれを解決します：

> **ユーザーの購入は 7 日間のみ BGT 報酬を獲得できます**

## OnlyPaws アプリの概要

アプリはこちらでご確認ください：[https://only-paws.vercel.app/](https://only-paws.vercel.app/?ref=berachain.ghost.io)

OnlyPaws では以下のことが可能です：

- 自分のパウ画像を出品し、他のユーザーが購入できるようにする
- 購入後 7 日間、自動的に **BGT** 報酬を獲得する
- リーダーボードで収益を追跡し、請求する

## マーケットプレイス

クリエイターは自分のパウ画像をアップロードし、価格（BERA）を設定できます。他の熱心なベアたちは、これらの貴重なパウにアクセスするために支払いを行うことができます。

![](https://berachain.ghost.io/content/images/2024/10/op-marketplace.gif)

## Proof of Liquidity の統合

パウを購入すると、スマートコントラクトは自動的に PoL リワードボールトにステーキングを行い、BGT 報酬を獲得できるようにします。**BGT リーダーボード**ページでは、最大のアクティブステークを確認できます。

![](https://berachain.ghost.io/content/images/2024/10/image-4.png)

将来の購入者にも平等に獲得のチャンスを与える必要があるため、ステークは永続的ではありません。パウの購入から**7 日間**が経過すると、他のユーザーが **BGT** を獲得できるように、自動的に**アンステーク**されます。

ただし、ご安心ください。パウはギャラリーに残り続けます！

## OnlyPaws スマートコントラクト

では、OnlyPaws がこのユニークな報酬メカニズムをどのように実装しているのか、詳しく見ていきましょう。そもそも、どうやって誰かを自動的にアンステークするのでしょうか？

`delegateStake` 機能の仕組みに馴染みがない場合は、このメカニズムについて詳しく説明している [POLTech の記事](https://blog.berachain.com/blog/poltech-proof-of-liquidity-goes-social?ref=berachain.ghost.io) の _スマートコントラクト_ セクションをご覧ください。

簡単に言うと：

> **コントラクトは、リワードボールトの `delegateStake` 関数を使用して、ユーザーの PoL ステーキングポジションを管理できます**

OnlyPaws のライブコントラクトはこちらで確認できます：[https://bartio.beratrail.io/address/0x3Df96af91D7a802132A996108C06B69f102bf7db/contract/80084/code](https://bartio.beratrail.io/address/0x3Df96af91D7a802132A996108C06B69f102bf7db/contract/80084/code?ref=berachain.ghost.io)

以下の図は、異なる要素がどのように相互作用するかを示しています：

![](https://berachain.ghost.io/content/images/2024/11/Group-1245--1-.png)

### 主要なデータ構造

OnlyPaws を動かす 2 つの主要な Solidity 構造体があります：

```solidity
struct PawImage {
    address owner;
    uint256 price;
}

struct StakeInfo {
    address user;
    uint256 pawId;
    uint256 amount;
    uint256 expiryTime;
}
```

- **PawImage** は、出品されたパウの所有者と価格を含み、`mapping(uint256 => PawImage) public pawImages` で `pawID` によってインデックス化されます
- **StakeInfo** は、購入されたパウの PoL ステーキング情報を含み、特に有効期限が切れる時期を、有効期限の**昇順**で保持します：`StakeInfo[] private orderedStakes`

### パウの購入で魔法が起きる 🪄

OnlyPaws の PoL 統合の中核は、誰かがパウを購入する時に発生します。コードを簡略化したバージョンを以下に示します：

```solidity
 function purchasePaw(uint256 pawId) external payable {

      purgeExpiredStakes();

      uint256 expiryTime = block.timestamp + 7 days;

      // 新しいステークを順序付き配列に追加
      orderedStakes.push(
          StakeInfo({
              user: msg.sender,
              pawId: pawId,
              amount: 1e18, // すべての購入に対して固定レート
              expiryTime: expiryTime
          })
      );

      userHasPaw[msg.sender][pawId] = true;
      userTotalStake[msg.sender] += PAW_STAKE_AMOUNT;

      // ユーザーにステークを委任
      stakingToken.mint(address(this), PAW_STAKE_AMOUNT); // 1e18
      vault.delegateStake(msg.sender, PAW_STAKE_AMOUNT); // 1e18
}
```

最初の行を飛ばして見ると、`orderedStakes` に新しいエントリが追加され、その後 `delegateStake` 呼び出しが行われ、ユーザーに代わってリワードボールトにステークされます（これでユーザーは **BGT** の獲得を開始します！）。`stakingToken` は、このシステムでパウの購入をインセンティブ付けすることだけを目的としたダミートークンです。

### 古いステークの整理 🧹

では、`purgeExpiredStakes()` 関数を呼び出す最初の行に戻って、中身を見てみましょう：

```solidity
  function purgeExpiredStakes() public {
      uint256 i = 0;

      // 有効期限が切れていないステークを見つけるか、すべてのステークを処理するまで続ける
      while (
          i < orderedStakes.length &&
          orderedStakes[i].expiryTime < block.timestamp
      ) {
          StakeInfo memory stake = orderedStakes[i];

          // ボールトからステークを引き出す
          vault.delegateWithdraw(stake.user, stake.amount);
          stakingToken.burn(address(this), stake.amount);

          // ユーザーの状態を更新
          userHasPaw[stake.user][stake.pawId] = false;
          userTotalStake[stake.user] -= stake.amount;

          emit PawUnstaked(stake.user, stake.pawId, stake.amount);
          i++;
      }
  }
```

PoL リワードボールトに現在ステークされているすべてのパウを、最も早く有効期限が切れる順に並べた `orderedStakes` 配列があるため、各購入トランザクションでクリーンアップを実行し、報酬の資格がなくなった（**7 日**以上経過した）パウを*アンステーク*します。

コントラクトコードが、異なるステークのユーザーに対して `delegateWithdraw` を実行する（もう **BGT** は獲得できません）様子に注目してください。以下の図は、コードが古いステークを走査してクリーンアップを実行する方法を示しています：

![](https://berachain.ghost.io/content/images/2024/11/image-2-1.png)

この例では、ステーク #1 と #2 がそれぞれ 7 日と 8 日が経過しているため、新しい購入に続いてこれらのステークは自動的にパージされます。

つまり、OnlyPaws は定期的なユーザー活動に依存して、システムの維持と秩序の保持を支援しています。これは、同様のアルゴリズムの実装を望む開発者が認識しておくべき依存関係です。

## 結論

ここまでお読みいただき、ありがとうございます！OnlyPaws がどのように**期限付き PoL 報酬**を実現し、創造的なインセンティブプログラムを立ち上げる Proof of Liquidity の柔軟性を示しているかについて、理解を深めていただけたと思います。OnlyPaws システムの主要な機能を振り返ってみましょう。

- **自動ステーキング：** `delegateStake` を使用してパウ購入者に代わって新しいステークを作成
  - これにより、購入者は一時的な **BGT** 報酬の権利を得ます...
- **自動クリーンアップ：** 他のユーザーの購入時に**7 日**以上経過したステークをチェックし、自動的にアンステークします

PoL を他の興味深いアプリケーションに適用する例は、まもなく公開予定です！

---

### 🐻 完全なコードリポジトリ

最終的なコードを確認し、他のガイドを見たい場合は、[**_OnlyPaws コード_**](https://github.com/larrythecucumber321/onlypaws?ref=berachain.ghost.io) をチェックしてください。

### 🛠️ さらに開発したい方へ

詳細をより深く理解したい場合は、[**_Berachain Docs_**](https://docs.berachain.com/?ref=berachain.ghost.io) をご覧ください。

### 開発サポートをお探しの方へ

[**_Berachain Discord_**](https://discord.com/invite/berachain?ref=berachain.ghost.io) サーバーに参加し、開発者チャンネルで質問してください。

❤️ この記事への「いいね」をお忘れなく 👏🏼

---

:::note info
【Sunrise とは】
Sunrise は Proof of Liquidity(PoL)と Fee Abstraction（手数料抽象化）を備えたデータ可用性レイヤーです。 私たちは DA の体験を再構築し、多様なエコシステムからのモジュラー型流動性を活用してロールアップを立ち上げています。

- [Sunrise - Specialized DA Layer for Proof of Liquidity](https://sunriselayer.io/)
- [Sunrise / Gluon Docs](https://docs.sunriselayer.io/)

【Social Links】

- [X(旧 Twitter)[英語])](https://twitter.com/SunriseLayer)
- [X(旧 Twitter)[日本語])](https://twitter.com/SunriseLayer)
- [Discord Community](https://discord.com/invite/sunrise)
- [Medium](https://sunriselayer.medium.com/)
- [Github](https://github.com/sunriselayer)
- [Linkedin](https://www.linkedin.com/company/sunriselayer)

【お問合せ】
Sunrise へのお問い合わせはこちらから 👉 [Google Form](https://forms.gle/h8RVahxRtXUvYwnv6)

![1080x360.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3839047/8971d83b-3331-4757-dc72-320d28618735.jpeg)

:::