アトミック・トランザクションの呼出し

post

/restproxy/api/v2/atomicTransactions

アトミック・トランザクションを呼び出します。これにより、複数のチャネルにまたがる複数のトランザクションをアトミックにコミットできます。すべてのトランザクションが正常にコミットされるか、いずれもコミットされません。

リクエスト

サポートされるメディア・タイプ
本文()
トランザクションを呼び出すリクエスト
ルート・スキーマ: schema
型: object
ソースの表示
ネストしたスキーマ: atomicTransactionLRCReq
型: object
最終リソース・コミット(lrc)トランザクションとして実行されるトランザクションのリクエスト本文
ソースの表示
ネストしたスキーマ: transactions
型: array
処理する個々のトランザクションの配列
ソースの表示
ネストしたスキーマ: atomicTransactionEthRequest
型: object
実行するethereumトランザクションのリクエスト本文
ソースの表示
ネストしたスキーマ: finalityParams
型: object
ソースの表示
  • トランザクションが最終とみなされるまでに待機するブロック数
  • トランザクションにトランザクション・ファイナリティ・チェックが必要かどうかを指定します。trueの場合、blocksToWaitまたはsecondsToWaitのいずれかが満たされた後にトランザクションが再チェックされます
  • トランザクションが最終とみなされるまでに待機する秒数
ネストしたスキーマ: signedReq
型: object
ソースの表示
ネストしたスキーマ: unsignedReq
型: object
ソースの表示
  • スマート・コントラクトでコールされるスマート・コントラクト・アプリケーション・バイナリ・インタフェース(ABI)またはメソッドABI。isContractCallがtrueに設定されている場合は必須
  • トランザクションとともに使用される16進入力データ。スマート・コントラクトの実行に使用されます
  • 送信者から受信者に転送するETHの金額(WEI単位)
  • ユーザーがトランザクションに対して支払を希望する最大料金
  • トランザクションで消費可能なガス単位の最大量
  • 取引で使用されるガス単位ごとのWeiでの価格
  • バリデータへのチップとして含める最大料金
  • デフォルト値: false
    指定されたリクエストがスマート・コントラクト・コールかどうかを指定します
  • スマート・コントラクトでコールされるメソッド名。isContractCallがtrueに設定されている場合は必須
  • アカウントによって実行される一連のトランザクションを表すトランザクション・カウンタ
  • paramKeys
    最終OBPチェーンコード・トランザクションの結果から抽出され、パラメータを介してスマート・コントラクトに送信されるキーのリスト
  • params
    使用可能な追加プロパティ: true
    スマート・コントラクトでコールされるメソッドに必要なパラメータ。isContractCallがtrueに設定されている場合は必須
  • ソース・アカウントの秘密キーを表す16進文字列
  • ETH転送の完了時の受取アドレス、またはスマート・コントラクトの実行時の契約アドレス
  • レガシー・トランザクションを表すには0を選択し、EIP-1559トランザクションを表すには2(デフォルト)を選択します
ネストしたスキーマ: paramKeys
型: array
最終OBPチェーンコード・トランザクションの結果から抽出され、パラメータを介してスマート・コントラクトに送信されるキーのリスト
ソースの表示
ネストしたスキーマ: params
型: object
使用可能な追加プロパティ: true
スマート・コントラクトでコールされるメソッドに必要なパラメータ。isContractCallがtrueに設定されている場合は必須
ネストしたスキーマ: atomicTransactionInvokeReq
型: object
ソースの表示
ネストしたスキーマ: args
型: array
チェーンコードに対する引数
ソースの表示
ネストしたスキーマ: endorsers
型: array
チェーンコードのエンドーサ
ソースの表示
ネストしたスキーマ: transientMap
型: object
使用可能なその他のプロパティ
ソースの表示
チェーンコードのtransientMap
先頭に戻る

レスポンス

サポートされるメディア・タイプ

201レスポンス

