오프체인 IP(예: 책, 캐릭터, 그림 등)가 있다고 가정해 봅시다. Story에서 해당 IP를 등록하려면 먼저 NFT를 발행해야 합니다. 이 NFT는 IP에 대한 소유권입니다. 그런 다음 등록하여 Story에서 IP 자산으로 만듭니다. 아래 튜토리얼에서 이 과정을 안내해 드리겠습니다.

사전 준비사항

튜토리얼을 시작하기 전에 완료해야 할 몇 가지 단계가 있습니다.

  1. TypeScript SDK 설정TypeScript SDK 설정
  2. [선택사항] Pinata로 이동하여 새 API 키를 생성하세요. JWT를 .env file:
.env
PINATA_JWT=<YOUR_PINATA_JWT>
  1. [선택사항] pinata-web3 dependency:
Terminal
npm install pinata-web3

1. [선택사항] IP 메타데이터 설정

NFT와 IP에 메타데이터를 설정할 수 있지만, 필수는 아닙니다. 이를 위해 IPA 메타데이터 표준을 확인하고 NFT와 IP 모두에 대한 메타데이터를 구성하세요.

main.ts
// you should already have a client set up (prerequisite)
import { client } from "./utils";

async function main() {
  const ipMetadata = {
    title: "Ippy",
    description: "Official mascot of Story.",
    image:
      "https://ipfs.io/ipfs/QmSamy4zqP91X42k6wS7kLJQVzuYJuW2EN94couPaq82A8",
    imageHash:
      "0x21937ba9d821cb0306c7f1a1a2cc5a257509f228ea6abccc9af1a67dd754af6e",
    mediaUrl:
      "https://ipfs.io/ipfs/QmSamy4zqP91X42k6wS7kLJQVzuYJuW2EN94couPaq82A8",
    mediaHash:
      "0x21937ba9d821cb0306c7f1a1a2cc5a257509f228ea6abccc9af1a67dd754af6e",
    mediaType: "image/png",
    creators: [
      {
        name: "Story Foundation",
        address: "0x67ee74EE04A0E6d14Ca6C27428B27F3EFd5CD084",
        description: "The World's IP Blockchain",
        contributionPercent: 100,
        socialMedia: [
          {
            platform: "Twitter",
            url: "https://twitter.com/storyprotocol",
          },
          {
            platform: "Website",
            url: "https://story.foundation",
          },
        ],
      },
    ],
  };
}

main();

2. [선택사항] NFT 메타데이터 설정

NFT 메타데이터는 ERC-721 메타데이터 표준을 따릅니다.

main.ts
import { IpMetadata } from "@story-protocol/core-sdk";
import { client } from "./utils";

async function main() {
  // previous code here ...

  const nftMetadata = {
    name: "Ownership NFT",
    description: "This is an NFT representing owernship of our IP Asset.",
    image: "https://picsum.photos/200",
  };
}

main();

3. [선택사항] IP 및 NFT 메타데이터를 IPFS에 업로드

별도의 uploadToIpfs 파일에서 IP 및 NFT 메타데이터 객체를 IPFS에 업로드하는 함수를 만드세요:

uploadToIpfs.ts
import { PinataSDK } from "pinata-web3";

const pinata = new PinataSDK({
  pinataJwt: process.env.PINATA_JWT,
});

export async function uploadJSONToIPFS(jsonMetadata: any): Promise<string> {
  const { IpfsHash } = await pinata.upload.json(jsonMetadata);
  return IpfsHash;
}

그런 다음 아래와 같이 해당 함수를 사용하여 메타데이터를 업로드할 수 있습니다:

main.ts
import { IpMetadata } from "@story-protocol/core-sdk";
import { client } from "./utils";
import { uploadJSONToIPFS } from "./uploadToIpfs";
import { createHash } from "crypto";

async function main() {
  // previous code here ...

  const ipIpfsHash = await uploadJSONToIPFS(ipMetadata);
  const ipHash = createHash("sha256")
    .update(JSON.stringify(ipMetadata))
    .digest("hex");
  const nftIpfsHash = await uploadJSONToIPFS(nftMetadata);
  const nftHash = createHash("sha256")
    .update(JSON.stringify(nftMetadata))
    .digest("hex");
}

main();

4. NFT를 IP 자산으로 등록

새로운 IP를 등록하려면 먼저 IP의 기본 소유권을 나타내는 NFT를 발행해야 한다는 점을 기억하세요. 이 NFT는 그 후 “등록”되어 IP 자산이 됩니다.

다행히도 mintAndRegisterIp 함수를 사용하여 NFT를 발행하고 동일한 트랜잭션에서 IP 자산으로 등록할 수 있습니다.

이 함수는 발행할 SPG NFT 계약이 필요합니다.

4a. 어떤 SPG NFT 계약 주소를 사용해야 하나요?

간단히 말해, Aeneid 테스트넷에서 여러분을 위해 만든 공개 컬렉션을 사용할 수 있습니다: 0xc32A8a0FF3beDDDa58393d022aF433e78739FAbc. 메인넷에서, 또는 Aeneid에서 실제 시나리오를 테스트할 때도 자체 계약을 생성해야 합니다. 이는 아래 “사용자 정의 ERC-721 계약 사용” 섹션에서 설명합니다.

다음은 IP를 등록하는 코드입니다:

main.ts
import { IpMetadata } from "@story-protocol/core-sdk";
import { client } from "./utils";
import { uploadJSONToIPFS } from "./uploadToIpfs";
import { createHash } from "crypto";
import { Address } from "viem";

async function main() {
  // previous code here ...

  const response = await client.ipAsset.mintAndRegisterIp({
    spgNftContract: "0xc32A8a0FF3beDDDa58393d022aF433e78739FAbc",
    ipMetadata: {
      ipMetadataURI: `https://ipfs.io/ipfs/${ipIpfsHash}`,
      ipMetadataHash: `0x${ipHash}`,
      nftMetadataURI: `https://ipfs.io/ipfs/${nftIpfsHash}`,
      nftMetadataHash: `0x${nftHash}`,
    },
    txOptions: { waitForTransaction: true },
  });

  console.log(
    `Root IPA created at transaction hash ${response.txHash}, IPA ID: ${response.ipId}`
  );
  console.log(
    `View on the explorer: https://aeneid.explorer.story.foundation/ipa/${response.ipId}`
  );
}

main();

5. 완성된 코드 보기

축하합니다, IP를 등록하셨습니다!

6. IP에 라이선스 조건 추가

이제 IP가 등록되었으니 라이선스 조건을 생성하고 첨부할 수 있습니다. 이를 통해 다른 사람들이 라이선스를 발행하고 조건에 따라 제한된 방식으로 여러분의 IP를 사용할 수 있게 됩니다.

다음 섹션에서 이에 대해 다루겠지만, mintAndRegisterIp function, you can register IP + create terms + attach terms all in the same step with the following functions: