This article will show you how to deploy FEVM-compatible smart contracts as deal clients on the Filecoin network. We will deploy the contract to Hyperspace, a developer-oriented test network. Hold on, you are wondering what is even this FEVM? We will start with some basics!

The Filecoin virtual machine (FVM) is a runtime environment for user-deployed smart contracts, known as actors, on the Filecoin network. You can find more details and its roadmap at https://fvm.filecoin.io. In March, developers can deploy EVM compatible smart contracts on FEVM, and later on any language that compiles to WASM on FVM.

Another question you might have is how does the Filecoin Virtual Machine come into play in today's Filecoin storage market?

The Filecoin Virtual Machine unlocks boundless possibilities, ranging from programmable storage primitives (such as storage bounties, auctions, and more) to data-centric Decentralized Autonomous Organizations (DAOs).

🎉Introducing PeSto

The Lotus team has been working on prototyping smart contracts that can enable storage marketplace primitives, codenamed PeSto. With this project, we want to enable developers to more easily understand the deal-making flow in the Filecoin network, and provide a solid deal client smart contract example that includes perpetual storage capabilities which can be deployed or further developed.

The project is still a WIP and there are currently a lot of intermediate steps! You can follow along the journey in this Github repo or the workshop at our Youtube channel! That being said, let´s take a look at how a bare minimum client contract works today by inspecting the deal client contract flow and the flow on the storage provider side.

📋The Client Contract

<aside> 💙 If you prefer to follow along with demos, head to our Youtube channel playlist - Workshop: Data Client Contracts, Perpetual Storage and Data Daos on Filecoin!

</aside>

The Client contract is located in this repo, please go through the README before moving forward...

Now that you know what a client contract is, lets jump right into it by deploying the DealClient contract to the HyperSpace network before we go into the flow of the contract.

Deploying the contract

You can import the DealClient.sol contract to Remix with this Github-link:

	<https://github.com/lotus-web3/client-contract/blob/main/src/DealClient.sol>

Importing DealClient.sol contract into Remix

Importing DealClient.sol contract into Remix

We need to comment out the first import line in DealClient.sol to be able to compile the contract:

Comment out the first import line in DealClient.sol

Comment out the first import line in DealClient.sol

Before we can deploy the contract to the Hyperspace network, we need to set up our Metamask wallet to interact with the Hyperspace network. Go to chainlist.wtf, search for the Filecoin Hyperspace, click Connect Wallet, and add the Hyperspace testnet to Metamask.

Screenshot 2023-01-31 at 20.29.34.png

Once you have your MetaMask set up you can request funds for your wallet address with the Hyperspace faucet. It might take a couple of minutes before testFIL lands in your wallet. Now we are ready to deploy the contract:

Deploying the client contract to the Hyperspace network

Deploying the client contract to the Hyperspace network

Once the message has been included in a block (it can take a couple of minutes) you should see a log of it in your Remix console.

Screenshot 2023-01-31 at 20.42.56.png

Open the transaction information by clicking on the debug button, copy the transaction hash and paste it into a Hyperspace chain explorer to inspect the contract. Your contract is now live on the Filecoin Hyperspace network ✅.

For developers: Client contract flow

<aside> ⚠️ Let’s stop here for a moment and explain a couple of IPFS and Filecoin related terms and formats before we go on!

</aside>

The CAR format

So what is this CAR thing? CAR stands for Content Addressable aRchives, and it is a format for bundling InterPlanetary Linked Data, IPLD, blocks into a large bundle. On the Filecoin network the majority of data is stored as large IPLD blocks.

You can read more about the CAR format here.

Sectors A sector is the default unit of storage that storage providers submit to the Filecoin network. On the mainnet storage providers can decide if they want to commit 32 GiB or 64 GiB sector sizes when they first initialize their storage provider on-chain. On the Hyperspace test network 512MiB sectors are also supported. A sector can contain data from multiple deals and clients.

PieceCID also known as commP (piece commitment)

The piece content identifier (CID) also known as commP (piece commitment), is the merkle root of the CAR file. We need to store this data in the deal information because it tells us where to find the deal data in a sector, which can be composed of several deals.


<aside> 💡 There are many toolings that developers can use for data preparation that’s provides simpler user experience, you can find more details here. In this tutorial, we will use lotus for demo purpose.

</aside>

Great! Now that we understand those concepts, lets start by generating a .CAR testfile using the car - The CLI tool. You can install the latests version with:

go install github.com/ipld/go-car/cmd/car@latest

With this tool we can create a CAR test file with the commands:

touch testfile.txt 
car create --version=1 --file testcar testfile.txt

We now have a CAR-file which we can inspect and get information about:

car inspect testcar                              
Version: 1
Roots: bafybeiamsh53xue7b42l4oflgbdoypled5w5hvijegjhrrjll57f2uk74u
Root blocks present in data: Yes
Block count: 2
Min / average / max block length (bytes): 60 / 85 / 110
Min / average / max CID length (bytes): 36 / 36 / 36
Block count per codec:
	raw: 1
	dag-pb: 1
