JSON-Cadence format

[Previous << Contract Upgrades with Incompatible Changes](https://qiita.com/flowcadence/items/498b5469c8fd62715e55)
[Next >> Measuring Time In Cadence](https://qiita.com/flowcadence/items/1aefd14bce23a00518ec)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#cadenceの言語仕様を学ぶ

JSON-Cadenceは、Cadenceの値を言語に依存しないJSONオブジェクトとして表現するために使用されるデータ交換フォーマットです。
このフォーマットは完全な[ABI](https://en.wikipedia.org/wiki/Application_binary_interface)よりも型情報が少なく、代わりに以下の原則を推進しています。

* 人間にとって読みやすい - JSON-Cadenceは読みやすく理解しやすいので、開発やデバッグのスピードアップにつながります。
* 互換性 - JSONは、ほとんどの高レベルプログラミング言語に組み込まれたサポート機能を持つ共通フォーマットであるため、さまざまなプラットフォームで簡単に解析できます。
* 移植性 - JSON-Cadenceは自己記述型であるため、型定義（例えばABI）を伴わずに転送およびデコードが可能です。

<h1 id="Values">Values</h1>
<h3 id="Void">Void</h3>

```ruby
{
  "type": "Void"
}
```
例
```ruby
{
  "type": "Void"
}
```
<h3 id="Optional">Optional</h3>

```ruby
{
  "type": "Optional",
  "value": null | <value>
}
```
例
```ruby
/* Non-nil */

{
  "type": "Optional",
  "value": {
    "type": "UInt8",
    "value": "123"
  }
}

/* Nil */

{
  "type": "Optional",
  "value": null
}
```
<h3 id="Bool">Bool</h3>

```ruby
{
  "type": "Bool",
  "value": true | false
}
```
例
```ruby
{
  "type": "Bool",
  "value": true
}
```

<h3 id="String">String</h3>

```ruby
{
  "type": "String",
  "value": "..."
}
```
例
```ruby
{
  "type": "String",
  "value": "Hello, world!"
}
```

<h3 id="Address">Address</h3>

```ruby
{
  "type": "Address",
  "value": "0x0" /* as hex-encoded string with 0x prefix */
}
```
例
```ruby
{
  "type": "Address",
  "value": "0x1234"
}
```

<h3 id="Integers">Integers</h3>

`[U]Int`, `[U]Int8`, `[U]Int16`, `[U]Int32`, `[U]Int64`, `[U]Int128`, `[U]Int256`, `Word8`, `Word16`, `Word32`, `Word64`, `Word128` or `Word256`

JSONは64ビットまでの整数リテラルをサポートしていますが、一貫性を保つため、すべての整数型は文字列としてエンコードされます。

デコードには厳密には静的型は必要ありませんが、クライアントに範囲の可能性を通知するために提供されます。
```ruby
{
  "type": "<type>",
  "value": "<decimal string representation of integer>"
}
```
例
```ruby
{
  "type": "UInt8",
  "value": "123"
}
```

<h3 id="Fixed-Point-Numbers">Fixed Point Numbers</h3>

`[U]Fix64`

固定小数点数は整数として実装されていますが、JSON-Cadenceでは可読性を考慮して小数表記を使用しています。
```ruby
{
  "type": "[U]Fix64",
  "value": "<integer>.<fractional>"
}
```
例
```ruby
{
  "type": "Fix64",
  "value": "12.3"
}
```

<h3 id="Array">Array</h3>

```ruby
{
  "type": "Array",
  "value": [
    <value at index 0>,
    <value at index 1>
    // ...
  ]
}
```
例
```ruby
{
  "type": "Array",
  "value": [
    {
      "type": "Int16",
      "value": "123"
    },
    {
      "type": "String",
      "value": "test"
    },
    {
      "type": "Bool",
      "value": true
    }
  ]
}
```

<h3 id="Dictionary">Dictionary</h3>
Dictionaryは、Cadenceによって実装された決定論的順序を維持するために、キーと値のペアのリストとしてエンコードされます。

```ruby
{
  "type": "Dictionary",
  "value": [
    {
      "key": "<key>",
      "value": <value>
    },
    ...
  ]
}
```
例
```ruby
{
  "type": "Dictionary",
  "value": [
    {
      "key": {
        "type": "UInt8",
        "value": "123"
      },
      "value": {
        "type": "String",
        "value": "test"
      }
    }
  ]
  // ...
}
```

<h2 id="Composites">Composites</h2>

<h3>(Struct, Resource, Event, Contract, Enum)</h3>

Compositeのフィールドは、Compositeの型宣言に現れる順序で、名前と値のペアのリストとしてエンコードされます。(原文: Composite fields are encoded as a list of name-value pairs in the order in which they appear in the composite type declaration.)

```ruby
{
  "type": "Struct" | "Resource" | "Event" | "Contract" | "Enum",
  "value": {
    "id": "<fully qualified type identifier>",
    "fields": [
      {
        "name": "<field name>",
        "value": <field value>
      },
      // ...
    ]
  }
}
```
例
```ruby
{
  "type": "Resource",
  "value": {
    "id": "0x3.GreatContract.GreatNFT",
    "fields": [
      {
        "name": "power",
        "value": { "type": "Int", "value": "1" }
      }
    ]
  }
}
```

<h2 id="Path">Path</h2>

```ruby
{
  "type": "Path",
  "value": {
    "domain": "storage" | "private" | "public",
    "identifier": "..."
  }
}
```
例
```ruby
{
  "type": "Path",
  "value": {
    "domain": "storage",
    "identifier": "flowTokenVault"
  }
}
```

<h2 id="Type Value">Type Value</h2>

```ruby
{
  "type": "Type",
  "value": {
    "staticType": <type>
  }
}
```
例
```ruby
{
  "type": "Type",
  "value": {
    "staticType": {
      "kind": "Int"
    }
  }
}
```

<h2 id="InclusiveRange">InclusiveRange</h2>

```ruby
{
  "type": "InclusiveRange",
  "value": {
    "start": <start_value>,
    "end": <end_value>,
    "step": <step_value>
  }
}
```
例
```ruby
{
  "type": "InclusiveRange",
  "value": {
    "start": {
      "type": "Int256",
      "value": "10"
    },
    "end": {
      "type": "Int256",
      "value": "20"
    },
    "step": {
      "type": "Int256",
      "value": "5"
    }
  }
}
```

<h2 id="Capability">Capability</h2>

```ruby
{
  "type": "Capability",
  "value": {
    "id": <Number>,
    "address": "0x0",  /* as hex-encoded string with 0x prefix */
    "borrowType": <type>,
  }
}
```
例
```ruby
{
  "type": "Capability",
  "value": {
    "id": "1",
    "address": "0x1",
    "borrowType": {
      "kind": "Int"
    }
  }
}
```

<h2 id="Functions">Functions</h2>

```ruby
{
  "type": "Function",
  "value": {
    "functionType": <type>
  }
}
```
Functionの値はエクスポートのみ可能で、インポートはできません。

例
```ruby
{
  "type": "Function",
  "value": {
    "functionType": {
      "kind": "Function",
      "typeID": "fun():Void",
      "parameters": [],
      "return": {
        "kind": "Void"
      }
    }
  }
}
```

<h1 id="Types">Types</h1>

<h3 id="Simple-Types">Simple Types</h3>

これらは、`Int`、`String`、`StoragePath`のような基本的な型です。

```ruby
{
  "kind": <kind>
}
```
ここで`kind`は次のいずれかです。
  * `Account`
  * `AccountCapabilityController`
  * `AccountKey`
  * `Address`
  * `AnyResource`
  * `AnyResourceAttachment`
  * `AnyStruct`
  * `AnyStructAttachment`
  * `Block`
  * `Bool`
  * `Capability`
  * `CapabilityPath`
  * `Character`
  * `DeployedContract`
  * `DeploymentResult`
  * `Fix64`
  * `FixedPoint`
  * `FixedSizeUnsignedInteger`
  * `HashAlgorithm`
  * `HashableStruct`
  * `Int`
  * `Int128`
  * `Int16`
  * `Int256`
  * `Int32`
  * `Int64`
  * `Int8`
  * `Integer`
  * `Never`
  * `Number`
  * `Path`
  * `PrivatePath`
  * `PublicKey`
  * `PublicPath`
  * `SignatureAlgorithm`
  * `SignedFixedPoint`
  * `SignedInteger`
  * `SignedNumber`
  * `StorageCapabilityController`
  * `StoragePath`
  * `String`
  * `Type`
  * `UFix64`
  * `UInt`
  * `UInt128`
  * `UInt16`
  * `UInt256`
  * `UInt32`
  * `UInt64`
  * `UInt8`
  * `Void`
  * `Word128`
  * `Word16`
  * `Word256`
  * `Word32`
  * `Word64`
  * `Word8`

例
```ruby
{
  "kind": "UInt8"
}
```

<h3 id="Optional-Types">Optional Types</h3>

```ruby
{
  "kind": "Optional",
  "type": <type>
}
```
例
```ruby
{
  "kind": "Optional",
  "type": {
    "kind": "String"
  }
}
```

<h3>Variable Sized Array Types</h3>

```ruby
{
  "kind": "VariableSizedArray",
  "type": <type>
}
```
例
```ruby
{
  "kind": "VariableSizedArray",
  "type": {
    "kind": "String"
  }
}
```

<h3>Constant Sized Array Types</h3>

```ruby
{
  "kind": "ConstantSizedArray",
  "type": <type>,
  "size": <length of array>,
}
```
例
```ruby
{
  "kind": "ConstantSizedArray",
  "type": {
    "kind": "String"
  },
  "size": 3
}
```

<h3>Dictionary Types</h3>

```ruby
{
  "kind": "Dictionary",
  "key": <type>,
  "value": <type>
}
```
例
```ruby
{
  "kind": "Dictionary",
  "key": {
    "kind": "String"
  },
  "value": {
    "kind": "UInt16"
  }
}
```

<h3>Composite Types</h3>

```ruby
{
  "kind": "Struct" | "Resource" | "Event" | "Contract" | "StructInterface" | "ResourceInterface" | "ContractInterface",
  "type": "", /* this field exists only to keep parity with the enum structure below; the value must be the empty string */
  "typeID": "<fully qualified type ID>",
  "initializers": [
    <initializer at index 0>,
    <initializer at index 1>
    /* ... */
  ],
  "fields": [
    <field at index 0>,
    <field at index 1>
    /* ... */
  ],
}
```
例
```ruby
{
  "kind": "Resource",
  "type": "",
  "typeID": "0x3.GreatContract.GreatNFT",
  "initializers": [
    [
      {
        "label": "foo",
        "id": "bar",
        "type": {
          "kind": "String"
        }
      }
    ]
  ],
  "fields": [
    {
      "id": "foo",
      "type": {
        "kind": "String"
      }
    }
  ]
}
```

<h3>Field Types</h3>

```ruby
{
  "id": "<name of field>",
  "type": <type>
}
```
例
```ruby
{
  "id": "foo",
  "type": {
    "kind": "String"
  }
}
```

<h3>Parameter Types</h3>

```ruby
{
  "label": "<label>",
  "id": "<identifier>",
  "type": <type>
}
```
例
```ruby
{
  "label": "foo",
  "id": "bar",
  "type": {
    "kind": "String"
  }
}
```

<h3>Initializer Types</h3>

初期化子型には、初期化子(init関数)へのパラメータのリストがエンコードされています。
```ruby
[
  <parameter at index 0>,
  <parameter at index 1>,
  /* ... */
]
```
例
```ruby
[
  {
    "label": "foo",
    "id": "bar",
    "type": {
      "kind": "String"
    }
  }
]
```

<h3>Function Types</h3>

```ruby
{
  "kind": "Function",
  "typeID": "<function name>",
  "parameters": [
    <parameter at index 0>,
    <parameter at index 1>,
    /* ... */
  ],
  "purity: "view" | undefined,
  "return": <type>
}
```
例
```ruby
{
  "kind": "Function",
  "typeID": "foo",
  "parameters": [
    {
      "label": "foo",
      "id": "bar",
      "type": {
        "kind": "String"
      }
    }
  ],
  "purity": "view",
  "return": {
    "kind": "String"
  }
}
```

<h3>Reference Types</h3>

```ruby
{
  "kind": "Reference",
  "authorization": {
    "kind": "Unauthorized" | "EntitlementMapAuthorization" | "EntitlementConjunctionSet" | "EntitlementDisjunctionSet",
    "entitlements": [
    <entitlement at index 0>,
    <entitlement at index 1>
    /* ... */
    ]
    },
  "type": <type>
}
```
例
```ruby
{
  "kind": "Reference",
  "authorization": {
    {
      "kind": "EntitlementMapAuthorization",
      "entitlements": [
        {
          "kind": "EntitlementMap",
          "typeID": "foo"
        }
      ]
    }
  },
  "type": {
    "kind": "String"
  }
}
```

<h3>Intersection Types</h3>

```ruby
{
  "kind": "Intersection",
  "typeID": "<fully qualified type ID>",
  "types": [
    <type at index 0>,
    <type at index 1>,
    /* ... */
  ]
}
```
例
```ruby
{
  "kind": "Intersection",
  "typeID": "{0x1.FungibleToken.Receiver}",
  "types": [
    {
      "kind": "ResourceInterface",
      "typeID": "0x1.FungibleToken.Receiver",
      "fields": [
        {
          "id": "uuid",
          "type": {
            "kind": "UInt64"
          }
        }
      ],
      "initializers": [],
      "type": ""
    }
  ]
}
```

<h3>Capability Types</h3>

```ruby
{
  "kind": "Capability",
  "type": <type>
}
```
例
```ruby
{
  "kind": "Capability",
  "type": {
    "kind": "Reference",
    "authorization": {
      "kind": "Unauthorized",
      "entitlements": null
    },
    "type": {
      "kind": "String"
    }
  }
}
```

<h3>Enum Types</h3>

```ruby
{
  "kind": "Enum",
  "type": <type>,
  "typeID": "<fully qualified type ID>",
  "initializers":[],
  "fields": [
    {
      "id": "rawValue",
      "type": <type>
    }
  ]
}
```
例
```ruby
{
  "kind": "Enum",
  "type": {
    "kind": "String"
  },
  "typeID": "0x3.GreatContract.GreatEnum",
  "initializers": [],
  "fields": [
    {
      "id": "rawValue",
      "type": {
        "kind": "String"
      }
    }
  ]
}
```

<h3>Repeated Types</h3>

複合型が同じJSON型エンコーディング内で複数回現れる場合、それは再帰的であるか、または（複合フィールド内で）繰り返されるためであり、その複合型は代わりにその型IDで表されます。

例
```ruby
{
  "type": "Type",
  "value": {
    "staticType": {
      "kind": "Resource",
      "typeID": "0x3.GreatContract.NFT",
      "fields": [
        {
          "id": "foo",
          "type": {
            "kind": "Optional",
            "type": "0x3.GreatContract.NFT"
                    /* recursive NFT resource type is instead encoded as an ID */
          }
        }
      ],
      "initializers": [],
      "type": ""
    }
  }
}
```

<h3>Inclusive Range Type</h3>

```ruby
{
  "kind": "InclusiveRange",
  "element":  <integer_type>
}
```
例
```ruby
{
  "kind": "InclusiveRange",
  "element": {
    "kind": "Int"
  }
}
```

翻訳元

https://cadence-lang.org/docs/json-cadence-spec

***
<b>[Previous << Contract Upgrades with Incompatible Changes](https://qiita.com/flowcadence/items/498b5469c8fd62715e55)
</b>

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

<b>[Next >> Measuring Time In Cadence](https://qiita.com/flowcadence/items/1aefd14bce23a00518ec)</b>