✏️

Filecoin Study2 : FVMによる保存の流れを理解

2023/06/01に公開

前回 につづいてもう少し具体的なコードのイメージを掴みたいとおもいもう少しStudyをすすめます。

filecoin における保存と取得のシーケンス理解

まずFVMとか、FEVMとか関係なく filecoinに保存、取得するとはについて分かりやすい解説です。
https://filecoin.io/blog/posts/how-storage-and-retrieval-deals-work-on-filecoin/

保存 Client視点の手順

  1. 取引に資金を提供する- クライアントは資金をエスクローにロックします
  2. マイナーに取引を提案する
  3. 取引を受け入れる意思があるかどうかを確認する
  4. 取引のデータをマイナーに転送します。これは、 GraphSyncプロトコルを介して行われます。GraphSync は、ピア間で IPLD グラフを同期するためのプロトコルです。これにより、ホストはリモート ピアに対して、リモート ピアのローカル IPLD グラフ上の IPLD セレクターを走査したすべての結果を求める単一の要求を行うことができます。Lotus は、GraphSync プロトコルのipfs/go-graphsync実装を使用します。
  5. 受け入れを確認する- マイナーが取引を受け入れ、オンチェーンで公開していることを確認します。
  6. シーリング- 取引はオンチェーン上にあり、マイナーは現在、取引を含むセクターを封印しています。
  7. アクティブ- 取引は締結されており、アクティブです。今後、ストレージプロバイダー/マイナーはデータを保存し続けていることを定期的に証明する必要があります。

保存 マイナー視点の手順

データを保存することでクライアントにサービスを提供するマイナーの観点から見ると、取引は大まかに次の段階を経ます。

  1. 取引の確認- 取引の提案を受け取り、パラメータ (サイズ、価格など) を確認します。
  2. ロックされた資金を確認する- クライアントが資金をロックしており、取引の支払いができることを確認します。
  3. データを待つ- 取引のためにクライアントからデータを受け取ります。
  4. チェーン取引の担保を差し入れる
  5. 取引をオンチェーンで公開する
  6. セクターを封印する
  7. 取引をアクティブ化する- これ以降、ストレージプロバイダー/マイナーは定期的に WindowPoSt プルーフを送信し、データを継続的に保存していることを証明します。

クライアントはマイナーを識別し、マイナーが取引を受け入れるために受け取りたい現在のアスク、つまり attoFIL (1 attoFIL は 10^-18 * FIL に等しい) でのエポック (30 秒) ごとの GiB あたりの価格を決定します。現在、Filecoin の取引の最低期間は 180 日です。

Filecoin にセクターを登録するには、マイナーはセクターを封印する必要があります。シーリングは、 Proof-of-Replication呼ばれる、証明の形式でデータの一意の表現を生成する、計算量の多いプロセスです。証明が生成されると、マイナーはそれを圧縮し、結果をブロックチェーンに送信します。これは、マイナーが保存することに同意したデータのコピーを実際に複製したことを証明するものです。

すべてのストレージマイナーは、セクターを保存し続けていることを証明するために、継続的に証拠をオンチェーンに提出する必要があります。

回収取引の手順

保管取引とは異なり、取り出し取引は主に支払いチャネルによって促進されるオフチェーンで行われます。データ送信は従量制で行われ、クライアントはデータが転送されるにつれてマイナーに段階的に支払います。支払いチャネルの作成とバウチャーの引き換えは、Filecoin ブロックチェーンとの対話を伴うプロセスの唯一の部分です。

全体的なプロセスは次のとおりです。

  1. ディスカバリー- クライアントは、必要なデータを持っているマイナーを特定し、バイトあたりの価格、開封価格、支払い間隔などの取得見積もりを要求します。
  2. 支払いチャネルのセットアップ- クライアントは、マイナーとの間に支払いチャネルをセットアップします (まだ存在しない場合)。
  3. 支払いを伴うデータ転送- マイナーは支払いが必要になるまでデータをクライアントに送信します。一定の閾値に達すると決済処理が要求され、その後はデータ転送が継続されます。マイナーがブロック ストアにデータを持っているかどうかに応じて、最初にそれをアンシールする必要がある場合があります。これは簡単ではなく瞬時ではない操作であり、ストレージ取引に関するセクションで説明したシールの逆です。

ファイルコインのデータ

ファイルを Filecoin に保存するには、クライアントはまずローカルの Filecoin ノードにファイルをインポートする必要があります。このステップでは、データ CID (コンテンツ識別子、コンテンツを一意に説明する ID) が生成されます。その後、データはマイナーに転送されます。

Filecoin ノードにローカルでデータをインポートするには、コマンドを使用しますlotus client import。後でマイナーからデータを取得するために使用する必要があるため、結果のデータ CID (後でローカル ノードでも使用可能になります)を覚えておくことが重要です。

ファイルコインピース

ファイルコイン ピースは、ユーザーがファイルコイン ネットワーク上に保存するデータのネゴシエーションの主要な単位です。Filecoin Piece は特定のサイズではありませんが、ネットワークのパラメータによって制御されるセクターのサイズによって上限が定められています。Filecoin ピースがマイナーがサポートするセクターのサイズよりも大きい場合は、各ピースがセクターに収まるようにファイルコイン ピースをより多くのピースに分割する必要があります。