CID count per multihash:
	sha2-256: 2

We can now compute the pieceCID/commP for the testfile using this lotus command:

lotus client commP testcar
CID:  baga6ea4seaqnyo6tkwpdme66jelyvyeucbb3a2njnhag5zzyls33otg7ll6bsni
Piece size:  508 B
Piece size in bytes:  508

Before we continue it is also useful to know what the padded piece size of the commP, as we will need to input the padded size into the addCID in the contract. For this we can either use a tool like stream-commp, or manually round it to the next power of 2.

cat testcar | stream-commp

CommPCid: baga6ea4seaqnyo6tkwpdme66jelyvyeucbb3a2njnhag5zzyls33otg7ll6bsni
Payload:                 304 bytes
Unpadded piece:          508 bytes
Padded piece:            512 bytes

CARv1 detected in stream:
Blocks:         2
Roots:          1
    1: bafybeiamsh53xue7b42l4oflgbdoypled5w5hvijegjhrrjll57f2uk74u

Great, now we have the commP for this testfile. As we can see in our Remix Deployed Contracts dashboard we will have to turn this value into raw bytes:

The addCID in the contract only takes in raw bytes because it does not have a concept of CID.

The addCID in the contract only takes in raw bytes because it does not have a concept of CID.

We can turn the commP into raw bytes using the lotus-shed tool.

./lotus-shed cid cborSer baga6ea4seaqnyo6tkwpdme66jelyvyeucbb3a2njnhag5zzyls33otg7ll6bsni
0181e203922020dc3bd3559e3613de49178ae0941043b069a969c06ee7385cb7b74cdf5afc1935

Now we are finally ready to add this CID to our contract. Take the output from the ./lotus-shed cid cborSer baga… output, append 0x00 in front of it and paste into cidraw. The size should be the padded size that we found in the step where we generated the CAR file and inspected it:

addCID.mov

Great! We have now deployed the contract and added a CID to the contract. We can use the lotus evm stat command to get more information about our contract:

lotus evm stat 0x287064f4E0e1f497edBB5141D19f556d6ede8B2e
ID address:  t06001
Code cid:  bafk2bzacea6etsvrqejjl7uej5dxlswja5gxzqyggsjjvg27timvtiedf7nsg
Actor Type:  fil/11/evm
Filecoin address:  t410ffbygj5ha4h2jp3n3kfa5dh2vnvxn5czocemvdpa
Eth address:  0x287064f4e0e1f497edbb5141d19f556d6ede8b2e

For Storage Providers(SPs) - Onboard a Deal From the Client Contract

Storage providers have a new command for interacting asynchronously with a client contract: lotus-miner storage-deals async-contract-deal

NAME:
   lotus-miner storage-deals async-contract-deal - Async deal with client contract

USAGE:
   lotus-miner storage-deals async-contract-deal [command options] <commP> <commPSize> <clientAddr> <startEpoch> <duration> <carFile>

OPTIONS:
   --help, -h  show help (default: false)

The command takes in a number arguments commP,commPSize, clientAddr, startEpoch, duration and carFile. When the storage provider executes the command it will start the asynchronous deal making process with the client contract. For the contract example and data in this guide the values would be:

commP - baga6ea4seaqnyo6tkwpdme66jelyvyeucbb3a2njnhag5zzyls33otg7ll6bsni

commPSize (unpadded) - 508

clientAddr (ID address of the contract) - t06001

startEpoch (block height) - 47200 - this must be set higher then the current block height, and should also take into account the sealing time as the sector must be sealed before the startEpoch.

duration (in epochs) - 576000

This process includes verification where the contract will authenticate making a deal for the given CID, it will create and publish a PublishStorageDeal (PSD) message which will show the deal details on-chain and it will create or add the data to a sector and seal it. Yes it’s just as easy as your other deal onboarding flow, see the whole flow in the video below if you wanna know more(starting 4’15’’)!

https://www.youtube.com/watch?v=uUpMZaTUC48&list=PLhmonklIHGmXu_uJ9JBvB6bA7hGb7tsXT&index=2

If you wanna try it out, join Hyperspace testnet and run your miner with this branch.

🤩Whats next

You might have noticed that this article skipped an essential step - How does the the storage provider get the data in the first place?

Going forward we will look at multiple possibilities, but one idea that we are currently exploring is enriching the client contract with more deal information and emitting events on actions like addCID. This would allow an consumer of these event (either an SP or a third party) to subscribe the events and trigger deal creation accordingly.

We are also going to show how you can make client contracts as a verified client so that it can enjoy the cheap storage provided by Filecoin storage providers.

Contact Us

<aside> 💙 We would love to hear questions and feedbacks from you!

</aside>

Slack: #fil-lotus-announcements #fil-lotus-dev at filecoin.io/slack

GitHub: https://github.com/orgs/lotus-web3/

Twitter: https://twitter.com/lotus_web3 ****(follow us!)

Youtube: @lotus_web3 (Subscribe!)