FLIX (Flow Interaction Templates)

[Previous << Fees](https://qiita.com/flowcadence/items/c4c24a01ec3d6b7429e2)
[Next >> Account Linking](https://qiita.com/flowcadence/items/b41866abc1858ba8acd1)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#flow-developers

**ドキュメント(上)と仕様詳細(下)の２部構成です**
***
Flow Interaction Templatesは、スマートコントラクト開発者、ウォレット、ユーザー、監査機関、およびアプリケーションが、Flowスクリプトおよびトランザクションの趣向、セキュリティ、およびメタデータをどのように作成、監査、および検証できるかを規定するスタンダードです。このスタンダードは、承認済みトランザクションの理解しやすさとセキュリティを向上させ、Flow上のアプリケーションの変更に抵抗できる構成を押し進めることを目的としています。

Interaction Templatesは、既存のスクリプトやトランザクションの利用や再利用、および、トランザクションやスクリプトが実行する内容の人間が読める形でのタイトルや説明など、より多くのメタデータの提供を可能にします。これらのメタデータは、アプリケーションの開発者やユーザーが使用することができます。

FLIX トランザクションとスクリプトを使用することで、開発者は一般的なオペレーションのために自分で記述する必要がなくなります！

FLIX の設計と目的についての詳細は、[FLIP](https://github.com/onflow/flips/blob/main/application/20220503-interaction-templates.md) をご覧ください。

<h1>Using FLIX</h1>

Flow makes FLIX available through an API available at flix.flow.com.

FLIX APIに問い合わせることで、インタラクションテンプレートを取得できます。クエリの例は次のようになります: https://flix.flow.com/v1/templates?name=transfer-flow

FLIX APIへの問い合わせ方法については、こちらの入手可能なドキュメント内に説明されています: https://github.com/onflow/flow-interaction-template-service

:::note info
INFO
FLIXワーキンググループは現在、FLIXテンプレートをブロックチェーン上にpublishするためのプロトコルを策定中です。
:::

<h2>Example</h2>

異なる開発チーム間でFLIXを統合するにはどうすればよいか？こちらの例では、GitHubリポジトリが2つあります。
* (smart contracts) https://github.com/onflow/hello-world-flix
* (web development) https://github.com/onflow/hello-world-web

スマートコントラクト開発者はFLIXテンプレートを作成し、GitHubで公開します。これらはバージョン管理が可能です。例として`v0.1.0`リリースでは、テンプレートは特定のバージョンで利用可能です。この例では、テンプレートは次の場所にあります。
* https://github.com/onflow/hello-world-flix/blob/v0.1.0/cadence/templates/ReadHelloWorld.template.json
* https://github.com/onflow/hello-world-flix/blob/v0.1.0/cadence/templates/UpdateHelloWorld.template.json

開発者は、スマートコントラクトのGitHubからFLIXテンプレートを使用して、スマートコントラクトとやりとりすることができます。FLIXテンプレートのURLがあれば、綴じ込んだファイル（TypeScriptまたはJavaScript）を作成できます。大きな利点の1つは、ウェブ開発者が、既存のスマートコントラクトと統合するために、Cadenceを学習したり、Cadenceをリポジトリにコピーしたりする必要がないことです。

テンプレートから生成されるTypeScriptコード：
* https://github.com/onflow/hello-world-web/blob/main/app/cadence/readHelloWorld.ts
* https://github.com/onflow/hello-world-web/blob/main/app/cadence/updateHelloWorld.ts

:::note warn
WARNING
リンティングエラーを防ぐため、生成されたファイルに手動で "@ts-ignore" を追加します。'template'プロパティは"object"として型付けされていますが、（URLやFLIXテンプレートファイルなど）文字列も許可されるべきだからです。現在、このリンティングの問題を修正する開発努力が進行中です。
:::
See the `hello-world-web` [README](https://github.com/onflow/hello-world-web/tree/main) for more information on how to generate and execute FLIX templates here [flow-cli flix](https://qiita.com/flowcadence/items/65f173cc69d1eb22e38e) commands.

<h2>Clients</h2>

現在利用が可能な、FLIXと統合したクライアントは2つあります。

**Go client** https://github.com/onflow/flixkit-go
**FCL client you** read how to get started [tools/clients/fcl-js/interaction-templates](https://qiita.com/flowcadence/items/e49102ecf2109f9e55bb)
<h1>(Advanced) Running a FLIX API</h1>

Flowは、Flow Interaction Templateサービスの実装を、オープンソースプロジェクトとして提供しています。独自のAPIを管理したい場合は、リポジトリをこちらでご確認いただけます：https://github.com/onflow/flow-interaction-template-service

*Last updated on **Dec 13, 2024** by **Chase Fleming***

翻訳元

https://developers.flow.com/build/advanced-concepts/flix

***

<h1>Interaction Templates (Latest)</h1>

> このFLIPは、InteractionTemplateおよびInteractionTemplateInterfaceのデータ構造の最新バージョン（v1.1.0）を紹介しています。InteractionTemplateおよびInteractionTemplateInterfaceの以前のバージョン（v1.0.0）についてさらに詳しく知りたい場合は、以下を参照してください: 
https://github.com/onflow/flips/blob/main/flips/20220503-interaction-templates.md

<h2>Abstract</h2>

このFLIPは、スマートコントラクト開発者、ウォレット、ユーザー、監査機関、アプリケーションが、Flowのスクリプトおよびトランザクションの趣向、セキュリティ、メタデータをどのように作成、監査、検証するかについての新たな基準(standard)を提案しています。その目的は、承認済みトランザクションの理解しやすさとセキュリティを向上させ、Flow上のアプリケーションの変更に強いコンポーザビリティのパターンを促進することです。

<h2>Background</h2>

<h3>Contract Interactions</h3>

Flowのスマートコントラクトの開発では、コントラクト自体に加えて、さまざまな機能を実現するためのスマートコントラクトとのやり取りの方法も規定のセットとして提供するのが一般的です。これらのコントラクトとやり取りを行うソフトウェアを開発する開発者は、そのプロジェクトでこれらのInteraction Templatesを使用することができます。

例えば、Flowのステーキングエコシステムとやりとりしたい開発者のために、[一連のトランザクションとスクリプトが提供された](https://github.com/onflow/flow-core-contracts/tree/master/transactions/stakingCollection)、Flowのコア・ステーキング・コントラクトが用意されています。[Flow Port](https://port.flow.com/)やブロックエクスプローラー、ウォレットなどのアプリは、ステーキングのアクションを実行したり、Flowのステーキングエコシステムに関する状態を照会したりするために、これらのトランザクションとスクリプトを使用しています。

このFLIPでは、トランザクションとスクリプトのより高次の用語を「インタラクション」と呼ぶことを提案しています。インタラクションとは、Flowブロックチェーンと"やり取り"して目的を達成する何かの包括的な用語となることを意図しています。この用語は、FLIPの残りの部分全体で使用されます。

<h3>Cadence Interactions</h3>

Cadenceは、Flow上で安全でセキュア、明瞭かつ利用しやすいスマートコントラクトの開発を促進する上で、目覚ましい進歩を遂げています。

しかし、エンドユーザー、開発者、ウォレットのいずれにとっても、Cadenceのトランザクションやスクリプトが実行された際に、それが何を実行するのかを解釈することが難しい場合があります。例えば、エンドユーザーが自身のウォレットを使用して署名する悪意のあるトランザクションを提示された場合、そのトランザクションが悪意のあるものであることを判断する技術的能力がない可能性が高いでしょう。

悪意のあるトランザクションからユーザーを守りたいと考えるウォレット開発者は、ユーザーに署名を促す前に、トランザクションが何を行う可能性があるかを推測してみることができます。このアプローチの問題点は、トランザクションの結果をすべて予測することが困難であることです。また、現在、すべてのトランザクションに対してこのような予測メカニズムを実装することは、ユーザーを十分に保護できるほど堅牢ではない可能性が高いです。

Flowコミュニティで浮上しているパターンは、スマートコントラクト開発者が、安全なトランザクションとして知られているさまざまなリポジトリにトランザクションを追加してもらうというものです。これらのリポジトリの管理者は、トランザクションの安全性を監査し、安全であると判断された場合はリポジトリに追加することができます。この実例として、[Portto（Blocto）のFlow-Transactionsリポジトリ](https://github.com/blocto/flow-transactions/tree/main/transactions)があります。Bloctoがトランザクションに署名を求められた場合、そのトランザクションがFlow-Transactionsリポジトリに存在するかどうかを確認します。もし存在すれば、そのトランザクションの安全性をより確信し、その確信をUIを通じてユーザーに知らせます。

<h3>Interaction Metadata</h3>

Cadenceのスクリプトやトランザクション自体には、それ自体に関するメタデータは含まれていません。 アプリケーションやウォレットの開発者は、ユーザーに署名を要求する前に、*人間が読める*トランザクションのタイトルや説明を表示することがよくあります。 ユーザーから徴収する必要のある各パラメータのタイトルや説明、あるいはトランザクションがユーザーのアカウントや資産にどのように影響を与えるかに関する情報を表示したい場合もあります。 開発者がアプリケーションで使用する可能性のあるメタデータは、さまざまな形式で、さまざまな目的で使用される可能性があります。

アプリケーションやウォレットは、望ましくない結果をもたらす可能性のあるアクションを実行しないよう、トランザクションが*何を行うか*を知っておく必要があるかもしれません。例えば、アプリケーション/ウォレットは、ユーザーが自分のアカウントからFLOWトークンを保有数を超えて送金するトランザクションを実行しないようにしたいと考えるかもしれません。なぜなら、そのようなトランザクションは失敗するからです。また、アプリケーション/ウォレットは、Interaction Templatesの依存ツリーがどのバージョンに基づいて作成されたのかを知りたいと考えるかもしれません。なぜなら、Flow上のコントラクトは変更が可能であるため、依存関係が変更されるとInteraction Templatesの機能も変更される可能性があるからです。

現在、アプリケーションやウォレットは、サポートするトランザクションのメタデータを独自に作成することになっています。例えば、Flow Portでは、サポートする各トランザクションにタイトルと説明、および各パラメータのタイトルと説明が含まれています。スマートコントラクトの開発者は、それらと関わるアプリケーションやウォレットが利用可能な、Interaction Templatesのメタデータを提供してくれる標準化された方法を持っていません。
<h2>Objective</h2>

大まかに言えば、Interaction Templatesは、スマートコントラクト開発者、ウォレット、ユーザー、監査機関、アプリケーションが、Flowのスクリプトやトランザクションの意図、セキュリティ、メタデータをどのように作成、監査、検証するかを標準化しようとするものです。
<h3>Metadata Standardization</h3>

**インタラクション・テンプレート・メタデータ**を標準化することで、Flowコミュニティは、サポートが必要な各インタラクションについて独自にメタデータを考案するのではなく、メタデータを消費できるアプリケーションの構築を開始することができます。メタデータのフォーマットが統一されるため、任意のInteraction Templatesを含め、より幅広いInteraction Templatesをサポートすることが可能になります。

メタデータの標準化は、やり取りの実行に関わるすべての関係者が、そのやり取りが何を必要とし、何を行うのかをより良く理解するのに役立ちます。アプリケーションにとっては、メタデータにより、ユーザーに直感的な方法でやり取りを理解させ、提示することが可能になります。また、ウォレットにとっては、メタデータにより、トランザクションがアカウントにどのような影響を与えるかを理解し、望ましくない結果を回避し、悪意のある取引を拒否する方法を把握することができます。ユーザーにとっては、メタデータにより、トランザクションの影響を人間が読める形で理解することが可能になります。
<h2>Interaction Audits</h2>

インタラクションメタデータは、価値あるものとされるためには正確でなければなりません。その根本的なInteraction Templatesの誤解を招くメタデータは、エンドユーザーに不都合な影響を及ぼす可能性があります。これを防ぐために、**Interaction Template Audits**を標準化することは、Interaction Templatesを利用したり作成したりするすべての関係者が、そのテンプレートが正確であると検証および証明することが可能になります。

信頼できるエンティティが監査機関として働き、インタラクションテンプレートの正確性と安全性を保証する証明を作成できる仕組み、および検証者（アプリケーション、ウォレットなど）が、信頼する監査人によって監査が作成されたことを証明できる仕組みを構築することで、Flow上でのインタラクションテンプレートの使用における安全性とセキュリティが全体的に向上します。
<h2>Design Proposal</h2>

<h3>Interaction Interfaces</h3>

多くのインタラクションは、特定のプロジェクトでそのアクションがどう実行されるかに応じて、同じタイプのアクションを達成することを目的としています。インタラクションのタイプには、「Transfer（譲渡）」、「Mint（発行）」、「Bid（入札）」、「List（リスト）」、「Destroy（破棄）」などがあります。

例えば、異なるマーケットプレイスでは、異なるユーザーが「出品」する仕組みを持つ場合がありますが、すべての実装において、「出品」というアクションは、すべてが目指すものです。

インタラクション・インターフェースは、アクションのタイプを定義し、これらのアクションを実装するインタラクションが消費しなければならないパラメータのセットを定義することで、これらのアクションを標準化することを目的としています。

以下は、"Fungible Token Transfer"のための`InteractionTemplateInterface`の例です。
```ruby
{
    f_type: "InteractionTemplateInterface",
    f_version: "1.1.0",
    id: "asadf23234...fas234234", // Unique ID for the data structure.
    data: {
        flip: "FLIP-XXXX",
        title: "Fungible Token Transfer",
        parameters: [
            {
              key: "amount",
              index: 0,
              type: "UFix64"
            },
            {
              key: "to",
              index: 1,
              type: "Address"
            }
        ]
    }
}
```

`f_type & f_version`
このフィールドは、データ構造の型とバージョンを宣言します。バージョンは、このデータ構造の利用者に対して、そのデータ構造をどう扱うかを指示します。また、バージョンにより、将来のバージョンでデータ構造を変更することも可能になります。

`id`
これは、このinteraction interface用のユニークなコンテンツ由来の識別子です。各IDは、各インタラクション・インターフェースに対してユニークです。データ構造の`data`フィールド内の情報の一部が、データ構造のidを作成するために使用されます。

idの生成は、このドキュメントの[Data Structure Serialization & Identifier Generation](#data-structure-serialization--identifier-generation)セクションで説明されているプロセスを使用して行われます。

`data.flip`
このインターフェースが確立されたFLIPの番号です。

`data.title`
FLIPで指定された確立されたインターフェースのタイトル。

`data.parameter`
このインターフェースを実装するインタラクションが消費しなければならないパラメータ。各パラメータの名前、インデックス(index)、および型を指定します。

この例では、`InteractionTemplateInterface`は、それを実装したいインタラクションのためのインターフェースを定義します。実装するインタラクションが必ず持っていなければならないパラメータを定義します。また、`InteractionTemplateInterface`が定義されているFLIPを参照します。インタフェースは、FLIPプロセスを通じて定義されるべきです。なぜなら、インタラクションは多くの関係者によって使用されるため、コミュニティのコンセンサスが達成されるべきだからです。

アプリケーションは、このようなインターフェースに準拠するインタラクションの実行をサポートすることができます。例えば、ユーザーのリソースを表示するアプリケーションやウォレットは、ユーザーが所有する各リソースの横に送金ボタンを表示したいと考えるかもしれません。ユーザーが送金ボタンを押すと、アプリケーションはそのリソースプロジェクトに対応する特定のTransferインタラクションを実行することができます。各プロジェクトのTransfer Interactionはすべて同じインターフェースに準拠できるため、アプリケーションは各プロジェクト間でロジックを再利用でき、また、標準化されたパラメータを使用することで、各プロジェクトに情報を提供する方法を知ることができます。

<h3>Interaction Templates</h3>

Interaction Templatesは、メタデータであり、トランザクションまたはスクリプトの Cadence でもあります。 インタラクションテンプレートには以下が含まれます。
* インタラクションに関する、人間が読める国際化されたメッセージ
* インタラクションを実行するための Cadence コード
* 国際化された人間が読めるメッセージなどのパラメータに関する情報、およびパラメータが作用する対象。
* スクリプトの出力の情報 (必要に応じて)
* インタラクションが準拠するインターフェース (必要に応じて)
* インタラクションが関与するコントラクト依存関係が、依存関係ツリーのバージョンに固定されたもの。

Interaction Templatesは、その中核は単なるデータです。この例のデータの形式はJSONですが、将来的にインタラクションテンプレートが他の形式で表現される可能性もあります。

以下は、"Transfer FLOW"のトランザクションの`InteractionTemplate`の例です。
```ruby
{
  f_type: "InteractionTemplate", // Data Type
  f_version: "1.1.0", // Data Type Version
  id: "a2b2d73def...aabc5472d2", // Unique ID for the data structure.
  data: {
    type: "transaction", // "transaction" || "script"
    interface: "asadf23234...fas234234", // ID of InteractionTemplateInterface this conforms to.
    messages: [
      {
        key: "title",
        i18n: [ // Internationalised (BCP-47) set of human readable messages about the interaction
          {
            tag: "en-US",
            translation: "Transfer FLOW"
          },
          {
            tag: "fr-FR",
            translation: "FLOW de transfert"
          },
          {
            tag: "zh-CN",
            translation: "转移流程"
          }
        ]
      },
      {
        key: "description",
        i18n: [ // Internationalised (BCP-47) set of human readable messages about the interaction
          {
            tag: "en-US",
            translation: "Transfer {amount} FLOW to {to}", // Messages might consume parameters.
          },
          {
            tag: "fr-FR",
            translation:  "Transférez {amount} FLOW à {to}"
          },
          {
            tag: "zh-CN",
            translation: "将 {amount} FLOW 转移到 {to}"
          }
        ]
      },
      {
        key: "signer",
        i18n: [ // Internationalised (BCP-47) set of human readable messages about the interaction
          {
            tag: "en-US",
            translation: "Sign this message to transfer FLOW", // Messages might consume parameters.
          },
          {
            tag: "fr-FR",
            translation:  "Signez ce message pour transférer FLOW."
          },
          {
            tag: "zh-CN",
            translation: "签署此消息以转移FLOW。"
          }
        ]
      }
    ],
    cadence: { // Cadence code this interaction executes.
      body: `
        import "FlowToken"
        transaction(amount: UFix64, to: Address) {
            let vault: @FungibleToken.Vault
            prepare(signer: AuthAccount) {
                %%self.vault <- signer
                .borrow<&{FungibleToken.Provider}>(from: /storage/flowTokenVault)!
                .withdraw(amount: amount)

                self.vault <- FungibleToken.getVault(signer)
            }
            execute {
                getAccount(to)
                .getCapability(/public/flowTokenReceiver)!
                .borrow<&{FungibleToken.Receiver}>()!
                .deposit(from: <-self.vault)
            }
        }
        `,
        network_pins: [
          {
            network: "mainnet",
            pin_self: "186e262ce6fe06b5075ec6569a0e5482a79c471881182612d8e4a665c2977f3e"
          },
          {
            network: "testnet",
            pin_self: "f93977d7a297f559e97259cb2a95fed0f87cfeec46c5257a26adc26a260d6c4c"
          }
        ]
    },   
    dependencies: [
      {
        contracts: [
          {
            contract: "FlowToken",
            networks: [
              {
                network: "mainnet",
                address: "0x1654653399040a61", // Address of the account the contract is located.
                dependency_pin_block_height: 10123123123 // Block height the pin was generated against.
                dependency_pin: {
                  pin: "c8cb7cc7a1c2a329de65d83455016bc3a9b53f9668c74ef555032804bac0b25b", // Unique identifier of this contract dependency and it's dependency tree.
                  pin_self: "38d0cca4b74c4e88213df636b4cfc2eb6e86fd8b2b84579d3b9bffab3e0b1fcb", // Unique identifier of this dependency
                  pin_contract_name: "FlowToken",
                  pin_contract_address: "0x1654653399040a61",
                  imports: [
                    {
                      pin: "b8a3ed26c222ed67016a28021d8fee5603b948533cbc992b3c90f71a61b2b312", // Unique identifier of this contract dependency and it's dependency tree.
                      pin_self: "7bc3056ba5d39d130f45411c2c05bb549db8ce727c11a1cb821136a621be27fb",  // Unique identifier of this dependency
                      pin_contract_name: "FungibleToken",
                      pin_contract_address: "0xf233dcee88fe0abe",
                      imports: []
                    }
                  ]
                },
              },
              {
                network: "testnet",
                address: "0x7e60df042a9c0868",
                dependency_pin_block_height: 10123123123, // Block height the pin was generated against.
                dependency_pin: {
                  pin: "c8cb7cc7a1c2a329de65d83455016bc3a9b53f9668c74ef555032804bac0b25b", // Unique identifier of this contract dependency and it's dependency tree tree.
                  pin_self: "38d0cca4b74c4e88213df636b4cfc2eb6e86fd8b2b84579d3b9bffab3e0b1fcb", // Unique identifier of this dependency
                  pin_contract_name: "FlowToken",
                  pin_contract_address: "0x7e60df042a9c0868",
                  imports: [
                    {
                      pin: "b8a3ed26c222ed67016a28021d8fee5603b948533cbc992b3c90f71a61b2b312", // Unique identifier of this contract dependency and it's dependency tree.
                      pin_self: "7bc3056ba5d39d130f45411c2c05bb549db8ce727c11a1cb821136a621be27fb", // Unique identifier of this dependency
                      pin_contract_name: "FungibleToken",
                      pin_contract_address: "0x9a0766d93b6608b7",
                      imports: []
                    }
                  ]
                },
              },
            ]
          }
        ]
      }
    ],
    parameters: [
      {
        label: "amount",
        index: 0,
        type: "UFix64",
        messages: [ // Set of human readable messages about the parameter
          {
            key: "title",
            i18n: [ // Internationalised (BCP-47) set of human readable messages about the parameter
              {
                tag: "en-US",
                translation: "Amount", // Messages might consume parameters.
              },
              {
                tag: "fr-FR",
                translation:  "Montant"
              },
              {
                tag: "zh-CN",
                translation: "数量"
              }
            ]
          },
          {
            key: "description",
            i18n: [ // Internationalised (BCP-47) set of human readable messages about the parameter
              {
                tag: "en-US",
                translation: "Amount of FLOW token to transfer", // Messages might consume parameters.
              },
              {
                tag: "fr-FR",
                translation:  "Quantité de token FLOW à transférer"
              },
              {
                tag: "zh-CN",
                translation: "要转移的 FLOW 代币数量"
              }
            ]
          }
        ],
        balance: [
          {
            network: "mainnet",
            pin: "A.0xABC123DEF456.FlowToken" // The token this parameter acts upon.
          }
          {
            network: "testnet",
            pin: "A.0xXYZ678DEF123.FlowToken" // The token this parameter acts upon.
          }
        ]
      },
      {
        label: "to",
        index: 1,
        type: "Address",
        messages: [ // Set of human readable messages about the parameter
          {
            key: "title",
            i18n: [ // Internationalised (BCP-47) set of human readable messages about the parameter
              {
                tag: "en-US",
                translation: "To", // Messages might consume parameters.
              },
              {
                tag: "fr-FR",
                translation:  "Pour"
              },
              {
                tag: "zh-CN",
                translation: "到"
              }
            ]
          },
          {
            key: "description",
            i18n: [ // Internationalised (BCP-47) set of human readable messages about the parameter
              {
                tag: "en-US",
                translation: "Amount of FLOW token to transfer", // Messages might consume parameters.
              },
              {
                tag: "fr-FR",
                translation:  "Le compte vers lequel transférer les jetons FLOW"
              },
              {
                tag: "zh-CN",
                translation: "将 FLOW 代币转移到的帐户"
              }
            ]
          }
        ]
      }
    ]
  }
}
```
```ruby
{
  f_type: "InteractionTemplate", // Data Type
  f_version: "1.1.0", // Data Type Version
  id: "a2b2d73def...aabc5472d2", // Unique ID for the data structure.
  data: {
    type: "script", // "transaction" || "script"
    messages: [
      {
        key: "title",
        i18n: [ // Internationalised (BCP-47) set of human readable messages about the interaction
          {
            tag: "en-US",
            translation: "Get FLOW Balance"
          },
          {
            tag: "fr-FR",
            translation: "obtenir le solde de FLOW"
          },
          {
            tag: "zh-CN",
            translation: "获取 Flow 余额"
          }
        ]
      }
    ],
    cadence: { // Cadence code this interaction executes.
      body: `
      import "FungibleToken"
      import "FlowToken"

      pub fun main(address: Address): UFix64 {
          let vaultRef = getAccount(address)
              .getCapability(/public/flowTokenBalance)
              .borrow<&FlowToken.Vault{FungibleToken.Balance}>()
              ?? panic("Could not borrow Balance reference to the Vault")

          return vaultRef.balance
      }
    `,
      pins: [
        {
          network: "mainnet",
          pin: "f4355ea07422d5b1cfebff8c609748dccb4e9a1a5c75d0d197df254232a90e6f"
        },
        {
          network: "testnet",
          pin: "7e26be0b1efbbe08dfccc343f31ba0fc631573227c67afbc11e5ff7b6baca964"
        }
      ]
    },
    dependencies: [
      {
        contracts: [
          {
            contract: "FlowToken",
            networks: [
              {
                network: "mainnet",
                address: "0x1654653399040a61", // Address of the account the contract is located.
                dependency_pin_block_height: 10123123123 // Block height the pin was generated against.
                dependency_pin: {
                  pin: "c8cb7cc7a1c2a329de65d83455016bc3a9b53f9668c74ef555032804bac0b25b", // Unique identifier of this contract dependency and it's dependency tree.
                  pin_self: "38d0cca4b74c4e88213df636b4cfc2eb6e86fd8b2b84579d3b9bffab3e0b1fcb", // Unique identifier of this dependency
                  pin_contract_name: "FlowToken",
                  pin_contract_address: "0x1654653399040a61",
                  imports: [
                    {
                      pin: "b8a3ed26c222ed67016a28021d8fee5603b948533cbc992b3c90f71a61b2b312", // Unique identifier of this contract dependency and it's dependency tree.
                      pin_self: "7bc3056ba5d39d130f45411c2c05bb549db8ce727c11a1cb821136a621be27fb",  // Unique identifier of this dependency
                      pin_contract_name: "FungibleToken",
                      pin_contract_address: "0xf233dcee88fe0abe",
                      imports: []
                    }
                  ]
                },
              },
              {
                network: "testnet",
                address: "0x7e60df042a9c0868",
                dependency_pin_block_height: 10123123123, // Block height the pin was generated against.
                dependency_pin: {
                  pin: "c8cb7cc7a1c2a329de65d83455016bc3a9b53f9668c74ef555032804bac0b25b", // Unique identifier of this contract dependency and it's dependency tree tree.
                  pin_self: "38d0cca4b74c4e88213df636b4cfc2eb6e86fd8b2b84579d3b9bffab3e0b1fcb", // Unique identifier of this dependency
                  pin_contract_name: "FlowToken",
                  pin_contract_address: "0x7e60df042a9c0868",
                  imports: [
                    {
                      pin: "b8a3ed26c222ed67016a28021d8fee5603b948533cbc992b3c90f71a61b2b312", // Unique identifier of this contract dependency and it's dependency tree.
                      pin_self: "7bc3056ba5d39d130f45411c2c05bb549db8ce727c11a1cb821136a621be27fb", // Unique identifier of this dependency
                      pin_contract_name: "FungibleToken",
                      pin_contract_address: "0x9a0766d93b6608b7",
                      imports: []
                    }
                  ]
                },
              },
            ]
          },
          {
            contract: "FungibleToken",
            networks: [{
              network: "mainnet",
              address: "0xf233dcee88fe0abe",
              fq_address: "A.0xf233dcee88fe0abe.FungibleToken",
              contract: "FungibleToken",
              pin: "83c9e3d61d3b5ebf24356a9f17b5b57b12d6d56547abc73e05f820a0ae7d9cf5",
              pin_contract_name: "FungibleToken",
              pin_block_height: 34166296
            }, {
              network: "testnet",
              address: "0x9a0766d93b6608b7",
              fq_address: "A.0x9a0766d93b6608b7.FungibleToken",
              contract: "FungibleToken",
              pin: "83c9e3d61d3b5ebf24356a9f17b5b57b12d6d56547abc73e05f820a0ae7d9cf5",
              pin_contract_name: "FungibleToken",
              pin_block_height: 74776482             
            }
          }]
          }
        ]
      }
    ],
    parameters: [
      {
        label: "address",
        index: 1,
        type: "Address",
        messages: [ // Set of human readable messages about the parameter
          {
            key: "title",
            i18n: [ // Internationalised (BCP-47) set of human readable messages about the parameter
              {
                tag: "en-US",
                translation: "Account",
              },
              {
                tag: "fr-FR",
                translation:  "Compte"
              },
              {
                tag: "zh-CN",
                translation: "帐户"
              }
            ]
          },
          {
            key: "description",
            i18n: [ // Internationalised (BCP-47) set of human readable messages about the parameter
              {
                tag: "en-US",
                translation: "Account to get the FLOW balance of", // Messages might consume parameters.
              },
              {
                tag: "fr-FR",
                translation:  "Compte pour obtenir le solde FLOW de"
              },
              {
                tag: "zh-CN",
                translation: "获取FLOW余额的账户"
              }
            ]
          }
        ]
      }
    ],
    output: {   // only needed for scripts
      label: "balance",
      type: "UFix64",
      messages: [ // optionally, only needed to give clarification to consumers
        {
          key: "description",
          i18n: [ 
            {
              tag: "en-US",
              translation: "Amount of FLOW token to transfer",
            },
            {
              tag: "fr-FR",
              translation:  "Le compte vers lequel transférer les jetons FLOW"
            },
            {
              tag: "zh-CN",
              translation: "将 FLOW 代币转移到的帐户"
            }
          ]
        }
        ]
    }  
}
```
`f_type & f_version`
このフィールドは、データ構造の型とバージョンを宣言します。バージョンは、このデータ構造の利用者に対して、そのデータ構造をどう扱うかを指示します。また、バージョンにより、将来のバージョンでデータ構造を変更することも可能になります。

`id`
これは、このinteraction interface用のユニークなコンテンツ由来の識別子です。各IDは、各インタラクション・インターフェースに対してユニークです。データ構造の`data`フィールド内の情報の一部が、データ構造のidを作成するために使用されます。

idの生成は、このドキュメントの[Data Structure Serialization & Identifier Generation](#data-structure-serialization--identifier-generation)セクションで説明されているプロセスを使用して行われます。

`data`
インタラクションテンプレートのコンテンツ。`data`のすべてのサブフィールドはオプションとみなされる。インタラクションテンプレートの利用者は、十分な量の情報を提供するもののみを選択して使用すべきである。

`data.type`
`transaction` か `script` かは、どのような種類のインタラクションに対応するかを定義しています。

`data.interface`
このインタラクションテンプレートが実装するインターフェースのID。すべてのインタラクションテンプレートがインターフェースを実装する必要があるわけではないため、このフィールドはオプションです。

`data.messages`
やり取りを説明する、国際化された、人間が読めるメッセージ。各メッセージには、任意の数の翻訳を用意することができます。翻訳には、[BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag)言語タグを使用する必要があります。メッセージは、トランザクションに提供されたパラメータに対応するパラメータを消費してもよいです。

`data.cadence`
完全に適格なCadenceのハッシュ値に沿って、インタラクションが実行するCadenceのコード。Cadenceにインポートがある場合、インポートが解決されます。`import "FungibleToken"` は、`import FungibleToken from 0x7e60df042a9c0868`（メインネット用）や `import FungibleToken from 0x9a0766d93b6608b7`（テストネット用）となります。

以下の例では、sha256ハッシュは`4ca967e0c3849d2a1d9a80dab7adf6a9c8b51b35a183a201fd69f1eadcd600fb`になります。
```ruby
import FungibleToken from 0x7e60df042a9c0868
import FlowToken from 0x9a0766d93b6608b7

pub fun main(address: Address): UFix64 {
    let vaultRef = getAccount(address)
        .getCapability(/public/flowTokenBalance)
        .borrow<&FlowToken.Vault{FungibleToken.Balance}>()
        ?? panic("Could not borrow Balance reference to the Vault")

    return vaultRef.balance
}
```
`data.dependencies`
インタラクションの各依存関係（インタラクションのサイクルでインポートされる各スマートコントラクト）には、ネットワーク・キー（メインネット or テストネット）の依存関係情報が含まれていなければなりません。各ネットワークの情報には、スマートコントラクトがデプロイされたアカウントのアドレス、コントラクトの依存関係のピン、コントラクト自体のピン（コントラクト自体の SHA3-256 ハッシュ）、それが行われた時のブロック高さを含める必要があります。依存関係ツリーのピンは、以下の擬似コードによって実行されます。
```ruby
/* Example contracts map
 *
 * const contracts = {
 *     contract1: {
 *        Body: '...',
 *        Imports: [contract2], // Imports are in declarative order, as specified in the transaction\/script\/contract
 *        Pin: '', <- Pin is initially empty, and will be processed below
 *        SelfPin: '' <- SelfPin is initially empty, and will be processed below
 *    },
 *    contract2: {
 *        Body: '...',
 *        Imports: [...],
 *        Pin: '',
 *        SelfPin: '' 
 *    },
 *     ... more contracts ...
 * };
 */

function generateDependentPinDepthFirst(contractKey, contracts) {
    const contract = contracts[contractKey];

    if (contract.Pin !== '') {
        return contract.Pin;
    }

    contract.SelfPin = shaHex(contract.Body);

    const pins = [contract.SelfPin];
    for (const imp of contract.Imports) {
        const dep = generateDependentPinDepthFirst(imp.ContractKey(), contracts);
        pins.push(dep);
    }

    contract.Pin = shaHex(pins.join(''));

    contracts[contractKey] = contract;

    return contract.Pin; /* Returned to assist with the recursive algorithm */
}

/* Generates the example contracts object illustrated above given a cadence transaction or script. */
let contracts = generateContractsObjectForEachContractInCadenceCode(cadence) 

/* Compute pins for each contract */
for (const contractKey in contracts) {
    generateDependentPinDepthFirst(contractKey, contracts);
}
```
`data.parameters`
各Cadenceパラメータを説明する、国際化された、人間が読めるメッセージ。各メッセージには、任意の数の翻訳を用意することができます。翻訳には、[BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag)言語タグを使用する必要があります。

パラメータは、代替可能なトークンの残高または代替不可能なトークンの識別子に対応する可能性がある。この場合、パラメータが対応する残高または識別子は、その依存識別子を指す必要がある。

`data.output`
data.parametersの様に、スクリプトの結果を説明する人間が読める形式のメッセージ。outputプロパティは、消化する側およびコード生成者にとって明確にするために必要です。これにより、より優れた統合が可能になります。

**Arbitrary Execution Phase**
Cadenceの強力な機能は、トランザクションに明確に定義された`pre`および`post`条件を設定できることです。トランザクションがリバートされないためには、これらの条件がtrueでなければなりません。トランザクションのインタラクションテンプレートには、executionブロックのないCadenceのトランザクションと、十分に定義されたpreおよびpost条件を含めることができます(補足: prepare、pre、postブロックのみ)。このインタラクションテンプレートの利用者（アプリケーション/ウォレット）は、executionフェーズを好きなように埋めてトランザクションを実行することで、このようなテンプレートを使用することができます(補足: executionフェーズはprepareフェーズほど安全にクリティカルな場所ではなく、アプリ独自のコードを書くために使用するフェーズである)。もし、preおよびpost条件が十分に定義されていれば、トランザクションのexecutionフェーズは任意のものでよく、そのトランザクションのインタラクションテンプレートは有効である。

"Transfer Token"トランザクションのexecutionフェーズが埋められていないCadenceコードの例：
```ruby
import "FungibleToken"
transaction(amount: UFix64, to: Address) {
    let vault: @FungibleToken.Vault
    let receiverBalanceBefore: UFix64
    let senderBalanceBefore: UFix64
    let from: Address
    prepare(signer: AuthAccount) {
        self.receiverBalanceBefore = getAccount(to).balance
        self.senderBalanceBefore = signer.balance
        self.from = signer.address

        self.vault <- signer
        .borrow<&{FungibleToken.Provider}>(from: /storage/flowTokenVault)!
        .withdraw(amount: amount)

        self.vault <- FungibleToken.getVault(signer)
    }
    pre {
        self.vault.balance == amount
    }
    post {
        getAccount(to).balance == self.receiverBalanceBefore + amount
        getAccount(from).balance = self.senderBalanceBefore - amount
    }
}
```
トランザクションのフェーズの詳細については、[こちら](https://qiita.com/flowcadence/items/6393a2af33f82475a7ca)をご覧ください。

**Interaction Template Discovery**

スマートコントラクト開発者は、インタラクションテンプレートを使用したい他の人々に対して、それらを利用できるようにすべきです。ウェブサーバーを使用してそれらを提供し、消費者に問い合わせさせることで、これを実現できます。また、オンチェーンに保存することもできます。さらに、IPFSに保存することもできます。インタラクションテンプレートは単なるデータであるため、シリアライズして任意のプラットフォームに保存できます。

スマートコントラクト開発者は、インタラクションテンプレートを静的なIDに紐づけて保存することもできます。これにより、インタラクションテンプレートの実装を変更しながら、識別子はそのままにしておくことができます。例えば、スマートコントラクト開発者はウェブサーバーをホストし、静的URLの背後にインタラクションテンプレートを配置することを選択できます。
```ruby
GET interactions.nft-project.com/purchase-nft -> InteractionTemplate
```
このインタラクションテンプレートの利用者は、静的IDを照会し、そこに保存されている最新のインタラクションテンプレートを常に取得することができます。

インタラクションテンプレートのレポジトリを作成して、さまざまなプロジェクトのインタラクションテンプレートを保存することができます。インタラクションテンプレートの開発者は、そのインタラクションテンプレートをそのようなレポジトリに提出することを選択できます。

インタラクションテンプレート discovery(検索)システムは、インタラクションテンプレートへのリクエストを、代理してその存在が確認されているレポジトリにリクエストすることができます。インタラクションテンプレートは単なるデータであるため、必要に応じてキャッシュしたり、そのようなレポジトリ間で配布したりすることができます。

<h3>Interaction Template Audits</h3>

インタラクションテンプレート監査(Interaction Template Audit)は、インタラクションテンプレートの正確性と安全性を保証する信頼されたエンティティを表します。

あらゆるエンティティが監査人となり、Interaction Template Auditを作成することができます。

ウォレットやアプリケーションなどの消費者（コンシューマー）は、信頼するエンティティが作成したインタラクションテンプレート監査を照会することができます。 監査機関が特定のインタラクションテンプレートを監査していることが確認できれば、消費者はその正確性と安全性をより信頼することができます。

監査機関はまず、自身のアカウントにインタラクションテンプレート監査マネージャ(Interaction Template Audit Manager)のリソースを追加します。このリソースは、`Interaction Template ID -> isAudited`の対応表を管理します。この対応表は検索可能であるべきであり、これにより、コンシューマーはインタラクションテンプレート監査マネージャリソースを持つ特定の監査機関が、特定のインタラクションテンプレートを監査済みであるかどうかを確認することができます。

監査機関は、自身のインタラクションテンプレート監査マネージャリソースに監査を追加したり、取り消したりできるべきです。

インタラクションテンプレート監査マネージャは、特定の監査機関によって監査が追加された場合、および特定の監査機関によって監査が取り消された場合にイベントを発行すべきである。
<h3>Proposed Workflow</h3>

次の図は、"NFTの購入" トランザクションを実行するために、インタラクションテンプレートおよびインタラクションテンプレート監査と連携して、スマートコントラクト開発者、監査機関、アプリケーション、ウォレットがどのように連携するかを示しています。

この例では、コントラクト開発者はインタラクションテンプレートを、アプリケーションとウォレットの両方にとって問い合わせ可能な方法で利用できるようにしており、監査機関は、自身が管理するアカウント上のインタラクションテンプレート監査マネージャーリソースに監査を追加しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/ab0ead2d-dac1-c1c1-9040-8ba3ff981b08.png)

あるいは、スマートコントラクト開発者によって作成されたInteraction Templateのデータ構造をキャッシュし、利用可能にするInteraction Template discoveryサービスを持つこともできます。このディスカバリーサービスは、さまざまなリポジトリに保存されたインタラクションテンプレートを収集し、キャッシュすることができます。このシステムでは、アプリケーションとウォレットが、複数のソースから問い合わせを行うことができる必要はなく、ディスカバリーサービスから問い合わせを行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/46dd4272-41ba-b028-e3bf-d439523c28d4.png)

ウォレットは同じ監査機関を信頼することを選択でき、これにより、そのような監査機関が作成する各監査は、それを信頼することを選択した多くのエンティティによって使用可能となります。これは、各ウォレットが各トランザクションを監査することを選択した場合に必要であった、このFLIP以前のパターンよりも拡張性のあるパターンです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/c71b4fe4-1680-715f-5a3d-ac66adfacdd4.png)

ウォレットが複数の監査機関を信頼する場合、ウォレットは各監査機関に対してインタラクションテンプレートに対する監査結果を問い合わせることができます。監査機関はそれぞれ異なるインタラクションテンプレートを監査している可能性があるため、複数の監査機関を信頼することで、ウォレットが受け取る可能性のある監査の通ったインタラクションテンプレートのカバレッジ(幅)を広げることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3912821/3a153614-0673-a044-ee36-50b1efcb234d.png)

<h2>Dependencies</h2>

Interaction Templatesは、スマートコントラクト開発者がコントラクト用のインタラクションテンプレートを作成し、利用可能にすることに依存しています。Interaction Template Interfacesは、Flowの開発者コミュニティが実装するインタラクションのインターフェースについて合意していることに依存しています。Interaction Template Auditsは、信頼できるエンティティがインタラクションテンプレートの監査を作成し、利用可能にすることに依存しています。
<h3>Template, Interface and Audit Tooling</h3>

開発者にとって、インタラクションテンプレート、インタラクションテンプレートインターフェース、インタラクションテンプレート監査の作成をより簡単にするために、これらの生成をサポートする機能をCLIツールまたはウェブアプリインターフェースに追加することもできます。これらのデータ構造を簡単に作成できるようにすることは、この新しいパターンを推進する上で不可欠です。
<h2>FCL Integration</h2>

FCLの`mutate`および`query`は、インタラクションテンプレートを受け入れるように変更し、そのインタラクションテンプレートを使用して、対象となるトランザクションまたはスクリプトを実行することができます。

例：
```ruby
import transferFLOWTemplate from "./transfer-flow-template.json"

await fcl.mutate({
  template: transferFLOWTemplate,
  args: (arg, t) => [arg("1.0", t.UFix64), arg("0xABC123DEF456", t.Address)],
})
```
例：
```ruby
import { getFLOWBalanceTemplate } from "@onflow/flow-templates"

await fcl.query({
  template: getFLOWBalanceTemplate,
  args: (arg, t) => [arg("0xABC123DEF456", t.Address)],
})
```
あるいは、テンプレートが外部の場所で利用可能になっている場合、開発者は必要に応じて、自分の場所から問い合わせる(querying)ことで、それらをリクエストすることができます。
例：
```ruby
await fcl.mutate({
  template: "https://transfer-flow.interactions.onflow.org",
  args: (arg, t) => [arg("1.0", t.UFix64), arg("0xABC123DEF456", t.Address)],
})
```

例：
```ruby
await fcl.query({
  template:
    "ipfs://64EC88CA00B268E5BA1A35678A1B5316D212F4F366B2477232534A8AECA37F3C",
  args: (arg, t) => [arg("0xABC123DEF456", t.Address)],
})
```
URLは静的のままであるが、対応するインタラクションテンプレートは動的であり、変更が可能であるため、開発者は常に最新のインタラクション実装を要求することができます。これにより、コントラクト開発者がコントラクトとインタラクションを修正する仕組みが可能になり、下流での破壊的変更を防止するのに役立ちます。[flixkit-go](https://github.com/onflow/flixkit-go)は、インタラクションテンプレートを使用してJavaScriptファイルを作成するためのサポートを提供しています。Flow CLIはflowkit-goを統合しています。

<h3>Golang Integrations</h3>

GoはFlowエコシステムの中で人気の高い言語です。[flixkit-go](https://github.com/onflow/flixkit-go)は、実行、生成、JavaScriptバインディングファイルの作成をサポートしています。Flow CLIはflixkit-goを統合しており、ユーザーは`execute`, `generate` そして `package`（インタラクティブテンプレートのcadenceを呼び出すJavaScriptの作成）することが出来ます。

<h3>Wallet Integration</h3>

Interaction Templatesをサポートすることを選択したウォレットは、認証サービスを変更して、署名可能なバウチャーの中で受け取ったCadenceに一致するインタラクションテンプレートをクエリーするようにする必要があります。次に、ウォレットは、このテンプレートについて信頼する監査機関からInteraction Template Auditsを照会(query)し、その監査を使用してインタラクションテンプレートのセキュリティと正確性に対する信頼を得る必要があります。
<h2>Prior Art</h2>

* [Portto (Blocto) Flow-Transactions repository](https://github.com/blocto/flow-transactions/tree/main/transactions)
* [Flow Staking Ecosystem transactions and scripts](https://github.com/onflow/flow-core-contracts/tree/master/transactions/stakingCollection)

<h2>Questions and Discussion Topics</h2>

* この提案に代わる実行可能な代替案は存在するだろうか？
* プロジェクト全体で共通のCadenceスマートコントラクトおよび共通のリソースインターフェースを使用することが普及すれば、エコシステムがこのソリューションに依存する度合いを減らすことができるだろうか？

<h2>Data Structure Serialization & Identifier Generation</h2>

`InteractionTemplate`および`InteractionTemplateInterface`データ構造のIDを生成するには、ハッシュ化に先立って決定論的なシリアライゼーションアルゴリズムを適用する必要があります。

各データ構造を特定のフォーマットにシリアライズし、そのフォーマットを[RLPエンコード](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/)し、そのエンコードをハッシュ化することで、各データ構造のIDを生成することができます。
<h3>InteractionTemplate f_version 1.1.0</h3>

```ruby
template-message-key-content   = UTF-8 string content of the message
template-message-key-bcp47-tag = BCP-47 language tag
template-message-translation   = [ sha3_256(template-message-key-bcp47-tag), sha3_256(template-message-key-content) ]
template-message-key           = Key for a template message (eg: "title", "description" etc)
template-message               = [ sha3_256(template-message-key), [ ...template-message-translation ] ]

template-dependency-contract-pin-block-height = Network block height the pin was generated against.
template-dependency-contract-pin              = Pin of contract and its dependency tree
template-dependency-contract-pin-self         = Pin of the contract itself
template-dependency-network-address           = Address of an account
template-dependency-network                   = "mainnet" | "testnet" | "emulator" | Custom Network Tag
template-dependency-contract-network          = [
    sha3_256(template-dependency-network),
    [
        sha3_256(template-dependency-network-address),
        sha3_256(template-dependency-contract-name),
        sha3_256(template-dependency-contract-pin),
	sha3_256(template-dependency-contract-pin-self),
        sha3_256(template-dependency-contract-pin-block-height)
    ]
]
template-dependency-contract-name    = Name of a contract
template-dependency-contract         = [
    sha3_256(template-dependency-contract-name),
    [ ...template-dependency-contract-network ]
]
template-dependency                  = [ 
  ...template-dependency-contract 
]


template-parameter-content-message-key-content   = UTF-8 string content of the message
template-parameter-content-message-key-bcp47-tag = BCP-47 language tag
template-parameter-content-message-translation   = [
  sha3_256(template-parameter-content-message-key-bcp47-tag),
  sha3_256(template-parameter-content-message-key-content)
]
template-parameter-content-message-key           = Key for a template message (eg: "title", "description" etc)
template-parameter-content-message = [
    sha3_256(template-parameter-content-message-key),
    [ ...template-parameter-content-message-translation ]
]
template-parameter-content-index   = Cadence type of parameter
template-parameter-content-index   = Index of parameter in cadence transaction or script
template-parameter-content-balance = Fully qualified contract identifier of a token this parameter acts upon | ""
template-parameter-content         = [
    sha3_256(template-parameter-content-index),
    sha3_256(template-parameter-content-type),
    sha3_256(template-parameter-content-balance),
    [ ...template-parameter-content-message ]
]
template-parameter-label         = Label for an parameter
template-parameter               = [ sha3_256(template-parameter-label), [ ...template-parameter-content ]]

template-output-content-message-key-content   = UTF-8 string content of the message
template-output-content-message-key-bcp47-tag = BCP-47 language tag
template-output-content-message-translation   = [
  sha3_256(template-output-content-message-key-bcp47-tag),
  sha3_256(template-output-content-message-key-content)
]
template-output-content-message-key           = Key for a template message (eg: "title", "description" etc)
template-output-content-message = [
    sha3_256(template-output-content-message-key),
    [ ...template-output-content-message-translation ]
]
template-output-content         = [
    sha3_256(template-output-content-type),
    [ ...template-output-content-message ]
]
template-output-label         = Label for an output
template-output               = [ sha3_256(template-output-label), [ ...template-output-content ]]


template-cadence-body-resolved   =  The cadence body for the transaction/script with imports resolved for the given network
cadence-pins-network.                     =  The network name for this pin ("mainnet" | "testnet" | "emulator")
cadence-pins-pin                               =  sha3_256(template-cadence-body-resolved )

template-cadence-networks     = [
  sha3_256(cadence-pins-network), 
  cadence-pins-pin,
]

template-cadence-body          = The body of the cadence transaction or script with string imports

template-cadence-content      =  [
  sha3_256(template-cadence-body ),
  [...template-cadence-networks]
]

  sha3_256(cadence-pins-network), 
  sha3_256(cadence-pins-pin)
]
template-cadence-content      = [
  sha3_256(cadence.body),
  [...template-cadence-networks]
]


template-f-version            = Version of the InteractionTemplate data structure being serialized.
template-f-type               = "InteractionTemplate"
template-type                 = "transaction" | "script"
template-interface            = ID of the InteractionTemplateInterface this template implements | ""
template-messages             = [ ...template-message ] | []
template-cadence              = template-cadence-content
template-dependencies         = [ ...template-dependency ] | []
template-parameters           = [ ...template-parameter ] | []
template-output               = [ ...template-output ] | {}


template-encoded              = RLP([
    sha3_256(template-f-type),
    sha3_256(template-f-version),
    sha3_256(template-type),
    sha3_256(template-interface),
    template-messages,
    sha3_256(template-cadence),
    template-dependencies,
    template-parameters,
    template-output
])

template-encoded-hex          = hex( template-encoded )

template-id                   = sha3_256( template-encoded-hex )

WHERE:

X | Y
    Denotes either X or Y.
RLP([ X, Y, Z, ... ])
    Denotes RLP encoding of [X, Y, Z, ...]
hex(MESSAGE)
    Denotes transform of message into Hex string.
sha3_256(MESSAGE)
    Is the SHA3-256 hash function.
...
    Denotes multiple of a symbol in retained order
```

<h3>InteractionTemplateInterface f_version 2.0.0</h3>

```ruby
interface-f-version            = Version of the InteractionTemplateInterface data structure being serialized.
interface-f-type               = "InteractionTemplateInterface"
interface-parameter-type        = Cadence type of the parameter
interface-parameter-index       = Index of the parameter
interface-parameter-label       = Label of the parameter
interface-parameter             = [
    sha3_256(interface-parameter-label),
    sha3_256(interface-parameter-index),
    sha3_256(interface-parameter-type)
]

interface-flip                 = FLIP the interface was established in (eg: "FLIP-XXXX")
interface-parameters            = [ ...interface-parameter ] | []

interface-encoded              = RLP([
    sha3_256(interface-f-type),
    sha3_256(interface-f-version),
    sha3_256(interface-flip),
    interface-parameters
])

interface-encoded-hex          = hex( interface-encoded )

interface-id                   = sha3_256( interface-encoded-hex )

WHERE:

X | Y
    Denotes either X or Y.
RLP([ X, Y, Z, ... ])
    Denotes RLP encoding of [X, Y, Z, ...]
hex(MESSAGE)
    Denotes transform of message into Hex string.
sha3_256(MESSAGE)
    Is the SHA3-256 hash function.
...
    Denotes multiple of a symbol in retained order
```
<h2>Data Structure JSON Schemas</h2>

<h3>InteractionTemplate</h3>

```ruby
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "definitions": {
    "dependency_pin": {
      "type": "object",
      "properties": {
        "pin": {
          "type": "string"
        },
        "pin_self": {
          "type": "string"
        },
        "pin_contract_name": {
          "type": "string"
        },
        "pin_contract_address": {
          "type": "string"
        },
        "imports": {
          "type": "array",
          "items": [
            { "$ref": "#/definitions/dependency_pin" }
          ],
          "default": []
        }
      },
      "required": [
        "pin",
        "pin_self",
        "pin_contract_name",
        "pin_contract_address",
        "imports"
      ]
    }
  },
  "properties": {
    "f_type": {
      "type": "string"
    },
    "f_version": {
      "type": "string"
    },
    "id": {
      "type": "string"
    },
    "data": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        },
        "interface": {
          "type": "string"
        },
        "messages": {
          "type": "array",
          "items": [
            {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "i18n": {
                  "type": "array",
				          "items": [
                    {
                      "type": "object",
                      "properties": {
						            "tag": {
							            "type": "string",
                        },
						            "translation": {
							            "patternProperties": {
                            ".*": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              },
              "required": [
                "key",
                "i18n"
              ]
            },
            {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "i18n": {
                  "type": "array",
				          "items": [
                    {
                      "type": "object",
                      "properties": {
						            "tag": {
							            "type": "string",
                        },
						            "translation": {
							            "patternProperties": {
                            ".*": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              },
              "required": [
                "key",
                "i18n"
              ]
            }
          ]
        },
        "cadence": {
          "body": "string",
          "pins": [
            {
              "network": string,
              "pin": string
            },
            "required": [
              "network",
              "pin"
            ]
          ],
          "required": [
            "body",
            "pins"
          ]
        },
        "dependencies": {
          "type": "array",
          "items": [
            {
              "type": "object",
              "properties": {
                "contracts": {
                  "type": "array",
                  "items": [
                    {
                      "type": "object",
                      "properties": {
                        "contract": {
                          "type": "string"
                        },
                        "networks": {
                          "type": "array",
                          "items": [
                            {
                              "type": "object",
                              "properties": {
                                "network": {
                                  "type": "string"
                                },
                                "address": {
                                  "type": "string"
                                },
                                "dependency_pin_block_height": {
                                  "type": "integer"
                                },
                                "dependency_pin": {
                                  "$ref": "#/definitions/dependency_pin"
                                }
                              },
                              "required": [
                                "network",
                                "address",
                                "dependency_pin_block_height",
                                "dependency_pin"
                              ]
                            }
                          ]
                        }
                      },
                      "required": [
                        "contract",
                        "networks"
                      ]
                    }
                  ]
                }
              },
              "required": [
                "contracts"
              ]
            }
          ]
        },
        "parameters": {
          "type": "array",
          "items": [
            {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "index": {
                  "type": "integer"
                },
                "type": {
                  "type": "string"
                },
                "messages": {
                  "type": "array",
                  "items": [
                    {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "i18n": {
                          "type": "array",
                          "items": [
                            {
                              "type": "object",
                              "properties": {
                                "tag": {
                                  "type": "string",
                                },
                                "translation": {
                                  "patternProperties": {
                                    ".*": {
                                      "type": "string"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        }
                      },
                      "required": [
                        "key",
                        "i18n"
                      ]
                    }
                  ]
                },
                "balance": {
                  "type": "string"
                }
              },
              "required": [
                "key",
                "index",
                "type",
                "messages",
                "balance"
              ]
            },
            {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "index": {
                  "type": "integer"
                },
                "type": {
                  "type": "string"
                },
                "messages": {
                  "type": "array",
                  "items": [
                    {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "i18n": {
                          "type": "array",
                          "items": [
                            {
                              "type": "object",
                              "properties": {
                                "tag": {
                                  "type": "string",
                                },
                                "translation": {
                                  "patternProperties": {
                                    ".*": {
                                      "type": "string"
                                    }
                                  }
                                }
                              }
                            }
                          ]
                        }
                      },
                      "required": [
                        "key",
                        "i18n"
                      ]
                    }
                  ]
                }
              },
              "required": [
                "key",
                "index",
                "type",
                "messages"
              ]
            }
          ]
        },
        "output": {
          "type": "object",
          "properties": {
            "key": {
              "type": "string"
            },
            "index": {
              "type": "integer"
            },
            "type": {
              "type": "string"
            },
            "messages": {
              "type": "array",
              "items": [
                {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "i18n": {
                      "type": "array",
                      "items": [
                        {
                          "type": "object",
                          "properties": {
                            "tag": {
                              "type": "string",
                            },
                            "translation": {
                              "patternProperties": {
                                ".*": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      ]
                    }
                  },
                  "required": [
                    "key",
                    "i18n"
                  ]
                }
              ]
            }
          },
          "required": [
            "key",
            "index",
            "type",
            "messages",
          ]
        }
      },
      "required": [
        "type",
        "interface",
        "messages",
        "cadence",
        "dependencies",
        "parameters"
      ]
    }
  },
  "required": [
    "f_type",
    "f_version",
    "id",
    "data"
  ]
}
```

<h3>InteractionTemplateInterface</h3>

```ruby
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "f_type": {
      "type": "string"
    },
    "f_version": {
      "type": "string"
    },
    "id": {
      "type": "string"
    },
    "data": {
      "type": "object",
      "properties": {
        "flip": {
          "type": "string"
        },
        "title": {
          "type": "string"
        },
        "parameters": {
          "type": "array",
          "items": [
            {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "index": {
                  "type": "integer"
                },
                "type": {
                  "type": "string"
                }
              },
              "required": [
                "key",
                "index",
                "type"
              ]
            }
          ]
        }
      },
      "required": [
        "flip",
        "title",
        "parameters"
      ]
    }
  },
  "required": [
    "f_type",
    "f_version",
    "id",
    "data"
  ]
}
```


翻訳元

https://github.com/onflow/flips/blob/main/application/20230330-interaction-templates-1.1.0.md

***

<b>[Previous << Fees](https://qiita.com/flowcadence/items/c4c24a01ec3d6b7429e2)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (FLIX (Flow Interaction Templates))

<b>[Next >> Account Linking](https://qiita.com/flowcadence/items/b41866abc1858ba8acd1)</b>