1. 程式人生 > >BlockChain技術系列(六)- 應用程式設計介面

BlockChain技術系列(六)- 應用程式設計介面

fabric的主要介面是REST API。 REST API允許應用註冊使用者,查詢區塊鏈,併發布交易。 CLI為了開發,同樣提供有效API的子集。CLI允許開發人員能夠快速測試鏈碼或查詢交易狀態。

應用程式通過REST API與非驗證的 peer 節點,這將需要某種形式的認證,以確保實體有適當的許可權進行互動。該應用程式是負責實現合適的身份驗證機制和 peer 節點隨後將使用客戶身份對發出訊息簽名。

Reference architecture

fabric API 設計涵蓋的類別如下,雖然當前版本的其中一些實現不完整。[REST API(#62-REST的API)節將說明API當前支援。

  • 身份 - 註冊來獲得或吊銷一張證書
  • Address - 交易的源或目的
  • Transaction - 總賬上的執行單元
  • Chaincode - 總賬上執行的程式
  • Blockchain - 總賬的內容
  • Network - 區塊鏈 peer 網路的資訊
  • Storage - 檔案或文件的外部儲存
  • Event Stream - 區塊鏈上訂閱/釋出事件

6.1 REST Service

REST服務可以(通過配置)在驗證和非驗證 peer 被啟用,但是建議在生產環境中只啟用非驗證 peer 的REST服務。

func StartOpenchainRESTServer(server *oc.ServerOpenchain, devops *oc.Devops)

這個函式讀取core.yamlpeer處理的配置檔案中的rest.addressrest.address鍵定義了 peer 的HTTP REST服務預設監聽的地址和埠。

假定REST服務接收來已經認證的終端使用者的應用請求。

6.2 REST API

您可以通過您所選擇的任何工具與REST API的工作。例如,curl命令列實用程式或一個基於瀏覽器的客戶端,如Firefox的REST客戶端或Chrome Postman。同樣,可以通過[Swagger](http://swagger.io/)直接觸發REST請求。為了獲得REST API Swagger描述,點選[這裡](

https://github.com/hyperledger/fabric/blob/master/core/rest/rest_api.json)。目前可用的API總結於以下部分。

6.2.1 REST Endpoints

  • Block
    • GET /chain/blocks/{block-id}
  • Blockchain
    • GET /chain
  • Chaincode
    • POST /chaincode
  • Network
    • GET /network/peers
  • Registrar
    • POST /registrar
    • GET /registrar/{enrollmentID}
    • DELETE /registrar/{enrollmentID}
    • GET /registrar/{enrollmentID}/ecert
    • GET /registrar/{enrollmentID}/tcert
  • Transactions
    • GET /transactions/{UUID}

6.2.1.1 塊API

  • GET /chain/blocks/{block-id}

使用塊API來從區塊鏈中檢索各個塊的內容。返回的塊資訊結構是在3.2.1.1節中定義

塊檢索請求:

GET host:port/chain/blocks/173

塊檢索響應:

{
    "transactions": [
        {
            "type": 3,
            "chaincodeID": "EgRteWNj",
            "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=",
            "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e",
            "timestamp": {
                "seconds": 1453758316,
                "nanos": 206716775
            },
            "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=",
            "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg=="
        }
    ],
    "stateHash": "7ftCvPeHIpsvSavxUoZM0u7o67MPU81ImOJIO7ZdMoH2mjnAaAAafYy9MIH3HjrWM1/Zla/Q6LsLzIjuYdYdlQ==",
    "previousBlockHash": "lT0InRg4Cvk4cKykWpCRKWDZ9YNYMzuHdUzsaeTeAcH3HdfriLEcTuxrFJ76W4jrWVvTBdI1etxuIV9AO6UF4Q==",
    "nonHashData": {
        "localLedgerCommitTimestamp": {
            "seconds": 1453758316,
            "nanos": 250834782
        }
    }
}

6.2.1.2 區塊鏈API

  • GET /chain

使用鏈API來檢索區塊鏈的當前狀態。返回區塊鏈資訊訊息被定義如下。

message BlockchainInfo {
    uint64 height = 1;
    bytes currentBlockHash = 2;
    bytes previousBlockHash = 3;
}
  • height - 區塊鏈中塊的數量,包括創始區塊

  • currentBlockHash - 當前或最後區塊的雜湊

  • previousBlockHash - 前一區塊的雜湊

區塊鏈檢索請求:

GET host:port/chain

區塊鏈檢索響應:

{
    "height": 174,
    "currentBlockHash": "lIfbDax2NZMU3rG3cDR11OGicPLp1yebIkia33Zte9AnfqvffK6tsHRyKwsw0hZFZkCGIa9wHVkOGyFTcFxM5w==",
    "previousBlockHash": "Vlz6Dv5OSy0OZpJvijrU1cmY2cNS5Ar3xX5DxAi/seaHHRPdssrljDeppDLzGx6ZVyayt8Ru6jO+E68IwMrXLQ=="
}

6.2.1.3 鏈碼API

  • POST /chaincode

使用鏈碼API來部署,呼叫和查詢鏈碼 部署請求需要客戶端提供path引數,執行檔案系統中鏈碼的目錄。部署請求的響應要麼是包含成功的鏈碼部署確認訊息要麼是包含失敗的原因的錯誤。 它還含有所生成的鏈碼的name域在訊息中,這是在隨後的呼叫和查詢交易中使用的已部署鏈碼的唯一標識。

要部署鏈碼,需要提供ChaincodeSpec的payload,在3.1.2.2節中定義。

部署請求:

POST host:port/chaincode

{
  "jsonrpc": "2.0",
  "method": "deploy",
  "params": {
    "type": "GOLANG",
    "chaincodeID":{
        "path":"github.com/hyperledger/fabic/examples/chaincode/go/chaincode_example02"
    },
    "ctorMsg": {
        "function":"init",
        "args":["a", "1000", "b", "2000"]
    }
  },
  "id": "1"  
}

部署響應:

{
    "jsonrpc": "2.0",
    "result": {
        "status": "OK",
        "message": "52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586"
    },
    "id": 1
}

當啟用安全時,修改所需的payload包括傳遞的登入使用者註冊ID的secureContext元素如下:

啟用安全的部署請求:

POST host:port/chaincode

{
  "jsonrpc": "2.0",
  "method": "deploy",
  "params": {
    "type": "GOLANG",
    "chaincodeID":{
        "path":"github.com/hyperledger/fabic/examples/chaincode/go/chaincode_example02"
    },
    "ctorMsg": {
        "function":"init",
        "args":["a", "1000", "b", "2000"]
    },
    "secureContext": "lukas"
  },
  "id": "1"  
}

該呼叫請求要求客戶端提供一個name引數,這是之前從部署交易響應得到的。呼叫請求的響應要麼是包含成功執行的確認訊息,要麼是包含失敗的原因的錯誤。

要呼叫鏈碼,需要提供ChaincodeSpec的payload,在3.1.2.2節中定義

呼叫請求:

POST host:port/chaincode

{
  "jsonrpc": "2.0",
  "method": "invoke",
  "params": {
    "type": "GOLANG",
    "chaincodeID":{
      "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586"
    },
    "ctorMsg": {
        "function":"invoke",
        "args":["a", "b", "100"]
    }
  },
  "id": "3"  
}

呼叫響應:

{
    "jsonrpc": "2.0",
    "result": {
        "status": "OK",
        "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d"
    },
    "id": 3
}

當啟用安全時,修改所需的payload包括傳遞的登入使用者註冊ID的secureContext元素如下:

啟用安全的呼叫請求:

{
  "jsonrpc": "2.0",
  "method": "invoke",
  "params": {
    "type": "GOLANG",
    "chaincodeID":{
      "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586"
    },
    "ctorMsg": {
        "function":"invoke",
        "args":["a", "b", "100"]
    },
    "secureContext": "lukas"
  },
  "id": "3"  
}

查詢請求需要在客戶端提供一個name引數,這是之前在部署交易響應中得到了。查詢請求的響應取決於鏈碼的實現。響應要麼是包含成功執行的確認訊息,要麼是包含失敗的原因的錯誤。在成功執行的情況下,響應將包含鏈碼請求的狀態變數的值

要查詢鏈碼,需要提供ChaincodeSpec的payload,在3.1.2.2節中定義。

查詢請求:

POST host:port/chaincode/

{
  "jsonrpc": "2.0",
  "method": "query",
  "params": {
    "type": "GOLANG",
    "chaincodeID":{
      "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586"
    },
    "ctorMsg": {
        "function":"query",
        "args":["a"]
    }
  },
  "id": "5"  
}

查詢響應:

{
    "jsonrpc": "2.0",
    "result": {
        "status": "OK",
        "message": "-400"
    },
    "id": 5
}

當啟用安全時,修改所需的payload包括傳遞的登入使用者註冊ID的secureContext元素如下:

啟用安全的查詢請求:

{
  "jsonrpc": "2.0",
  "method": "query",
  "params": {
    "type": "GOLANG",
    "chaincodeID":{
      "name":"52b0d803fc395b5e34d8d4a7cd69fb6aa00099b8fabed83504ac1c5d61a425aca5b3ad3bf96643ea4fdaac132c417c37b00f88fa800de7ece387d008a76d3586"
    },
    "ctorMsg": {
        "function":"query",
        "args":["a"]
    },
    "secureContext": "lukas"
  },
  "id": "5"  
}

6.2.1.4 網路API

使用網路API來獲取組成區塊鏈 fabric 的 peer 節點的網路資訊

/network/peers 端點返回的目標 peer 節點的所有現有的網路連線的列表。該列表包括驗證和非驗證 peer。peer 的列表被返回型別PeersMessage是包含PeerEndpoint的陣列,在第[3.1.1](#311-discovery-messages發現的訊息)定義。

message PeersMessage {
    repeated PeerEndpoint peers = 1;
}

網路請求:

GET host:port/network/peers

網路響應:

{
    "peers": [
        {
            "ID": {
                "name": "vp1"
            },
            "address": "172.17.0.4:30303",
            "type": 1,
            "pkiID": "rUA+vX2jVCXev6JsXDNgNBMX03IV9mHRPWo6h6SI0KLMypBJLd+JoGGlqFgi+eq/"
        },
        {
            "ID": {
                "name": "vp3"
            },
            "address": "172.17.0.5:30303",
            "type": 1,
            "pkiID": "OBduaZJ72gmM+B9wp3aErQlofE0ulQfXfTHh377ruJjOpsUn0MyvsJELUTHpAbHI"
        },
        {
            "ID": {
                "name": "vp2"
            },
            "address": "172.17.0.6:30303",
            "type": 1,
            "pkiID": "GhtP0Y+o/XVmRNXGF6pcm9KLNTfCZp+XahTBqVRmaIumJZnBpom4ACayVbg4Q/Eb"
        }
    ]
}

6.2.1.5 註冊API (成員服務)

  • POST /registrar
  • GET /registrar/{enrollmentID}
  • DELETE /registrar/{enrollmentID}
  • GET /registrar/{enrollmentID}/ecert
  • GET /registrar/{enrollmentID}/tcert

使用註冊API來管理的證書頒發機構(CA)的終端使用者註冊。這些API端點用於註冊與CA使用者,確定指定使用者是否已註冊,並從本地儲存中刪除任何目標使用者的登入令牌,防止他們執行任何進一步的交易。註冊API也用於從系統中檢索使用者註冊和交易證書。

/registrar端點使用與CA註冊使用者所需的祕密payload定義如下。註冊請求的響應可以是一個成功的註冊的確認或包含失敗的原因的錯誤。

message Secret {
    string enrollId = 1;
    string enrollSecret = 2;
}
  • enrollId - 在證書頒發機構的註冊ID
  • enrollSecret - 在證書頒發機構的密碼

註冊請求:

POST host:port/registrar

{
  "enrollId": "lukas",
  "enrollSecret": "NPKYL39uKbkj"
}

註冊響應:

{
    "OK": "Login successful for user 'lukas'."
}

GET /registrar/{enrollmentID}端點用於確認一個給定的使用者是否與CA註冊如果是,確認將被反悔。否則,將導致授權錯誤。

註冊驗證請求:

GET host:port/registrar/jim

註冊驗證返回:

{
    "OK": "User jim is already logged in."
}

註冊驗證請求:

GET host:port/registrar/alex

註冊驗證返回:

{
    "Error": "User alex must log in."
}

DELETE /registrar/{enrollmentID} 端點用於刪除一個目標使用者的登入令牌。如果登入令牌成功刪除,確認將被反悔。否則,將導致授權錯誤。此端點不需要payload。

刪除註冊請求:

DELETE host:port/registrar/lukas

刪除註冊返回:

{
    "OK": "Deleted login token and directory for user lukas."
}

GET /registrar/{enrollmentID}/ecert 端點用於檢索從本地儲存給定使用者的登記證書。如果目標使用者已與CA註冊,響應將包括註冊證書的URL-encoded版本。如果目標使用者尚未註冊,將返回一個錯誤。如果客戶希望使用檢索後返回的註冊證書,請記住,它必須是URL-decoded。

註冊證書檢索請求:

GET host:port/registrar/jim/ecert

註冊證書檢索響應:

{
    "OK": "-----BEGIN+CERTIFICATE-----%0AMIIBzTCCAVSgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwNPQkMwHhcNMTYwMTIxMDYzNjEwWhcNMTYwNDIw%0AMDYzNjEwWjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNP%0AQkMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARSLgjGD0omuJKYrJF5ClyYb3sGEGTU%0AH1mombSAOJ6GAOKEULt4L919sbSSChs0AEvTX7UDf4KNaKTrKrqo4khCoboMg1VS%0AXVTTPrJ%2BOxSJTXFZCohVgbhWh6ZZX2tfb7%2BjUDBOMA4GA1UdDwEB%2FwQEAwIHgDAM%0ABgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwDgYG%0AUQMEBQYHAQH%2FBAE0MAoGCCqGSM49BAMDA2cAMGQCMGz2RR0NsJOhxbo0CeVts2C5%0A%2BsAkKQ7v1Llbg78A1pyC5uBmoBvSnv5Dd0w2yOmj7QIwY%2Bn5pkLiwisxWurkHfiD%0AxizmN6vWQ8uhTd3PTdJiEEckjHKiq9pwD%2FGMt%2BWjP7zF%0A-----END+CERTIFICATE-----%0A"
}

/registrar/{enrollmentID}/tcert端點檢索已與證書機關登記給定使用者的交易證書。如果使用者已註冊,確認訊息將包含URL-encoded交易證書的列表被返回。否則,將會導致一個錯誤。交易證書的所需數量由可選的'count'查詢引數指定。返回交易證書的預設數量為1;500是可以與單個請求中檢索證書的最大數量。如果客戶端希望使用取回後的交易證書,請記住,他們必須是URL-decoded。

交易證書檢索請求:

GET host:port/registrar/jim/tcert

交易證書檢索響應:

{
    "OK": [
        "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQfwJORRED9RAsmSl%2FEowq1STBb%0A%2FoFteymZ96RUr%2BsKmF9PNrrUNvFZFhvukxZZjqhEcGiQqFyRf%2FBnVN%2BbtRzMo38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwSRWQFmErr0SmQO9AFP4GJYzQ%0APQMmcsCjKiJf%2Bw1df%2FLnXunCsCUlf%2FalIUaeSrT7MAoGCCqGSM49BAMDA0gAMEUC%0AIQC%2FnE71FBJd0hwNTLXWmlCJff4Yi0J%2BnDi%2BYnujp%2Fn9nQIgYWg0m0QFzddyJ0%2FF%0AKzIZEJlKgZTt8ZTlGg3BBrgl7qY%3D%0A-----END+CERTIFICATE-----%0A"
    ]
}

交易證書檢索請求:

GET host:port/registrar/jim/tcert?count=5

交易證書檢索響應:

{
    "OK": [
        "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A",
        "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A",
        "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A",
        "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A",
        "-----BEGIN+CERTIFICATE-----%0AMIIBwDCCAWagAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMzExMjEwMTI2WhcNMTYwNjA5%0AMjEwMTI2WjApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwNq%0AaW0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwJxVezgDcTAgj2LtTKVm65qft%0AhRTYnIOQhhOx%2B%2B2NRu5r3Kn%2FXTf1php3NXOFY8ZQbY%2FQbFAwn%2FB0O68wlHiro38w%0AfTAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH%2FBAIwADANBgNVHQ4EBgQEAQIDBDAP%0ABgNVHSMECDAGgAQBAgMEMD0GBioDBAUGBwEB%2FwQwRVPMSKVcHsk4aGHxBWc8PGKj%0AqtTVTtuXnN45BynIx6lP6urpqkSuILgB1YOdRNefMAoGCCqGSM49BAMDA0gAMEUC%0AIAIjESYDp%2FXePKANGpsY3Tu%2F4A2IfeczbC3uB%2BpziltWAiEA6Stp%2FX4DmbJGgZe8%0APMNBgRKeoU6UbgTmed0ZEALLZP8%3D%0A-----END+CERTIFICATE-----%0A"
    ]
}

6.2.1.6 交易API

  • GET /transactions/{UUID}

使用交易API來從區塊鏈中檢索匹配UUID的單個交易。返回的交易訊息在3.1.2.1小節定義

交易檢索請求:

GET host:port/transactions/f5978e82-6d8c-47d1-adec-f18b794f570e

交易檢索響應:

{
    "type": 3,
    "chaincodeID": "EgRteWNj",
    "payload": "Ch4IARIGEgRteWNjGhIKBmludm9rZRIBYRIBYhICMTA=",
    "uuid": "f5978e82-6d8c-47d1-adec-f18b794f570e",
    "timestamp": {
        "seconds": 1453758316,
        "nanos": 206716775
    },
    "cert": "MIIB/zCCAYWgAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYwMTI1MjE0MTE3WhcNMTYwNDI0MjE0MTE3WjArMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQ4wDAYDVQQDEwVsdWthczB2MBAGByqGSM49AgEGBSuBBAAiA2IABC/BBkt8izf6Ew8UDd62EdWFikJhyCPY5VO9Wxq9JVzt3D6nubx2jO5JdfWt49q8V1Aythia50MZEDpmKhtM6z7LHOU1RxuxdjcYDOvkNJo6pX144U4N1J8/D3A+97qZpKN/MH0wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDA9BgYqAwQFBgcBAf8EMABNbPHZ0e/2EToi0H8mkouuUDwurgBYuUB+vZfeMewBre3wXG0irzMtfwHlfECRDDAKBggqhkjOPQQDAwNoADBlAjAoote5zYFv91lHzpbEwTfJL/+r+CG7oMVFUFuoSlvBSCObK2bDIbNkW4VQ+ZC9GTsCMQC5GCgy2oZdHw/x7XYzG2BiqmRkLRTiCS7vYCVJXLivU65P984HopxW0cEqeFM9co0=",
    "signature": "MGUCMCIJaCT3YRsjXt4TzwfmD9hg9pxYnV13kWgf7e1hAW5Nar//05kFtpVlq83X+YtcmAIxAK0IQlCgS6nqQzZEGCLd9r7cg1AkQOT/RgoWB8zcaVjh3bCmgYHsoPAPgMsi3TJktg=="
}

6.3 CLI

CLI包括可用的API的一個子集,使開發人員能夠快速測試和除錯鏈碼或查詢交易狀態。CLI由Golang實現和可在多個作業系統上操作。當前可用的CLI命令歸納在下面的部分:

6.3.1 CLI命令

To see what CLI commands are currently available in the implementation, execute the following:

要檢視當前可用的CLI命令,執行如下命令

cd $GOPATH/src/github.com/hyperledger/fabic/peer
./peer

你可以獲得和下面類似的響應:

    Usage:
      peer [command]

    Available Commands:
      peer        Run the peer.
      status      Status of the peer.
      stop        Stop the peer.
      login       Login user on CLI.
      vm          VM functionality on the fabric.
      chaincode   chaincode specific commands.
      help        Help about any command

    Flags:
      -h, --help[=false]: help


    Use "peer [command] --help" for more information about a command.

Some of the available command line arguments for the peer command are listed below:

  • -c - 建構函式: 用來為部署觸發初始化鏈碼狀態的函式

  • -l - 語言: 指定鏈碼的實現語言,目前只支援Golang

  • -n - 名字: 部署交易返回的鏈碼的標識。在後續的呼叫和查詢交易中必須使用

  • -p - 路徑: 鏈碼在本地檔案系統中的標識。在部署交易時必須提供。

  • -u - 使用者名稱: 呼叫交易的登入的使用者的註冊ID

上述所有命令並非完全在當前版本中實現。如下所述全面支援的命令是有助於鏈碼的開發和除錯的。

所有 peer 節點的設定都被列在core.yaml這個peer處理的配置檔案中,可能通過命令列的環境變數而被修改。如,設定peer.id或 peer.ddressAutoDetect,只需要傳遞CORE_PEER_ID=vp1CORE_PEER_ADDRESSAUTODETECT=true給命令列。

6.3.1.1 peer

peerCLI命令在開發和生產環境中都會執行 peer 處理。開發模式會在本地執行單個 peer 節點和本地的鏈碼部署。這使得在鏈碼開修改和除錯程式碼,不需要啟動一個完整的網路。在開發模式啟動 peer 的一個例子:

./peer peer --peer-chaincodedev

在生產環境中啟動peer程序,像下面一樣修改上面的命令:

./peer peer

6.3.1.2 登入

登入的CLI命令會登入一個已經在CA註冊的使用者。要通過CLI登入,發出以下命令,其中username是註冊使用者的註冊ID。

./peer login <username>

下面的例子演示了使用者jim登入過程。

./peer login jim

該命令會提示輸入密碼,密碼必須為此使用者使用證書頒發機構註冊登記的密碼相匹配。如果輸入的密碼不正確的密碼匹配,將導致一個錯誤。

22:21:31.246 [main] login -> INFO 001 CLI client login...
22:21:31.247 [main] login -> INFO 002 Local data store for client loginToken: /var/hyperledger/production/client/
Enter password for user 'jim': ************
22:21:40.183 [main] login -> INFO 003 Logging in user 'jim' on CLI interface...
22:21:40.623 [main] login -> INFO 004 Storing login token for user 'jim'.
22:21:40.624 [main] login -> INFO 005 Login successful for user 'jim'.

您也可以與-p引數來提供使用者的密碼。下面是一個例子。

./peer login jim -p 123456

6.3.1.3 鏈碼部署

deployCLI命令為鏈碼和接下來的部署包到驗證 peer 建立 docker 映象。如下面的例子。

./peer chaincode deploy -p github.com/hyperledger/fabric/example/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}'

啟用安全性時,命令必須修改來通過-u引數傳遞使用者登入的註冊ID。下面是一個例子

./peer chaincode deploy -u jim -p github.com/hyperledger/fabric/example/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}'

6.3.1.4 鏈碼呼叫

invokeCLI命令執行目標來程式碼中的指定函式。如下:

./peer chaincode invoke -n <name_value_returned_from_deploy_command> -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'

啟用安全性時,命令必須修改來通過-u引數傳遞使用者登入的註冊ID。下面是一個例子

./peer chaincode invoke -u jim -n <name_value_returned_from_deploy_command> -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'

6.3.1.5 鏈碼查詢

queryCLI命令在目標鏈碼上觸發指定的查詢。返回的響應取決於鏈碼實現。下面是一個例子。

./peer chaincode query -l golang -n <name_value_returned_from_deploy_command> -c '{"Function": "query", "Args": ["a"]}'

啟用安全性時,命令必須修改來通過-u引數傳遞使用者登入的註冊ID。下面是一個例子

./peer chaincode query -u jim -l golang -n <name_value_returned_from_deploy_command> -c '{"Function": "query", "Args": ["a