Crust Wiki

Crust Wiki

  • 文档
  • 主网
  • 贡献
  • Languages icon中文
    • English
    • Help Translate

›构建

概览

  • 开始
  • Shadow Bridge
  • CSM 认领

学习

  • 即将到来

构建

  • 即将到来

节点

  • 即将到来

存储

  • 即将到来

Maxwell

    概览

    • 开始
    • 预览网 Maxwell
    • Crust Grants
    • Ethereum Bridge
    • CRU 转回
    • CRU18 认领
    • CSM 转回
    • Crust 钱包
    • 术语表
    • 社区
    • 贡献

    学习

    • 账户
    • Crust 通证
    • 新增绑定
    • sWorker
    • 担保人
    • 验证人
    • 存储商户
    • GPoS
    • 去中心化存储市场
    • BitSwap
    • 民主指南

    构建

    • 开始
    • Hello Crust
    • Crust Rocky Network
    • 代码示例:使用Crust
    • Crust SDK
    • 总览
    • 部署和运行网站
    • 内容存储与分发
    • NFT数据存储
    • Crust Storage Manager
    • Crust Node

    节点

    • 节点概要
    • 节点硬件指南
    • Owner 节点
    • Member 节点
    • Isolation 节点
    • 验证人指南
    • 担保人指南
    • 参数表
    • Q&A

    存储

    • 概览
    • 存储用户指南
    • 存储商户指南
    • 存储订单清算指南
    • 使用Crust Apps 存储的问题
    • Crust 存储浏览器
    • Q&A
Translate

代码示例:使用Crust

This doc contains a code sample to demonstrate how to upload a file to IPFS, and place a storage order to get the file stored in Crust Network. After that, the file can be retrieved via standard IPFS interface and gateway from anywhere. This scenario is simple but generic. It can be widely applied in WebSite/DApp frontend hosting, content/media delivery, cloud storage, etc.

The code sample is open source on GitHub repo: https://github.com/crustio/crust-demo

1 Overview

1.1 Storage process

Using IPFS and Crust Network, developers can follow below process to upload, store and distribute files:

  • Upload the file to IPFS, and get the file CID (a unique identifier generated based on the content of each file) and file Size (the actual size of the file stored in IPFS, which is different from the original file size)
  • Use the CID and Size of the file to place a storage order on the Crust chain. The given size should be no smaller than the actual file size.
  • Obtain and monitor order status

The process should be executed sequentially to ensure that the files are stored smoothly by the Crust network。

1.2 Dependencies

The code sample mainly depends on the following libraries:

  • @crustio/type-definitions Custom data type, used to adapt to Crust network
  • @polkadot/api The polkadot api library provides a Promise-style interface for performing related operations on the Crust chain
  • ipfs-core ipfs library, contains all the functions of ipfs

2 Description

2.1 Upload files to IPFS

Before interacting with the IPFS network, an instance of ipfs needs to be instantiated. The code is as follows:

import IPFS from 'ipfs-core';

// Start local ipfs, ipfs base folder will be $USER/.jsipfs
const ipfs = await IPFS.create()

Then you can use ipfs.add(fileContent, options) to upload a file into IPFS, fileContent can be any of the following types:Uint8Array | Blob | String | Iterable<Uint8Array> | Iterable<number> | AsyncIterable<Uint8Array> | ReadableStream<Uint8Array>. The following code will return two values, namely CID and Size

async function addFile(ipfs: IPFS.IPFS, fileContent: any) {
    // Add file to ipfs
    const cid = await ipfs.add(
        fileContent,
        {
            progress: (prog) => console.log(`Add received: ${prog}`)
        }
    );

    // Get file status from ipfs
    const fileStat = await ipfs.files.stat("/ipfs/" + cid.path);

    return {
        cid: cid.path,
        // Needs to be cumulativeSize
        size: fileStat.cumulativeSize
    };
}

2.2 Initialize API instance and on-chain identity

You need to initialize an instance of api to interact with the Crust network. The code is as follows:

import { ApiPromise, WsProvider } from '@polkadot/api';
import { typesBundleForPolkadot, crustTypes } from '@crustio/type-definitions';

// WS address of Crust chain
const chain_ws_url = "ws://127.0.0.1:9933";