同期トランザクションの操作の成功
本文()
ルート・スキーマ: schema
型: object
ソースの表示
ネストしたスキーマ: atomicTransactionResults
型: object
ソースの表示
ネストしたスキーマ: atomicTransactionLRCResults
型: object
ソースの表示
ネストしたスキーマ: transactions
型: array
処理された個々のトランザクションの詳細
ソースの表示
ネストしたスキーマ: atomicTransactionEthResponse
型: object
ソースの表示
  • コミットされたトランザクションのブロック番号
  • 失敗の場合のエラー・メッセージ
  • 実行されたトランザクションを表す16進文字列
ネストしたスキーマ: atomicTransactionIndividualResults
型: object
ソースの表示
ネストしたスキーマ: commit
型: object
トランザクションのコミット・フェーズの詳細
ソースの表示
  • トランザクションが失敗した場合のエラー・メッセージ
  • コミット・フェーズのトランザクションID
ネストしたスキーマ: prepare
型: object
トランザクションの準備フェーズの詳細
ソースの表示
  • トランザクションが失敗した場合のエラー・メッセージ
  • 準備フェーズのトランザクションID
ネストしたスキーマ: rollback
型: object
トランザクションのロールバック・フェーズの詳細
ソースの表示
  • トランザクションが失敗した場合のエラー・メッセージ
  • ロールバック・フェーズのトランザクションID

202レスポンス

非同期トランザクションの操作の成功
本文()
ルート・スキーマ: schema
型: object
ソースの表示
ネストしたスキーマ: result
型: object
ソースの表示

400レスポンス

不正なリクエスト

401レスポンス

未認可

403レスポンス

禁止されています

404レスポンス

無効なパラメータ

500レスポンス

サービス使用不可
先頭に戻る

2つのチェーンコードを使用したアトミック・トランザクションの例

次の例は、cURLを使用してRESTリソースにPOSTリクエストを送信することにより、2つのチェーンコード・トランザクションで構成されるアトミック・トランザクションを呼び出す方法を示しています。

curl -v -u <username>:<password> -X POST \
  "https://<rest proxy of your blockchain instance>/api/v2/atomicTransactions" \
  -H "accept: application/json" \
  -H "Content-Type: application/json" \
  --data @<JSON file with the request parameters>

たとえば、

curl -v -u <username>:<password> -X POST \
  "https://myvm.oracle.com:10001/restproxy/api/v2/atomicTransactions" \
  -H "accept: application/json" \
  -H "Content-Type: application/json" 
  --data @file.json
file.jsonの内容は次のとおりです。
{
 "transactions": [
   {"chaincode":"obcs-marbles","args":["transferMarble", "marble1", "tom"],"timeout":0, "channel":"goods"},
   {"chaincode":"obcs-example02","args":["invoke", "a", "b", "50"],"timeout":0, "channel":"wallet"}
 ],
 "isolationLevel": "serializable",
 "prepareTimeout": 10000,
 "sync": true
}
説明:
  • transactionsは、2つのチェーンコード・トランザクションを含む配列です。最初のトランザクションは、Marblesサンプル・チェーンコードを使用してmarbleを転送します。2番目のトランザクションは、Balance Transferサンプル・チェーンコードを使用してmarbleの代金を支払います。
  • argsは、呼び出すチェーンコード関数とそのパラメータを指定します。
  • serializable値を指定したisolationLevelは、トランザクションの読取りおよび書込みセット内のすべてのキーが準備フェーズとコミット・フェーズの間でロックされることを示します。分離のreadCommitted値は、トランザクションの一連の書込みのキーが準備フェーズとコミット・フェーズの間でロックされることを示します。
  • timeoutは、準備フェーズ中にトランザクションがタイムアウトするまでの最大ミリ秒を指定します。
  • synctrue値の場合は、これが同期トランザクションであることを示します。

次の例に、成功したアトミック・トランザクションに対するJSON形式のレスポンス本文の内容を示します:

