Use this file to discover all available pages before exploring further.
Sometimes you want to encode smart contract function data for things like sending arbitrary transactions via Crossmint.As seen in Crossmint’s docs, you can get encoded function data via Story’s SDK. However this is shortly going to be deprecated and it does not support every function anyway.So here’s a quick tutorial on how to get encoded function data for any Story smart contract function.
As an example, let’s try to call the mintAndRegisterIpAndAttachPilTerms in our periphery contract. This function mints & registers a new IP and attaches PIL Terms to it.As shown in Deployed Smart Contracts, LicenseAttachmentWorkflows is deployed at 0xcC2E862bCee5B6036Db0de6E06Ae87e524a79fd8 on Aeneid (at the time of writing this tutorial).There’s a few things we’ll need:
Contract ABI - you can get this by going to our block explorer and looking up the contract. This is a proxy contract, so go to Contract > Read/Write proxy > Click on the implementation address > Contract > ABI. After all that, you should end up here.
Function Args - you can get these just by looking at the code.
Great! Now let’s build our transaction request.
import { encodeFunctionData } from "viem";import { Account, Address, privateKeyToAccount } from "viem/accounts";const account: Account = privateKeyToAccount( `0x${process.env.WALLET_PRIVATE_KEY}` as Address);const transactionRequest = { to: "0xcC2E862bCee5B6036Db0de6E06Ae87e524a79fd8" as `0x${string}`, data: encodeFunctionData({ abi: CONTRACT_ABI, // the abi you copied above functionName: "mintAndRegisterIpAndAttachPILTerms", args: [ "0xc32A8a0FF3beDDDa58393d022aF433e78739FAbc", // example spg nft contract I use on Aeneid account.address, // example metadata values { ipMetadataURI: "https://ipfs.io/ipfs/bafkreiabrkevameeffdpjpizchywldogzai7kp5oodawbhgbojyeomk7uq", ipMetadataHash: "0x018a895030842946f4bd1911f1658dc6c811f53fae70c1609cc1727047315fa4", nftMetadataURI: "https://ipfs.io/ipfs/bafkreicbuti233kvewqs7uwb5y2toexj5gafgvsr5mqmnnx7cuof53gvsa", nftMetadataHash: "0x41a4d1aded5525a12fd2c1ee353712e9e980535651eb20c6b6ff151c5eecd590", }, // example PIL terms [ { terms: { transferable: true, royaltyPolicy: "0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E", defaultMintingFee: 0n, expiration: 0n, commercialUse: true, commercialAttribution: true, commercializerChecker: "0x0000000000000000000000000000000000000000", commercializerCheckerData: "0x", commercialRevShare: 0, commercialRevCeiling: 0n, derivativesAllowed: true, derivativesAttribution: true, derivativesApproval: false, derivativesReciprocal: true, derivativeRevCeiling: 0n, currency: "0x1514000000000000000000000000000000000000", uri: "https://github.com/piplabs/pil-document/blob/ad67bb632a310d2557f8abcccd428e4c9c798db1/off-chain-terms/CommercialRemix.json", }, licensingConfig: { mintingFee: 0n, isSet: false, disabled: false, commercialRevShare: 0, expectGroupRewardPool: "0x0000000000000000000000000000000000000000", expectMinimumGroupRewardShare: 0, licensingHook: "0x0000000000000000000000000000000000000000", hookData: "0x", }, }, ], true, ], }),};
At this point, we have the data and to needed for sending this transaction, for example if we were using Crossmint.However we could also then send this transaction ourselves:
import { aeneid } from "@story-protocol/core-sdk";import { createWalletClient, http, WalletClient } from "viem";// other code hereconst walletClient = createWalletClient({ chain: aeneid, transport: http("https://aeneid.storyrpc.io"), account,}) as WalletClient;const txHash = await walletClient.sendTransaction({ ...transactionRequest, account, chain: aeneid,});console.log(`Transaction sent: https://aeneid.storyscan.io/tx/${txHash}`);