// Connect to chain
const api = new ApiPromise({
    provider: new WsProvider(chain_ws_url),
    typesBundle: typesBundleForPolkadot,
});

Also, you need to get the identity krp on the chain to send the order transaction. It can be generated from the seeds of the account (please ensure that the account has enough CRUs for sending storage orders):

/* eslint-disable node/no-extraneous-import */
import {Keyring} from '@polkadot/keyring';
import {KeyringPair} from '@polkadot/keyring/types';

// Seeds of account
const seeds = "echo xxxx soccer xxxx catch xxxx stone xxxx pumpkin nest merge xxxx";

const kr = new Keyring({
    type: 'sr25519',
});

// krp will be used in sending transaction
const krp = kr.addFromUri(seeds);

2.3 Place storage order

You can use the following code to determine whether the chain is synchronized to the latest block:

/**
  * Used to determine whether the chain is synchronizing
  * @param api chain instance
  * @returns true/false
  */
async function isSyncing(api: ApiPromise) {
    const health = await api.rpc.system.health();
    let res = health.isSyncing.isTrue;

    if (!res) {
        const h_before = await api.rpc.chain.getHeader();
        await delay(3000);
        const h_after = await api.rpc.chain.getHeader();
        if (h_before.number.toNumber() + 1 < h_after.number.toNumber()) {
            res = true;
        }
    }

    return res;
}

After waiting for the chain to synchronize to the latest block, you can interact with the chain to place a storage order. Note that the fileSize must be the cumulativeSize obtained in the previous step. If it is smaller than the cumulativeSize, the order will fail:

/**
 * Place stroage order
 * @param api chain instance
 * @param fileCID the cid of file
 * @param fileSize the size of file in ipfs
 * @param tip tip for this order
 * @return true/false
 */
async function placeOrder(api: ApiPromise, krp: KeyringPair, fileCID: string, fileSize: number, tip: number) {
    // Determine whether to connect to the chain
    await api.isReadyOrError;
    // Generate transaction
    const pso = api.tx.market.placeStorageOrder(fileCID, fileSize, tip);
    // Send transaction, for 'sendTx()' please refer https://github.com/crustio/crust-demo/blob/main/sample-store-demo/src/utils.ts
    const txRes = JSON.parse(JSON.stringify((await sendTx(krp, pso))));
    return JSON.parse(JSON.stringify(txRes));
}

2.4 Get order status

In general, the order stauts is updated every half an hour. You can query the status of the order through api.query.market.files()

/**
 * Get on-chain order information about files
 * @param api chain instance
 * @param cid the cid of file
 * @return order state
 */
async function getOrderState(api: ApiPromise, cid: string) {
    await api.isReadyOrError;
    return await api.query.market.files(cid);
}

If the order does not exist, it will return none. If the order exists, it will return the following data structure, where expired_on is compared with the current block height to determine whether it has expired. If reported_replica_count is 0, the order is still in progress, if it is greater than 0 , and if it has not expired, the order is successful.

{
    "file_size": 186,
    "expired_on": 12314,
    "claimed_at": 12164,
    "amount": 92812500,
    "expected_replica_count": 2,
    "reported_replica_count": 1,
    "replicas": [
        {
            "who": "5Ck95aKKQHiFd2W8gfrbqiF8u7L4DSEYqBazA3iqbCgncj4H",
            "valid_at": 12094,
            "anchor": "0x9a59000c5a3e5f8f6261e09cc8b77c98d2c45bac0a2af7a151d97a392b927b074c6d580053e50f11325ca0dc3f2135eb4372b6f4e73329f99705208a31c4d728",
            "is_reported": true
        }
    ]
}

3 Github Link

Please refer to this link

← Crust Rocky NetworkCrust SDK →
  • 1 Overview
    • 1.1 Storage process
    • 1.2 Dependencies
  • 2 Description
    • 2.1 Upload files to IPFS
    • 2.2 Initialize API instance and on-chain identity
    • 2.3 Place storage order
    • 2.4 Get order status
  • 3 Github Link
Docs
Getting StartedCRU ClaimsWebsite Hosting with CrustNFT Data Storage with Crust
Community
DiscordTwitterTelegram
More
CooperationGitHub
Copyright © 2025 Crust Network