Filecoin Piece は、独自のデータ/ペイロード CIDおよびピース CIDを持つIPLD DAGを含むCARファイルです。

CAR

CAR は、 Content Addressable aRchivesの略です。CARファイルは、ブロックの連結としてのIPLD DAG(Directed Acyclic Graph)のシリアル化表現と、ファイル内のグラフを記述するヘッダー (ルート CID を含む)です。

クライアントが Filecoin ネットワークにファイルを保存したい場合、 UnixFSを使用してファイルのIPLD DAGを生成することから始めます(これがコマンドの動作です)。DAG のルート ノードを表すハッシュは、データ/ペイロード CIDと呼ばれる IPFS スタイルのCIDです。

UnixFS は、 IPFS でファイル、ディレクトリ、およびシンボリックリンクを記述するための protobuf ベースの形式です。UnixFS は、Filecoin ネットワークに送信されるファイルのファイル形式ガイドラインとして Filecoin で使用されます。

結果のCARファイルには、バイナリ マークル ツリーを作成するために、余分なゼロ ビットが埋め込まれます。

FVMライブラリを利用するsample contract の作成

以下2種類がありますが、hardhat バージョンのほうがスクリプト動作が安定していたのでhardhatでおこないます。

補足: 当初foundry バージョンで始めましたがscript の実行時下記エラーが発生してうまくいきませんでした。 多分FVMは反映されるまで90秒程度またないといけないところが関係していると想像しています。

Error: 
Transaction dropped from the mempool: 0x49970389fb7291aeda2fbef34a9c1aa51781ec9306352cd8b8011ff5bf5c570e
  • hardhat deploy 手順
cd fevm-hardhat-kit
yarn 
export PRIVATE_KEY='abcdef'
yarn hardhat deploy
  • 動作確認
yarn hardhat get-balance --contract 'THE DEPLOYED CONTRACT ADDRESS HERE' --account 'YOUR ETHEREUM ADDRESS HERE'
Reading SimpleCoin owned by 0xXXX on network hyperspace
Amount of Simplecoin owned by 0xXXX is 12000
Total amount of minted tokens is 12000

上記で1200 と表示されていればOKです

Deal client contract による 保存リクエストの動作確認

hardhat のレポからリンクされている 下記のReadMeにそって作業を進めます
https://github.com/filecoin-project/fvm-starter-kit-deal-making/

car file 作成

car 変換ツールのbuild

(base) fevm-hardhat-kit % cd tools/go-generate-car
(base) go-generate-car % git submodule update --init
(base) go-generate-car % make

格納したいファイルを.car に変換

(base) go-generate-car % ./generate-car --single -i ./tmp/mynounsjp.jpg -o tmp -p ./tmp/      
{"Ipld":{"Name":"","Hash":"bafybeic7nmddrubj4okj27bg4cgpdtpoyydbgo2uzrzjf3zwwqr5aj3ti4","Size":0,"Link":[{"Name":"mynounsjp.jpg","Hash":"bafkreielgsyo5lowro6jtr2pswtvwyndjakalybisxo7otw7ojpb3qroay","Size":76983,"Link":null}]},"DataCid":"bafybeic7nmddrubj4okj27bg4cgpdtpoyydbgo2uzrzjf3zwwqr5aj3ti4","PieceCid":"baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni","PieceSize":131072,"CidMap":{"":{"IsDir":true,"Cid":"bafybeic7nmddrubj4okj27bg4cgpdtpoyydbgo2uzrzjf3zwwqr5aj3ti4"},"mynounsjp.jpg":{"IsDir":false,"Cid":"bafkreielgsyo5lowro6jtr2pswtvwyndjakalybisxo7otw7ojpb3qroay"}}}
(base) go-generate-car % ls tmp
baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni.car  test.json
mynounsjp.jpg
(base) go-generate-car % ll tmp
total 312
-rw-r--r--  1 takehararyuuji  staff  77181  6  1 05:51 baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni.car
-rw-r--r--@ 1 takehararyuuji  staff  76983  5 30 09:47 mynounsjp.jpg
-rw-r--r--  1 takehararyuuji  staff     62  5 30 09:50 test.json

web3.storageへup

https://web3.storage/
Signupして、作成したcar fileをUploadします。
わかりにくいですが、この時点ではまだweb3storageが提供しているipfsにUpしただけなので、filecoinの仕組みで永続化されてないです(web3storageが倒産したら、無くなってしまう状態) 。 ちなみにfilecoinに保存したいだけであれば、web3.storageを使えばUI操作だけでfilecoinに保存することもできますが、今回は仕組みの理解のためわざわざcontract でDealを発行したりしています。

cid をクリックして、ipfsのURLをコピーしておきます
例:
https://bafybeib6j373ttmwa62vjfqz3sfq2tqvfzf6bfw33o4uegfo5andn74sm4.ipfs.w3s.link/ipfs/bafybeib6j373ttmwa62vjfqz3sfq2tqvfzf6bfw33o4uegfo5andn74sm4/baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni.car