{
  "returnCode": "Success",
  "error": "",
  "result": {
    "transactions": [
      {
        "channel": "goods",
        "chaincode": "obcs-marbles",
        "txstatus": "Committed",
        "prepare": {
          "txid": "bb248ef3f948cb107417c3f66ea144910644dee8086a370d44687fd9fe262233"
        },
        "commit": {
          "txid": "21068846ef85942f9df1ccfd27dcb95d509146c5a0d10c6366642215badcb3b4"
        },
        "rollback": {}
      },
      {
        "channel": "wallet",
        "chaincode": "obcs-example02",
        "txstatus": "Committed",
        "prepare": {
          "txid": "08d03d7170e7f696c79da0aa60142bbfdc08b3d92cee0d9423983dd19caf809c"
        },
        "commit": {
          "txid": "ef9d8a824631f9e671162b81c7d1617080746ef3897b029cfbef1cfd1594d0ab"
        },
        "rollback": {}
      }
    ],
    "globalStatus": "Success",
    "globalTxid": "21438a99-9fd7-4f96-b0bf-259910a26006",
    "txStartTime": "2022-08-15T16:16:19.2180799642"
  }
}

この場合、globalStatusに返される値はSuccessで、アトミック・トランザクションを構成するすべてのトランザクションが正常にコミットされたことを示します。

次の例は、準備フェーズ中に操作の1つでエラーが発生した、失敗したアトミック・トランザクションのレスポンスを示しています。ここで、整数値を必要とするBalance Transferパラメータに整数以外の値が指定されました。この場合、準備フェーズで成功したトランザクションはロールバックされます。

{
  "returnCode": "Failure",
  "error": "blockchain transaction error",
  "result": {
    "transactions": [
      {
        "channel": "goods",
        "chaincode": "obcs-marbles",
        "txstatus": "Rolledback",
        "prepare": {
          "txid": "bb248ef3f948cb107417c3f66ea144910644dee8086a370d44687fd9fe262233"
        },
        "commit": {},
        "rollback": {
          "txid": "21068846ef85942f9df1ccfd27dcb95d509146c5a0d10c6366642215badcb3b4"
        },
      },
      {
        "channel": "wallet",
        "chaincode": "obcs-example02",
        "txstatus": "FailedPrepare",
        "prepare": {
          "error": "failed to invoke chaincode: Transaction processing for endorser [myvm.oracle.com:20010]: Chaincode status Code: (500) UNKNOWN.
            Description: Invalid transaction amount, expecting a integer value"
        },
        "commit": {},
        "rollback": {
          "error":"skipping rollback since prepare stage has failed or was skipped"
        }
      }
    ],
    "globalStatus": "Failure",
    "globalTxid": "21438a99-9fd7-4f96-b0bf-259910a26006",
    "txStartTime": "2022-08-15T16:16:19.2180799642"
  }
}

Ethereumトランザクションの例

Ethereumトランザクションは、準備フェーズとコミット・フェーズに分割できないため、最終リソース・コミット(LRC)最適化を使用してアトミック・ワークフローでサポートされます。他のすべてのトランザクションが準備完了状態になると、Ethereumトランザクションが開始されます。Ethereumトランザクションが成功すると、他のトランザクションがコミットされます。Ethereumトランザクションが失敗すると、他のトランザクションはロールバックされます。

次のJSONファイルは、lrcセクションに署名なしEthereumトランザクションを記述し、他の2つのチェーンコード・トランザクションを呼び出すアトミック・トランザクションとともに含める方法を示しています。lrcセクションには、トランザクションを説明するethReqセクションと、トランザクションのファイナリティを待機する時間を決定するfinalityParamsセクションが含まれています。
{
 "transactions": [
   {"chaincode":"bt1","args":["invoke", "a", "b", "7"],"timeout":0, "channel":"ch1"},
   {"chaincode":"bt2","args":["invoke", "a", "b", "5"],"timeout":0, "channel":"ch2"}
 ],
 "lrc": {
   "ethReq": {
     "url": "http://<IP address of Ethereum server>:<port>",
     "chainId": 1337,
     "unSignedReq": {
        "privateKey": "de1fab4e05b476f81d11901a69e58a3000859395eb6bdb222fcb583b8d599b00",
        "ethValue": "1000000000000000000",
        "gasLimit": 21000,
        "toAddress": "0x7336d04f97fdccd0a93462947474c8879a5c6597"
     },
     "finalityParams": {
       "checkFinality": true,
       "blocksToWait": 2,
       "secondsToWait": 30
     }
   }
 },
 "isolationLevel": "serializable",
 "prepareTimeout": 10000,
 "sync": true
}
説明(前述のパラメータ以外):
  • urlは、プロトコルおよびポート番号を含むEthereumエンドポイントのURLです。
  • chainIdは、EthereumネットワークのネットワークIDです。
  • unsignedReqは、次のパラメータを含む署名なしリクエスト本文です:
    • privateKey: 16進文字列形式の秘密キー。脚注1
    • ethValue: 転送するEtherの量(Wei単位で測定)。
    • gasLimit: トランザクションが消費できるガスの最大量。
    • toAddress: Ether転送の受信アドレス。
  • checkFinalityは、トランザクションのファイナリティをチェックするかどうかを指定するブール値です。
  • blocksToWaitは、トランザクションが最終とみなされるまでに待機するブロックの数です。
  • secondsToWaitは、ファイナリティを待機する秒数です。最大待機時間は120秒です。
