fabric的主要接口是REST API。 REST API允许应用注册用户,查询区块链,并发布交易。 CLI为了开发,同样提供有效API的子集。CLI允许开发人员能够快速测试链码或查询交易状态。
应用程序通过REST API与非验证的 peer 节点,这将需要某种形式的认证,以确保实体有适当的权限进行交互。该应用程序是负责实现合适的身份验证机制和 peer 节点随后将使用客户身份对发出消息签名。
fabric API 设计涵盖的类别如下,虽然当前版本的其中一些实现不完整。[REST API(#62-REST的API)节将说明API当前支持。
REST服务可以(通过配置)在验证和非验证 peer 被启用,但是建议在生产环境中只启用非验证 peer 的REST服务。
func StartOpenchainRESTServer(server *oc.ServerOpenchain, devops *oc.Devops)
这个函数读取core.yaml
peer
处理的配置文件中的rest.address
。rest.address
键定义了 peer 的HTTP REST服务默认监听的地址和端口。
假定REST服务接收来已经认证的终端用户的应用请求。
您可以通过您所选择的任何工具与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总结于以下部分。
使用块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
}
}
}
使用链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=="
}
使用链码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"
}
使用网络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"
}
]
}
使用注册API来管理的证书颁发机构(CA)的最终用户注册。这些API端点用于注册与CA用户,确定指定用户是否已注册,并从本地存储中删除任何目标用户的登录令牌,防止他们执行任何进一步的交易。注册API也用于从系统中检索用户注册和交易证书。
/registrar
端点使用与CA注册用户所需的秘密payload定义如下。注册请求的响应可以是一个成功的注册的确认或包含失败的原因的错误。
message Secret {
string enrollId = 1;
string enrollSecret = 2;
}
enrollId
- 在证书颁发机构的注册IDenrollSecret
- 在证书颁发机构的密码注册请求:
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"
]
}
使用交易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=="
}
CLI包括可用的API的一个子集,使开发人员能够快速测试和调试链码或查询交易状态。CLI由Golang实现和可在多个操作系统上操作。当前可用的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=vp1
和CORE_PEER_ADDRESSAUTODETECT=true
给命令行。
peer
CLI命令在开发和生产环境中都会执行 peer 处理。开发模式会在本地运行单个 peer 节点和本地的链码部署。这使得在链码开修改和调试代码,不需要启动一个完整的网络。在开发模式启动 peer 的一个例子:
./peer peer --peer-chaincodedev
在生产环境中启动peer进程,像下面一样修改上面的命令:
./peer peer
登录的CLI命令会登入一个已经在CA注册的用户。要通过CLI登录,发出以下命令,其中username
是注册用户的注册ID。
./peer login
下面的例子演示了用户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
deploy
CLI命令为链码和接下来的部署包到验证 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"]}'
invoke
CLI命令执行目标来代码中的指定函数。如下:
./peer chaincode invoke -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'
启用安全性时,命令必须修改来通过-u
参数传递用户登录的注册ID。下面是一个例子
./peer chaincode invoke -u jim -n -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'
query
CLI命令在目标链码上触发指定的查询。返回的响应取决于链码实现。下面是一个例子。
./peer chaincode query -l golang -n -c '{"Function": "query", "Args": ["a"]}'
启用安全性时,命令必须修改来通过-u
参数传递用户登录的注册ID。下面是一个例子
./peer chaincode query -u jim -l golang -n -c '{"Function": "query", "Args": ["a