deal proposal の作成

作成した car に合わせて 以下のようなparameter を準備しておきます

  const DealRequestStruct = [
    "baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni", // pieceCID (Generated in previous step)
    131072, // pieceSize (Generated in previous step)
    false, // verifiedDeal (whether the deal has datacap or not)
    "baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni", // DataCID (generated in previous step)
    520000, // startEpoch (when you want the storage to start)
    1555200, // endEpoch (when you want the storage to end)
    0, // storagePricePerEpoch (how much attoFIL per GiB per 30s you are offering for this deal, set to 0 for a free deal)
    0, // providerCollateral (how much collateral the provider must put up for the deal)
    0, // clientCollateral (how much collateral you, the client, must put up for the deal)
    1, // extraParamsVersion (set to 1)
    extraParamsV1, // see below
  ];

    const extraParamsV1 = [
    "https://bafybeib6j373ttmwa62vjfqz3sfq2tqvfzf6bfw33o4uegfo5andn74sm4.ipfs.w3s.link/ipfs/bafybeib6j373ttmwa62vjfqz3sfq2tqvfzf6bfw33o4uegfo5andn74sm4/baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni.car", // carLink (Generated in previous step)
    77181, // carSize (Generated in previous step).
    false, // skipIpniAnnounce (whether or not the deal should be announced to IPNI indexers, set to false)
    false, // removeUnsealedCopy (whether or not the storage provider should remove an unsealed copy. Set to false)
  ];

hardhat を使い最初に作成したdeploy済みのdeal clientにリクエストをおくります。

DCLIENT=0x//hyperspace にDeployしたdeal client のETH形式アドレス
yarn hardhat make-deal-proposal --contract $DCLIENT --piece-cid baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni --piece-size 131072 --verified-deal false --label "baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni" --start-epoch 520000 --end-epoch 1555200 --storage-price-per-epoch 0 --provider-collateral 0 --client-collateral 0 --extra-params-version 1 --location-ref "https://bafybeib6j373ttmwa62vjfqz3sfq2tqvfzf6bfw33o4uegfo5andn74sm4.ipfs.w3s.link/ipfs/bafybeib6j373ttmwa62vjfqz3sfq2tqvfzf6bfw33o4uegfo5andn74sm4/baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni.car" --car-size 77181 --skip-ipni-announce false --remove-unsealed-copy false

ここで、 errorが発生。 Networkがない??
たまたま、filecoin のtestnet  hyperspace => calibrationnetの移行時期にかさなってしまったみたいです。。

git pull すると ちょうど昨日 hyperspace=>calibrationへの変更がmergeされていました。

しょうがないので calibration に再度ContractをDeployしてやりなおします。
当然faucetもしなおさないと gasが払えません。 ググるとcalibrationのfaucetは下記でできるようです
https://faucet.triangleplatform.com/filecoin/calibration

下記のようなログがでて無事proposalIdが発行されました。

hardhat make-deal-proposal --contract 0x0856f4E2c3Df2A1f5A205aea14DEe6D6462F6fC7 --piece-cid baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni --piece-size 131072 --verified-deal false --label baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni --start-epoch 520000 --end-epoch 1555200 --storage-price-per-epoch 0 --provider-collateral 0 --client-collateral 0 --extra-params-version 1 --location-ref https://bafybeib6j373ttmwa62vjfqz3sfq2tqvfzf6bfw33o4uegfo5andn74sm4.ipfs.w3s.link/ipfs/bafybeib6j373ttmwa62vjfqz3sfq2tqvfzf6bfw33o4uegfo5andn74sm4/baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni.car --car-size 77181 --skip-ipni-announce false --remove-unsealed-copy false
Making deal proposal on network calibrationnet
Complete! Event Emitted. ProposalId is: 0x1038f02496c508802de2bdb1abd85179484ce27ba14c292588671aec8f9f56c4
✨  Done in 62.52s.

Boostは?? Storage Providerからの応答は??

ここまで順調にすすんできましたが、 さていよいよこのDealにどうSP(StorageProvider)が答えてくれるのかドキドキしますが FilecoinのBlockExplorerでContractのイベントをみても何も反応ありません。

deal-status をみても変わる気配がありません。

(base) fevm-hardhat-kit % yarn hardhat get-deal-status --contract $DCLIENT --piece-cid baga6ea4seaqgiu5zj3poqkyd3buszz4rp7e6y3dity2qjzibg5rkzra2kyhvyni  
Getting deal status on network calibrationnet
The deal status is: 1

GithubのReadmeに乗っているシーケンスをみると DealProposalCreate EventをなげるとBoostSPが反応してくれるように期待できるのですが、、

event DealProposalCreate(
    bytes32 indexed id,
    uint64 size,
    bool indexed verified,
    uint256 price
);

testnetだからか、それともまだこのFVM対応シーケンスが議論段階だからなのか
このつぎの StorageProvierが反応してCARをDLして格納してくれるところまでは
動作確認することはできませんでした。 残念。 Dealを出すまではだいぶ理解が進みました。

Discussion