5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Reactを使用したIPFSへのデータアップロードアプリを作った

Last updated at Posted at 2019-12-28

#要約
ReactとIPFSを使って、IPFSにデータを保存しそのハッシュ値を得るアプリを作った。
IPFSアップローダー:https://ipfsuploader-d6luh021e.now.sh/
ソースコード:https://github.com/andynuma/ipfs-uploader

#IPFS
Ethereumを用いたDappの開発で大きなデータをEthereumに保存しようとした場合に、Ethereumではデータの容量に制限があるため、大きなデータは保存できない。そこで、[IPFS]
(https://ipfs.io)が使用される場合がある。IPFSは簡単に言うとデータのハッシュ値を保存して、そのハッシュ値を指定すればデータが取得できるコンテンツ指向プロトコル。

#Reactでのipfs呼び出し
ipfs-apiを使用。
参考:https://github.com/ipfs/js-ipfs-http-client
##文字列アップロード
文字列をIPFSに送信する時のソースコードを以下に示す。

import React, { FC, useState } from 'react';
import { Form, Button, Segment, Message } from 'semantic-ui-react';
import { getTextIpfsHash } from '../../utils/getIpfsHash';

const TextUpLoader: FC = () => {
  const [inputText, setText] = useState('');
  const [resultHash, setResultHash] = useState('');
  const [load, setLoad] = useState<boolean>(true);
  const [end, setEnd] = useState(false);

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setLoad(false);
    const res = await getTextIpfsHash(inputText);
    setResultHash(res);
    setEnd(true);
  };

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setText(event.target.value);
  };

  return (
    <>
      <h1>Text Uploader</h1>
      <Segment.Group>
        <Segment>
          <Form onSubmit={handleSubmit}>
            <Form.Field>
              <input
                placeholder="Input data"
                value={inputText}
                onChange={handleChange}
              />
            </Form.Field>
            <Button type="submit">Submit</Button>
          </Form>
          {load ? <></> : <Message as="h3">Uploading...</Message>}
          {end ? <Message positive>End</Message> : <></>}
          <Segment>IPFS Hash : {resultHash}</Segment>
          <Segment>
            IPFS Link is{' '}
            <a
              href={`https://ipfs.io/ipfs/${resultHash}`}
              target="_blank"
              rel="noreferrer noopener"
            >
              here
            </a>
          </Segment>
        </Segment>
      </Segment.Group>
    </>
  );
};

export default TextUpLoader;

###動作例

スクリーンショット 2019-12-28 18.25.06.png

IPFSのハッシュ値とそのデータへのURLが表示されている。

##ファイルアップロード

import React, { useState } from 'react';
import { Segment, Form, Input, Button, Message } from 'semantic-ui-react';
import { getImageIpfsHash } from '../../utils/getIpfsHash';

const FileUpLoader = () => {
  const [buffer, setBuffer] = useState<ArrayBuffer>(new ArrayBuffer(0));
  const [resultHash, setResultHash] = useState('');
  const [load, setLoad] = useState<boolean>(true);
  const [end, setEnd] = useState(false);

  const handleChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files as FileList;
    const reader = new window.FileReader();
    reader.readAsArrayBuffer(files[0]);
    reader.onloadend = () => {
      const res = reader.result as string;
      setBuffer(Buffer.from(res));
      console.log(reader.result);
    };
    console.log(buffer);
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    console.log('submitted...');
    setLoad(false);
    const hash: string = await getImageIpfsHash(buffer);
    setResultHash(hash);
    console.log(hash);
    setEnd(true);
  };

  return (
    <>
      <h1>File Uploader</h1>
      <Segment.Group>
        <Segment>
          <Form onSubmit={handleSubmit}>
            <Form.Field>
              <Input type="file" onChange={handleChange}></Input>
            </Form.Field>
            <Button>Submit</Button>
          </Form>
        </Segment>
        {load ? <></> : <Message as="h3">Uploading...</Message>}
        {end ? <Message positive>End</Message> : <></>}
        <Segment>IPFS Hash : {resultHash}</Segment>
        <Segment>
          IPFS Link is{' '}
          <a
            href={`https://ipfs.io/ipfs/${resultHash}`}
            target="_blank"
            rel="noreferrer noopener"
          >
            here
          </a>
        </Segment>
      </Segment.Group>
    </>
  );
};

export default FileUpLoader;

###動作例

スクリーンショット 2019-12-28 18.28.21.png

ファイルのhash値が表示されており、リンクをクリックするとスクリーンショットが表示される。

Ethereumとの連携

IPFSを使用するのはDappでの使用が多い。ここではDappの開発で人気のEthereumにデータを保存する場合を考える。Ethereumには大きなデータを格納することはできないため、IPFSのハッシュ値を保存する。
これはかなり簡単でipfs-apiを使用してデータをIPFSに送信し保存、その後データのハッシュ値を取得してそのハッシュ値をコントラクトの関数の引数などに与えてデータを送信すれば良い。

コントラクトにSetDataという関数があるとする。その関数の引数にipfsのハッシュ値を渡すだけである。以下にフォームハンドラを示す。

const handleSubmit = async e => {
    e.preventDefault();
    setLoad(false);

    // ipfsに送信するためのcontent作成
    const content = ipfs.Buffer.from(e.target.value);

    // add
    const results = await ipfs.add(content);

    // hashを取得
    const hash = await results[0].hash;

    // ipfsのハッシュ値をチェーンに記録
    try {
      await setData(hash);
      setEnd(true);
    } catch (err) {
      setError(err.message);
    }

  };

#まとめ
IPFSにデータを送信してそのハッシュ値を得るアプリを作った(個人的にipfsを使用することがありハッシュ値の確認をしたかった)。

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?