ユーザ用ツール

サイト用ツール


blockchain:dappsからipfsにファイルをアップロードする

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
blockchain:dappsからipfsにファイルをアップロードする [2022/06/06 02:02] dotblockchain:dappsからipfsにファイルをアップロードする [2022/06/16 12:54] (現在) dot
行 1: 行 1:
  
 +====== DAppsからIPFSにファイルをアップロードする ======
 +
 +React で Web アプリケーションを実装し、HTML の FILE API で指定されたファイルを IPFS にアップロードする機能を実現します。
 +
 +===== React プロジェクトの作成 =====
  
 <code JavaScript> <code JavaScript>
行 6: 行 11:
 IPFS> npx create-react-app ipfs-web --template typescript IPFS> npx create-react-app ipfs-web --template typescript
 IPFS> cd .\ipfs-web\ IPFS> cd .\ipfs-web\
-IPFS\ipfs-web> npm install --save ipfs-core ipfs-core-types+IPFS\ipfs-web> npm install --save ipfs-core ipfs-core-types util
 </code> </code>
 +
 +「[[https://github.com/ipfs/js-ipfs|ipfs-core]]」は JavaScript で IPFS を操作するためのライブラリ js-ipfs の一部です。
 +
 +===== 参考 =====
 +
 +  * [[https://github.com/ipfs-examples/js-ipfs-examples|js-ipfs-examples]]
 +  * [[https://github.com/ipfs/js-ipfs/tree/master/docs/core-api|IPFS Core API]]
 +
 +===== IPFSUploader.tsx の実装 =====
 +
 +IPFS にファイルをアップロードする機能を提供する IPFSUploader.tsx コンポーネントを実装します。
 +
 +<code PowerShell>
 +IPFS\ipfs-web> mkdir src\components
 +IPFS\ipfs-web> code src\components\IPFSUploader.tsx
 +</code>
 +
 +<code JavaScript>
 +import React, { useState, useEffect } from 'react';
 +import type { IPFS } from 'ipfs-core-types';
 +import * as IPFSCore from 'ipfs-core';
 +
 +let ipfs: IPFS;
 +
 +function IPFSUploader() {
 +    const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs))
 +    const [version, setVersion] = useState("");
 +    const [cid, setCID] = useState("");
 +
 +    useEffect(() => {
 +        startIpfs();
 +        return function cleanup () {
 +            if (ipfs && ipfs.stop) {
 +                console.log('Stopping IPFS');
 +                ipfs.stop().catch((err: any) => console.error(err));
 +                //ipfs = undefined;
 +                setIpfsReady(false);
 +            }
 +        }
 +    }, []);
 +
 +    const startIpfs = async () => {
 +        if(ipfs){
 +            console.log('IPFS already started');
 +        /*
 +        } else if (window.ipfs && window.ipfs.enable) {
 +            console.log('Found window.ipfs')
 +            ipfs = await window.ipfs.enable({ commands: ['id'] })
 +        */
 +        } else {
 +            ipfs = await IPFSCore.create();
 +            console.log("IPFS Started");
 +            const _version = await ipfs.version();
 +            setVersion(_version.version);
 +        }
 +        setIpfsReady(Boolean(ipfs));
 +    };
 +    const fileSelected = async (event: React.ChangeEvent<HTMLInputElement>) => {
 +        if(!isIpfsReady) return;
 +
 +        const targetFile = event.target.files?.[0];
 +        if(targetFile){
 +            const _result = await ipfs.add(targetFile);
 +            //const _result = await ipfs.add('Hello world');
 +            setCID(_result.path);
 +        }
 +    };
 +
 +  return (
 +    <div>
 +        <h1>IPFS File Uploader</h1>
 +        <p>IPFS(ipfs-core) Version: { version }</p>
 +        <input id="input-file" type="file" onChange={fileSelected} disabled={!isIpfsReady}></input>
 +        <div>
 +            <p>Uploaded File CID: { cid }</p>
 +            <p><a href={`ipfs://${cid}`} target="_blank">open browser</a></p>
 +            <p><a href={`https://ipfs.io/ipfs/${cid}`} target="_blank">open ipfs.io public gateway</a></p>
 +        </div>
 +    </div>
 +  );
 +}
 +
 +export default IPFSUploader;
 +</code>
 +
 +===== App.tsx に IPFSUploader を追加 =====
 +
 +<code PowerShell>
 +IPFS\ipfs-web> code src\App.tsx
 +</code>
 +
 +不要な記述を削除し、IPFSUploader コンポーネントを追加します。
 +
 +<code JavaScript>
 +import React from 'react';
 +import './App.css';
 +import IPFSUploader from './components/IPFSUploader';
 +
 +function App() {
 +  return (
 +    <div className="App">
 +      <header className="App-header">
 +        <IPFSUploader/>
 +      </header>
 +    </div>
 +  );
 +}
 +
 +export default App;
 +</code>
 +
 +
 +===== 実行 =====
 +
 +<code PowerShell>
 +IPFS\ipfs-web> npm start
 +</code>
 +
 +
 +
 +===== IPFSDirectoryUploader =====
 +
 +MFS を利用してファイルをアップロードする。
 +<code PowerShell>
 +IPFS\ipfs-web> code src\components\IPFSDirectoryUploader.tsx
 +</code>
 +
 +<code JavaScript>
 +import React, { useState, useEffect } from 'react';
 +import type { IPFS } from 'ipfs-core-types';
 +import * as IPFSCore from 'ipfs-core';
 +import { MFSEntry } from 'ipfs-core-types/dist/src/files/index';
 +
 +let ipfs: IPFS;
 +
 +function IPFSDirectoryUploader() {
 +    const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs))
 +    const [version, setVersion] = useState("");
 +    const [MFSEntlies, setMFSEntlies] = useState<MFSEntry[]>();
 +
 +    useEffect(() => {
 +        startIpfs();
 +        return function cleanup () {
 +            if (ipfs && ipfs.stop) {
 +                console.log('Stopping IPFS');
 +                ipfs.stop().catch((err: any) => console.error(err));
 +                //ipfs = undefined;
 +                setIpfsReady(false);
 +            }
 +        }
 +    }, []);
 +
 +    const startIpfs = async () => {
 +        if(ipfs){
 +            console.log('IPFS already started');
 +        /*
 +        } else if (window.ipfs && window.ipfs.enable) {
 +            console.log('Found window.ipfs')
 +            ipfs = await window.ipfs.enable({ commands: ['id'] })
 +        */
 +        } else {
 +            ipfs = await IPFSCore.create();
 +            console.log("IPFS Started");
 +            const _version = await ipfs.version();
 +            setVersion(_version.version);
 +
 +            const lsResult = await ipfs.files.ls("/");
 +            let uploadDirectoryExist = false;
 +            for await (const file of lsResult){
 +                if(file.name === "upload-directory"){
 +                    console.log("/upload-directory is already exist.");
 +                    uploadDirectoryExist = true;
 +                }
 +            }
 +            if(!uploadDirectoryExist){
 +                console.log("mkdir /upload-directory");
 +                await ipfs.files.mkdir("/upload-directory");
 +            }
 +        }
 +        setIpfsReady(Boolean(ipfs));
 +    };
 +    const fileSelected = async (event: React.ChangeEvent<HTMLInputElement>) => {
 +        if(!isIpfsReady) return;
 +
 +        const targetFile = event.target.files?.[0];
 +        if(targetFile){
 +            const fileReader = new window.FileReader();
 +            fileReader.readAsArrayBuffer(targetFile);
 +            fileReader.onloadend = async () => {
 +                let ab = fileReader.result as ArrayBuffer;
 +                const u8a = new Uint8Array(ab);
 +                console.log(`upload /upload-directory/${targetFile.name}`);
 +                await ipfs.files.write(`/upload-directory/${targetFile.name}`, u8a, {create: true});
 +                await ls("/upload-directory");
 +            };
 +        }
 +    };
 +    const ls = async (path: string) => {
 +        const lsResult = await ipfs.files.ls(path);
 +        for await (const file of lsResult){
 +            console.log(`${file.name}: ${file.cid.toString()}`);
 +        }
 +    };
 +    const MFSStat = async () => {
 +        if(!isIpfsReady) return;
 +
 +        const lsResult = await ipfs.files.ls('/upload-directory');
 +        let _mfs_entlies: MFSEntry[] = [];
 +        for await (const file of lsResult){
 +            console.log(`${file.name}: ${file.cid.toString()}`);
 +            _mfs_entlies.push(file);
 +        }
 +        setMFSEntlies(_mfs_entlies);
 +    };
 +
 +  return (
 +    <div>
 +        <h1>IPFS File Uploader</h1>
 +        <p>IPFS(ipfs-core) Version: { version }</p>
 +        <input id="input-file" type="file" onChange={fileSelected} disabled={!isIpfsReady}></input>
 +        <div>
 +            <p><button onClick={MFSStat}>MFS Stat</button></p>
 +            <p>
 +                { MFSEntlies?.map((file) => (
 +                    <div>
 +                        <p>{file.name}: {file.cid.toString()}</p>
 +                        <p>
 +                            <a href={`https://ipfs.io/ipfs/${file.cid.toString()}`} target="_blank" rel="noreferrer">Open</a>
 +                            <img src={`https://ipfs.io/ipfs/${file.cid.toString()}`} alt="IPFS img link."/>
 +                        </p>
 +                    </div>
 +                ))}
 +            </p>
 +        </div>
 +    </div>
 +  );
 +}
 +
 +export default IPFSDirectoryUploader;
 +</code>
 +
 +App.tsx に IPFSDirectoryUploader コンポーネントを記述する。
blockchain/dappsからipfsにファイルをアップロードする.1654480966.txt.gz · 最終更新: 2022/06/06 02:02 by dot