次の例は、前のトランザクションの正常なレスポンス本文を示しています。txHex値を使用して、Etherscanなどのブロック・エクスプローラ・ツールでブロックに関する情報を検索できます。
{
    "returnCode": "Success",
    "error": "",
    "result": {
        "transactions": [
            {
                "channel": "ch1",
                "chaincode": "bt1",
                "txstatus": "Committed",
                "prepare": {
                    "txid": "f9c65ac93568b3cb878f3f98a5021c443cf138a6411da22d2154ec6f52299de3"
                },
                "commit": {
                    "txid": "b7539349027a0e26eb0522f3066aea721a6bb3bf29d8e821736f73b52357a637"
                },
                "rollback": {}
            },
            {
                "channel": "ch2",
                "chaincode": "bt2",
                "txstatus": "Committed",
                "prepare": {
                    "txid": "b96d046ab11437b7dc6d5d584ef5f33968c11f893e3587ebf07aec0484be38e2"
                },
                "commit": {
                    "txid": "8f3f1fccfead63a2ce6a76be7c2678791ffc8093997a36c94100faa312f95f17"
                },
                "rollback": {}
            }
        ],
        "lrc": {
            "ethResp": {
                "block": 19,
                "txHex": "0xc5741e0da0e16d9b594cac44d5c3cd70d552d013552265f2d06789a01d3fa81d"
            },
            "txstatus": "Committed"
        },
        "globalStatus": "Success",
        "globalTxid": "4b9099f4-9528-82cc-357a-7ed5c703d772",
        "txStartTime": "2022-09-14T10:56:40.018420392Z"
    }
}
次のJSONファイルは、他の2つのチェーンコード・トランザクションを起動するアトミック・トランザクションで署名済Ethereumトランザクションを含める方法を示しています。unSignedReqセクションのかわりに、リクエストにはsignedReqセクションが含まれます。
{
    "transactions": [
        {
            "chaincode": "obcs-example02","args": ["invoke","a","b","1"], 
            "timeout": 0,
            "channel": "default",
            "endorsers":["http://<IP address of endorser>:<port>"]
        }
    ],
    "lrc": {
        "ethReq": {
            "url": "http://<IP address of Ethereum server>:<port>",
            "chainId": 5,
            "signedReq": { 
                "signedTxHex" : "02f8950506841ad2748084476807808401406f409442efb56de8e6a516fff899c9263ef3d21ffd9c298502540be400a4e3456fa90000000000000000000000000000000000000000000000000000000000000001c080a074c985cce323b924e5503592a1301e301c4a3fa4c55234cf60b2782dce81e825a0605b9f61113057e02f614b4d2a52fc5953719aec30743ff4d8b7e2bbf3a206b5"
            },
            "pendingTimeout": 420,
            "finalityParams": {
                "checkFinality": true,
                "blocksToWait": 10,
                "secondsToWait": 20
            }
        }
    },
    "isolationLevel": "serializable",
    "prepareTimeout": 10000,
    "sync": false
}

前述のパラメータ以外では、unsignedReqは署名付きリクエスト本文で、signedTxHexパラメータ(16進形式の署名付きリクエスト文字列)が含まれます。

