Skip to content

v1.2.0 Migration Guide

Overview

Hyperledger FireFly v1.2.0 is a feature release that includes new features for tokens and data management as well as enhancements for debugging FireFly apps and operating FireFly nodes.

For the most part, upgrading from v1.1.x to v.1.2.0 should be a seamless experience, but there are several important things to note about changes between the two versions, which are described in detail on this page.

Tokens considerations

There are quite a few new features around tokens in FireFly v1.2.0. Most notably, FireFly's token APIs now work with a much wider variety of ERC-20, ERC-721, and ERC-1155 contracts, supporting variations of these contracts generated by the OpenZepplin Contract Wizard.

Sample token contract deprecations

In FireFly v1.2.0 two of the old, lesser used sample token contracts have been deprecated. The ERC20NoData and ERC721NoData contracts have been updated and the previous versions are no longer supported, unless you set the USE_LEGACY_ERC20_SAMPLE=true or USE_LEGACY_ERC721_SAMPLE=true environment variables for your token connector.

For more details you can read the description of the pull requests (#104 and #109) where these changes were made.

Differences from v1.1.0

Optional fields

Some token connectors support some optional fields when using them with certain contracts. For example, the ERC-721 token connector supports a URI field. If these optional fields are specified in an API call to a token connector and contract that does not support that field, an error will be returned, rather than the field being silently ignored.

Auto incrementing token index

In FireFly v1.2.0 the default ERC-721 and ERC-1155 contracts have changed to automatically increment the token index when a token is minted. This is useful when many tokens may be minted around the same time, or by different minters. This lets the blockchain handle the ordering, and keeping track of the state of which token index should be minted next, rather than making that an application concern.

NOTE: These new contracts will only be used for brand new FireFly stacks with v1.2.0. If you have an existing stack, the new token contracts will not be used, unless you specifically deploy them and start using them.

Data management considerations

FireFly v1.2.0 introduces the ability to delete data records and their associated blobs, if present. This will remove the data and blob rows from the FireFly database, as well as removing the blob from the Data Exchange microservice. This can be very useful if your organization has data retention requirements for sensitive, private data and needs to purge data after a certain period of time.

Please note that this API only removes data from the FireFly node on which it is called. If data has been shared with other participants of a multi-party network, it is each participants' responsibility to satisfy their own data retention policies.

Differences from v1.1.0

It is important to note that FireFly now stores a separate copy of a blob for a given payload, even if the same data object is sent in different messages, by different network participants. Previously, in FireFly v1.1.0 the blob was de-duplicated in some cases. In FireFly v1.2.0, deleting the data object will result in each copy of the associated payload being removed.

NOTE: If data has been published to IPFS, it cannot be deleted completely. You can still call the DELETE method on it, and it will be removed from FireFly's database and Data Exchange, but the payload will still persist in IPFS.

Application considerations

Optional tokens fields

Please see the optional token fields section above for details. If your application code is calling any token API endpoints with optional fields that are not supported by your token connector or contract, you will need to remove those fields from your API request or it will fail.

Transaction output details

In previous versions of FireFly, transaction output details used to appear under the output object in the response body. Behind the scenes, some of this data is now fetched from the blockchain connector asynchronously. If your application needs the detailed output, it should now add a fetchStatus=true query parameter when querying for an Operation. Additionally the details have moved from the output field to a new detail field on the response body. For more details, please refer to the PRs where this change was made (#1111 and #1151). For a detailed example comparing what an Operation response body looks like in FireFly v1.2.0 compared with v1.1.x, you can expand the sections below.

v1.2.0 Operation response body with `fetchStatus=true`
{
  "id": "2b0ec132-2abd-40f0-aa56-79871a7a23b9",
  "namespace": "default",
  "tx": "cb0e6de1-50a9-44f2-a2ff-411f6dcc19c9",
  "type": "blockchain_invoke",
  "status": "Succeeded",
  "plugin": "ethereum",
  "input": {
    "idempotencyKey": "5a634941-29cb-4a4b-b5a7-196331723d6d",
    "input": {
      "newValue": 42
    },
    "interface": "46189886-cae5-42ff-bf09-25d4f58d649e",
    "key": "0x2ecd8d5d97fb4bb7af0fbc27d7b89fd6f0366350",
    "location": {
      "address": "0x9d7ea8561d4b21cba495d1bd29a6d3421c31cf8f"
    },
    "method": {
      "description": "",
      "id": "d1d2a0cf-19ea-42c3-89b8-cb65850fb9c5",
      "interface": "46189886-cae5-42ff-bf09-25d4f58d649e",
      "name": "set",
      "namespace": "default",
      "params": [
        {
          "name": "newValue",
          "schema": {
            "details": {
              "type": "uint256"
            },
            "type": "integer"
          }
        }
      ],
      "pathname": "set",
      "returns": []
    },
    "methodPath": "set",
    "options": null,
    "type": "invoke"
  },
  "output": {
    "Headers": {
      "requestId": "default:2b0ec132-2abd-40f0-aa56-79871a7a23b9",
      "type": "TransactionSuccess"
    },
    "protocolId": "000000000052/000000",
    "transactionHash": "0x9adae77a46bf869ee97aab38bb5d789fa2496209500801e87bf9e2cce945dc71"
  },
  "created": "2023-01-24T14:08:17.371587084Z",
  "updated": "2023-01-24T14:08:17.385558417Z",
  "detail": {
    "created": "2023-01-24T14:08:17.378147625Z",
    "firstSubmit": "2023-01-24T14:08:17.381787042Z",
    "gas": "42264",
    "gasPrice": 0,
    "history": [
      {
        "count": 1,
        "info": "Success=true,Receipt=000000000052/000000,Confirmations=0,Hash=0x9adae77a46bf869ee97aab38bb5d789fa2496209500801e87bf9e2cce945dc71",
        "lastOccurrence": null,
        "time": "2023-01-24T14:08:17.384371042Z"
      },
      {
        "count": 1,
        "info": "Submitted=true,Receipt=,Hash=0x9adae77a46bf869ee97aab38bb5d789fa2496209500801e87bf9e2cce945dc71",
        "lastOccurrence": null,
        "time": "2023-01-24T14:08:17.381908959Z"
      }
    ],
    "id": "default:2b0ec132-2abd-40f0-aa56-79871a7a23b9",
    "lastSubmit": "2023-01-24T14:08:17.381787042Z",
    "nonce": "34",
    "policyInfo": null,
    "receipt": {
      "blockHash": "0x7a2ca7cc57fe1eb4ead3e60d3030b123667d18eb67f4b390fb0f51f970f1fba0",
      "blockNumber": "52",
      "extraInfo": {
        "contractAddress": null,
        "cumulativeGasUsed": "28176",
        "from": "0x2ecd8d5d97fb4bb7af0fbc27d7b89fd6f0366350",
        "gasUsed": "28176",
        "status": "1",
        "to": "0x9d7ea8561d4b21cba495d1bd29a6d3421c31cf8f"
      },
      "protocolId": "000000000052/000000",
      "success": true,
      "transactionIndex": "0"
    },
    "sequenceId": "0185e41b-ade2-67e4-c104-5ff553135320",
    "status": "Succeeded",
    "transactionData": "0x60fe47b1000000000000000000000000000000000000000000000000000000000000002a",
    "transactionHash": "0x9adae77a46bf869ee97aab38bb5d789fa2496209500801e87bf9e2cce945dc71",
    "transactionHeaders": {
      "from": "0x2ecd8d5d97fb4bb7af0fbc27d7b89fd6f0366350",
      "to": "0x9d7ea8561d4b21cba495d1bd29a6d3421c31cf8f"
    },
    "updated": "2023-01-24T14:08:17.384371042Z"
  }
}
v1.1.x Operation response body
{
  "id": "4a1a19cf-7fd2-43f1-8fae-1e3d5774cf0d",
  "namespace": "default",
  "tx": "2978a248-f5df-4c78-bf04-711ab9c79f3d",
  "type": "blockchain_invoke",
  "status": "Succeeded",
  "plugin": "ethereum",
  "input": {
    "idempotencyKey": "5dc2ee8a-be5c-4e60-995f-9e21818a441d",
    "input": {
      "newValue": 42
    },
    "interface": "752af5a3-d383-4952-88a9-b32b837ed1cb",
    "key": "0xd8a27cb390fd4f446acce01eb282c7808ec52572",
    "location": {
      "address": "0x7c0a598252183999754c53d97659af9436293b82"
    },
    "method": {
      "description": "",
      "id": "1739f25d-ab48-4534-b278-58c4cf151bf9",
      "interface": "752af5a3-d383-4952-88a9-b32b837ed1cb",
      "name": "set",
      "namespace": "default",
      "params": [
        {
          "name": "newValue",
          "schema": {
            "details": {
              "type": "uint256"
            },
            "type": "integer"
          }
        }
      ],
      "pathname": "set",
      "returns": []
    },
    "methodPath": "set",
    "options": null,
    "type": "invoke"
  },
  "output": {
    "_id": "default:4a1a19cf-7fd2-43f1-8fae-1e3d5774cf0d",
    "blockHash": "0x13660667b69f48646025a87db603abdeeaa88036e9a1252b1af4ec1fc3e1d850",
    "blockNumber": "52",
    "cumulativeGasUsed": "28176",
    "from": "0xd8a27cb390fd4f446acce01eb282c7808ec52572",
    "gasUsed": "28176",
    "headers": {
      "id": "8dfaabd1-4493-4a64-52dd-762497022ba2",
      "requestId": "default:4a1a19cf-7fd2-43f1-8fae-1e3d5774cf0d",
      "requestOffset": "",
      "timeElapsed": 0.109499833,
      "timeReceived": "2023-01-24T17:16:52.372449013Z",
      "type": "TransactionSuccess"
    },
    "nonce": "0",
    "receivedAt": 1674580612482,
    "status": "1",
    "to": "0x7c0a598252183999754c53d97659af9436293b82",
    "transactionHash": "0x522e5aac000f5befba61ddfd707aaf5c61314f47e00cd0c5b779f69dd14bd899",
    "transactionIndex": "0"
  },
  "created": "2023-01-24T17:16:52.368498346Z",
  "updated": "2023-01-24T17:16:52.48408293Z"
}

Local development considerations

It is also worth noting that the default Ethereum blockchain connector in the FireFly CLI is now Evmconnect. Ethconnect is still fully supported, but FireFly v1.2.0 marks a point of maturity in the project where it is now the recommended choice for any Ethereum based FireFly stack.