次の例は、前のトランザクションの正常なレスポンス本文を示しています:
{
    "returnCode": "Success",
    "error": "",
    "result": {
        "transactions": [
            {
                "channel": "default",
                "chaincode": "obcs-example02",
                "txstatus": "Committed",
                "prepare": {
                    "txid": "cb2bb0474bbd1dcb53e8dea68be26f9f3480e60aeeae12977c34fe27a7583f9b"
                },
                "commit": {
                    "txid": "915d61e3c1b9b2c9e1a55aa13b3670cb8c2b1b14ea6426b3cad1ff0bb519532f"
                },
                "rollback": {}
            }
        ],
        "lrc": {
            "ethResp": {
                "block": 8167525,
                "txHex": "0x53254e565aedfdac6d63e40d64c967347661dcc64045a673f948b52c6e48ff4c"
            },
            "txstatus": "Committed"
        },
        "globalStatus": "Success",
        "globalTxid": "3ab9421d-9dfa-40c0-a463-2f9fcb936c42",
        "txStartTime": "2022-12-20T06:09:47.040072324Z"
    }
    }

OBPからEthereumへのNFT転送

Oracle Blockchain Platformにデプロイされたチェーンコードから、EthereumまたはPolygonブロックチェーン・ネットワークにデプロイされたスマート・コントラクトにNFTを送信できます。これは、アトミック・トランザクションの最終リソース・コミット(LRC)トランザクション・リクエストの拡張を使用して行われます。

ブロックチェーン・プラットフォームは、ERC1155およびERC721 GoおよびTypeScriptアプリケーション・ビルダーで生成されたチェーンコードにあるburnNFTメソッドをコールして、Oracle Blockchain Platformチェーンコードから必要なNFTをバーンします。このメソッドは、OBPチェーンコードからNFTをバーンし、tokenIdpricetokenHistoryなどのNFTの必要な情報を返します。Oracle Blockchain Platformは、次のようにします:
  • burnNFTメソッドによって返される情報を収集します
  • 必要なパラメータを抽出します
  • メソッドで必要なパラメータを使用してトランザクション(コントラクト・コール)を作成します
  • スマート・コントラクトに存在するカスタム・ミント・メソッドを呼び出して、EthereumまたはPolygonブロックチェーン・ネットワーク上にデプロイされたスマート・コントラクトでNFTをミントします
  • Oracle Blockchain PlatformのtokenPricetokenHistoryなど、NFTで必要なすべてのカスタム・プロパティを設定します。

NFT転送のリクエスト本文の例:

{
   "transactions": [
       {
           "chaincode": "<chaincodeName>",
           "args": [
              "burnNFT",
              "Org1MSP",
              "user1",
               "1"
           ],
           "timeout": 0,
           "channel": "<channelName>"
       }
   ],
   "lrc": {
       "ethReq": {
           "url": "https://eth-sepolia.g.alchemy.com/v2/6Ho4Tv8uQ1hKCoIjfI_2v_xN6gZJWqLP",
           "chainId": 11155111,
           "unsignedReq": {
               "toAddress": "<contractAddress>",
               "ethValue": "0",
               "methodName": "mintNft",
               "isContractCall": true,
               "abi":"[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"tokenHistory\",\"type\":\"string\"}],\"name\":\"mintNft\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
               "privateKey": "<privateKey>",
               "paramKeys": ["tokenId", "tokenUri", "price", "tokenHistory"],
               "params": {
                   "to": "<toAddress>",
                   "id": "${tokenId}",
                   "tokenUri": "${tokenUri}",
                   "price": "${price}",
                   "tokenHistory": "${tokenHistory}"
               },
               "gasLimit": 2589190,
               "gasTipCap": "250000000",
               "gasFeeCap": "250000000"
           },
           "pendingTimeout": 500,
           "finalityParams": {
               "checkFinality": false,
               "blocksToWait": 3,
               "secondsToWait": 30
           }
       }
   },
   "isolationLevel": "serializable",
   "prepareTimeout": 60000,
   "sync": false
}
説明(前述のパラメータ以外):
  • urlは、プロトコルおよびポート番号を含むEthereumエンドポイントのURLです。
  • chainIdは、EthereumネットワークのネットワークIDです。
  • unsignedReqは、次のパラメータを含む署名なしリクエスト本文です:
    • toAddress: Ether転送の受信アドレス。
    • ethValue: 転送するEtherの量(Wei単位で測定)。
    • methodName: スマート・コントラクトでコールされるメソッド名。この例では、Ethereumブロックチェーン・ネットワークを介してデプロイされたスマート・コントラクトでNFTをミントするスマート・コントラクトに存在するカスタム・ミント・メソッド(mintNft)を使用します。
    • isContractCall: 指定されたリクエストがスマート・コントラクト・コールであることを指定します。
    • abi: アプリケーション・バイナリ・インタフェースを使用すると、スマート・コントラクトは他のアプリケーションやスマート・コントラクトと対話できます。
    • privateKey: 16進文字列形式の秘密キー。
    • paramKeys: 最終的なOracle Blockchain Platformチェーンコード・トランザクションの結果から抽出され、パラメータを介してスマート・コントラクトに送信されるキー。
    • params: スマート・コントラクトでコールされるメソッドに必要なパラメータ。
    • gasLimit: トランザクションが消費できるガスの最大量。
    • gasTipCap: バリデータへのチップとして含める最大料金。
    • gasFeeCap: トランザクションに支払ってもよいと考える最大料金。
  • pendingTimeout: トランザクションが保留状態のままの場合に待機する最大時間(秒)。
  • finalityParamsは、トランザクションが最終とみなされるまでに待機するブロックの数です。
    • checkFinality: トランザクションのファイナリティ・チェックが不要であることを指定します。
    • blocksToWait: トランザクションが最終とみなされるまでに3ブロック待機することを指定します。
    • secondsToWait: トランザクションが最終とみなされるまでに30秒待機することを指定します。

NFT転送のレスポンス本文の例:

{
"returnCode": "Success",
"error": "",
"result": {
     "transactions": [
         {
             "channel": "default",
             "chaincode": "obcs-example02",
             "txstatus": "Committed",
             "prepare": {
                 "txid": "b8dda6fe3bf4013c587c96aa1028e57ce3ad71ea59d5d4612d2795ab88046896"
             },
             "commit": {
                 "txid": "45f7da042ebedac4faebd458692752e1b934f5f3561fc36255fec6d6ee1d7976"
             },
             "rollback": {}
         }
     ],
     "lrc": {
         "ethResp": {
             "block": 8167617,
             "txHex": "0x99c2da536f751491311a6f671a74e14b3614897b78b0e30d24ba65ff3a370a38"
         },
         "txstatus": "Committed"
     },
     "globalStatus": "Success",
     "globalTxid": "734e4f32-d2b1-4111-9168-f89f739a16e4",
     "txStartTime": "2022-12-20T06:33:24.577427607Z"
}
}


脚注の説明

脚注1: atomicTransaction APIを使用してOracle Blockchain Platformトークンをバーンし、メタデータに含まれるOracle Blockchain Platformトークン履歴を使用してEthereumまたはその他のEVMネットワークでそれらを再ミントする場合、Oracle Blockchain Platform burnメソッドから返されたトークン履歴やその他の関連データを、指定されたパラメータを介してEthereum mintメソッドに含めるために、署名なしEthereumリクエストを使用する必要があります。署名なしEthereumリクエストを使用するには、RESTプロキシが指定されたパラメータでリクエストをファイナライズし、Ethereum RPC APIを呼び出す前に署名できるように、atomicTransaction APIペイロードにアカウントの秘密キーを含める必要があります。転送中、キーはTLS (HTTP/S)を使用して保護されますが、Oracle Blockchain PlatformのRESTプロキシ・エンドポイントに到達する前に、コールが他の外部システム(プロキシなど)を介してリダイレクトされる場合は注意してください。コールがOracle Blockchain Platform RESTプロキシに到達すると、秘密キーはEthereumコール・リクエストに署名する目的でのみメモリーで使用され、操作後に破棄されます。Oracle Blockchain PlatformサービスまたはOracle Cloud Infrastructure内のどこにも記録または格納されません。
先頭に戻る