超级账本1.2版本--官网翻译(couchdb_tutorial) part(2)

… _cdb-install-instantiate:

Install and instantiate the Chaincode-安装实例化链码

Client applications interact with the blockchain ledger through chaincode. As
such we need to install the chaincode on every peer that will
execute and endorse our transactions and and instantiate the chaincode on the
channel. In the previous section, we demonstrated how to package the chaincode
so they should be ready for deployment.

客户端应用程序通过链代码与区块链账本交互。 因此,我们需要在每个将执行和背书我们的事务的peer节点上安装链码,并在通道上实例化链代码。 在上一节中,我们演示了如何打包链码,以便它们可以为部署做好准备。

Chaincode is installed onto a peer and then instantiated onto the channel using

  1. Use the peer chaincode install <http://hyperledger-fabric.readthedocs.io/en/master/commands/peerchaincode.html?%20chaincode%20instantiate#peer-chaincode-install>__ command to install the Marbles chaincode on a peer.

使用peer chaincode install <http://hyperledger-fabric.readthedocs.io/en/master/commands/peerchaincode.html?%20chaincode%20instantiate#peer-chaincode-install>__命令在peer节点上安装Marbles链码。

:guilabel:Try it yourself

Assuming you have started the BYFN network, navigate into the CLI
container using the command:

… code:: bash

  docker exec -it cli bash

Use the following command to install the Marbles chaincode from the git
repository onto a peer in your BYFN network. The CLI container defaults
to using peer0 of org1:
使用以下命令将Marnles链码从git存储库安装到BYFN网络中的peer节点。 CLI容器默认使用org1的peer0:

… code:: bash

  peer chaincode install -n marbles -v 1.0 -p github.com/chaincode/marbles02/go
  1. Issue the peer chaincode instantiate <http://hyperledger-fabric.readthedocs.io/en/master/commands/peerchaincode.html?%20chaincode%20instantiate#peer-chaincode-instantiate>__ command to instantiate the
    chaincode on a channel.
    通过peer chaincode instantiate <http://hyperledger-fabric.readthedocs.io/en/master/commands/peerchaincode.html?%20chaincode%20instantiate#peer-chaincode-instantiate>__命令来实例化通道上的链码。

:guilabel:Try it yourself

To instantiate the Marbles sample on the BYFN channel mychannel
run the following command:

… code:: bash

export CHANNEL_NAME=mychannel
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -v 1.0 -c '{"Args":["init"]}' -P "OR ('Org0MSP.peer','Org1MSP.peer')"

Verify index was deployed–验证索引已部署

Indexes will be deployed to each peer’s CouchDB state database once the
chaincode is both installed on the peer and instantiated on the channel. You
can verify that the CouchDB index was created successfully by examining the
peer log in the Docker container.

一旦链码安装在peer上并在通道上实例化,索引将被部署到每个peer的CouchDB状态数据库。 您可以通过检查Docker容器中的peer日志来验证是否已成功创建CouchDB索引。

:guilabel:Try it yourself

To view the logs in the peer docker container,
open a new Terminal window and run the following command to grep for message
confirmation that the index was created.



docker logs peer0.org1.example.com 2>&1 | grep “CouchDB index”

You should see a result that looks like the following:


[couchdb] CreateIndex -> INFO 0be Created CouchDB index [indexOwner] in state database [mychannel_marbles] using design document [_design/indexOwnerDoc]

… note:: If Marbles was not installed on the BYFN peer peer0.org1.example.com,
you may need to replace it with the name of a different peer where
Marbles was installed.
如果在BYFN 的peer peer0.org1.example.com上没有安装Marbles,您可能需要将其替换为安装了Marbles的其他peer节点的名称。

… _cdb-query:

Query the CouchDB State Database-查询CouchDB状态数据库

Now that the index has been defined in the JSON file and deployed alongside
the chaincode, chaincode functions can execute JSON queries against the CouchDB
state database, and thereby peer commands can invoke the chaincode functions.

Specifying an index name on a query is optional. If not specified, and an index
already exists for the fields being queried, the existing index will be
automatically used.

在查询上指定索引名称是可选的。 如果未指定,并且已查询的字段已存在索引,则将自动使用现有索引。

… tip:: It is a good practice to explicitly include an index name on a
query using the use_index keyword. Without it, CouchDB may pick a
less optimal index. Also CouchDB may not use an index at all and you
may not realize it, at the low volumes during testing. Only upon
higher volumes you may realize slow performance because CouchDB is not
using an index and you assumed it was.
使用use_index关键字在查询中显式包含索引名称是一个好习惯。 没有它,CouchDB可能会选择一个不太理想的索引。 此外,CouchDB可能根本不使用索引,您可能没有意识到它,当测试低容量的时候。 只有在较高的容量的时候,您可能会发现性能较慢,因为CouchDB没有使用索引而您认为它使用了。

Build the query in chaincode-在链码中创建查询

You can perform complex rich queries against the chaincode data values using
the CouchDB JSON query language within chaincode. As we explored above, the
marbles02 sample chaincode <https://github.com/hyperledger/fabric-samples/blob/master/chaincode/marbles02/go/marbles_chaincode.go>__
includes an index and rich queries are defined in the functions - queryMarbles
and queryMarblesByOwner:
您可以通过链码中的CouchDB JSON查询语言对链码数据值执行复杂的富查询。 正如我们上面所探讨的那样,marbles02示例链码<https://github.com/hyperledger/fabric samples / blob / master / chaincode / marbles02 / go / marbles_cha ncode.go>__包含索引,并且富查询定义于 函数 - queryMarblesqueryMarblesByOwner

  • queryMarbles

    Example of an ad hoc rich query. This is a query
    where a (selector) string can be passed into the function. This query
    would be useful to client applications that need to dynamically build
    their own selectors at runtime. For more information on selectors refer
    to CouchDB selector syntax <http://docs.couchdb.org/en/latest/api/database/find.html#find-selectors>__.

ad hoc富查询的示例。 这是一个查询,其中(选择器)字符串可以传递给函数。 此查询对于需要在运行时动态构建自己的选择器的客户端应用程序非常有用。 有关选择器的更多信息,请参阅CouchDB选择器语法http://docs.couchdb.org/en/latest/api/database/find.html#find-selectors`__。

  • queryMarblesByOwner

    Example of a parameterized query where the
    query logic is baked into the chaincode. In this case the function accepts
    a single argument, the marble owner. It then queries the state database for
    JSON documents matching the docType of “marble” and the owner id using the
    JSON query syntax.
    参数化查询的示例,其中查询逻辑被复制到链代码中。 在这种情况下,函数接受单个参数,即marble的所有者。 然后,它使用JSON查询语法在状态数据库中查询与“marble”的docType和所有者id匹配的JSON文档。

Run the query using the peer command-使用peer命令执行查询

In absence of a client application to test rich queries defined in chaincode,
peer commands can be used. Peer commands run from the command line inside the
docker container. We will customize the peer chaincode query <http://hyperledger-fabric.readthedocs.io/en/master/commands/peerchaincode.html?%20chaincode%20query#peer-chaincode-query>__
command to use the Marbles index indexOwner and query for all marbles owned
by “tom” using the queryMarbles function.

如果没有客户端应用程序来测试链码中定义的富查询,则可以使用peer命令。 peer命令从docker容器内的命令行运行。 我们将自定义peer chaincode query <http:// hyperledger fabric.readthedocs.io/en/master/commands/peerchaincode.html?%20chaincode%20query#peer-chaincode-query>__命令来使用Marbles索引 `indexOwner并使用queryMarbles``函数查询“tom”拥有的marbles。

:guilabel:Try it yourself

Before querying the database, we should add some data. Run the following
command in the peer container to create a marble owned by “tom”:
在查询数据库之前,我们应该添加一些数据。 在对等容器中运行以下命令以创建由“tom”拥有的marble:

… code:: bash

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c ‘{“Args”:[“initMarble”,“marble1”,“blue”,“35”,“tom”]}’

After an index has been deployed during chaincode instantiation, it will
automatically be utilized by chaincode queries. CouchDB can determine which
index to use based on the fields being queried. If an index exists for the
query criteria it will be used. However the recommended approach is to
specify the use_index keyword on the query. The peer command below is an
example of how to specify the index explicitly in the selector syntax by
including the use_index keyword:

在链码实例化期间部署索引之后,链码查询将自动使用它。 CouchDB可以根据要查询的字段确定要使用的索引。 如果查询条件存在索引,则将使用该索引。 但是,建议的方法是在查询中指定use_index关键字。 下面的peer命令是一个如何通过包含use_index关键字在选择器语法中显式指定索引的示例:

… code:: bash

// Rich Query with index name explicitly specified:
peer chaincode query -C $CHANNEL_NAME -n marbles -c ‘{“Args”:[“queryMarbles”, “{“selector”:{“docType”:“marble”,“owner”:“tom”}, “use_index”:[”_design/indexOwnerDoc", “indexOwner”]}"]}’

Delving into the query command above, there are three arguments of interest:

  • queryMarbles
    Name of the function in the Marbles chaincode. Notice a shim <https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim>__
    shim.ChaincodeStubInterface is used to access and modify the ledger. The
    getQueryResultForQueryString() passes the queryString to the shim API getQueryResult().

Marbles链码中函数的名称。 注意一下shim <https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim>__ shim.ChaincodeStubInterface用于访问和修改账本。该 getQueryResultForQueryString()将queryString传递给shim APIgetQueryResult()

… code:: bash

func (t *SimpleChaincode) queryMarbles(stub shim.ChaincodeStubInterface, args []string) pb.Response {

  //   0
  // "queryString"
   if len(args) < 1 {
	   return shim.Error("Incorrect number of arguments. Expecting 1")

   queryString := args[0]

   queryResults, err := getQueryResultForQueryString(stub, queryString)
   if err != nil {
	 return shim.Error(err.Error())
   return shim.Success(queryResults)


  • {"selector":{"docType":"marble","owner":"tom"}
    This is an example of an ad hoc selector string which finds all documents
    of type marble where the owner attribute has a value of tom.
    这是一个** ad hoc selector **字符串的示例,它查找所有类型为marble的文档,其中owner属性的值为tom

  • "use_index":["_design/indexOwnerDoc", "indexOwner"]
    Specifies both the design doc name indexOwnerDoc and index name
    indexOwner. In this example the selector query explicitly includes the
    index name, specified by using the use_index keyword. Recalling the
    index definition above :ref:CreateAnIndex, it contains a design doc,
    "ddoc":"indexOwnerDoc". With CouchDB, if you plan to explicitly include
    the index name on the query, then the index definition must include the
    ddoc value, so it can be referenced with the use_index keyword.

指定设计文档名称indexOwnerDoc和索引名称indexOwner。 在此示例中,选择器查询显式包含使用use_index关键字指定的索引名称。 回顾上面的索引定义:ref:CreateAnIndex,它包含一个设计文档,“ddoc”:“indexOwnerDoc”。 使用CouchDB,如果您计划在查询中明确包含索引名称,那么索引定义必须包含ddoc值,因此可以使用use_index关键字引用它。

The query runs successfully and the index is leveraged with the following results:

… code:: json

Query Result: [{“Key”:“marble1”, “Record”:{“color”:“blue”,“docType”:“marble”,“name”:“marble1”,“owner”:“tom”,“size”:35}}]

… _cdb-update-index:

Update an Index-更新索引

It may be necessary to update an index over time. The same index may exist in
subsequent versions of the chaincode that gets installed. In order for an index
to be updated, the original index definition must have included the design
document ddoc attribute and an index name. To update an index definition,
use the same index name but alter the index definition. Simply edit the index
JSON file and add or remove fields from the index. Fabric only supports the
index type JSON, changing the index type is not supported. The updated
index definition gets redeployed to the peer’s state database when the chaincode
is installed and instantiated. Changes to the index name or ddoc attributes
will result in a new index being created and the original index remains
unchanged in CouchDB until it is removed.
随着时间推移可能需要更新索引。 安装的链码的后续版本中可能存在相同的索引。 为了更新索引,原始索引定义必须包含设计文档ddoc属性和索引名称。 要更新索引定义,请使用相同的索引名称,但更改索引定义。 只需编辑索引JSON文件,然后在索引中添加或删除字段。 Fabric仅支持索引类型JSON,不支持更改索引类型。 在安装和实例化链代码时,更新的索引定义将重新部署到对等方的状态数据库。 对索引名称或ddoc属性的更改将导致创建新索引,并且原始索引在CouchDB中保持不变,直到将其删除。

… note:: If the state database has a significant volume of data, it will take
some time for the index to be re-built, during which time chaincode
invokes that issue queries may fail or timeout.

Iterating on your index definition - 迭代索引定义

If you have access to your peer’s CouchDB state database in a development
environment, you can iteratively test various indexes in support of
your chaincode queries. Any changes to chaincode though would require
redeployment. Use the CouchDB Fauxton interface <http://docs.couchdb.org/en/latest/fauxton/index.html>__ or a command
line curl utility to create and update indexes.

如果您可以在开发环境中访问peer的CouchDB状态数据库,则可以迭代测试各种索引以支持您的链码查询。 但是,对链码的任何更改都需要重新部署。 使用CouchDB Fauxton接口 http://docs.couchdb.org/en/latest/fauxton/index.html`__或命令行curl实用程序来创建和更新索引。

… note:: The Fauxton interface is a web UI for the creation, update, and
deployment of indexes to CouchDB. If you want to try out this
interface, there is an example of the format of the Fauxton version
of the index in Marbles sample. If you have deployed the BYFN network
with CouchDB, the Fauxton interface can be loaded by opening a browser
and navigating to http://localhost:5984/_utils.
Fauxton接口是用于创建,更新和部署CouchDB索引的Web UI。 如果你想试试这个界面,有一个Marbles样本中索引的Fauxton版本格式的例子。 如果已使用CouchDB部署BYFN网络,则可以通过打开浏览器并导航到http:// localhost:5984 / _utils来加载Fauxton接口。

Alternatively, if you prefer not use the Fauxton UI, the following is an example
of a curl command which can be used to create the index on the database
或者,如果您不想使用Fauxton UI,则以下是curl命令的示例,该命令可用于在数据库“mychannel_marbles”上创建索引:
// Index for docType, owner.
// Example curl command line to define index in the CouchDB channel_chaincode database

… code:: bash

curl -i -X POST -H “Content-Type: application/json” -d
“type”:“json”}” http://hostname:port/mychannel_marbles/_index

… note:: If you are using BYFN configured with CouchDB, replace hostname:port
with localhost:5984.

… _cdb-delete-index:

Delete an Index-删除索引

Index deletion is not managed by Fabric tooling. If you need to delete an index,
manually issue a curl command against the database or delete it using the
Fauxton interface.
索引删除不受Fabric工具管理。 如果需要删除索引,请手动向数据库发出curl命令或使用Fauxton接口将其删除。

The format of the curl command to delete an index would be:

… code:: bash

curl -X DELETE http://localhost:5984/{database_name}/_index/{design_doc}/json/{index_name} -H “accept: /” -H “Host: localhost:5984”

To delete the index used in this tutorial, the curl command would be:

… code:: bash

curl -X DELETE http://localhost:5984/mychannel_marbles/_index/indexOwnerDoc/json/indexOwner -H “accept: /” -H “Host: localhost:5984”

… Licensed under Creative Commons Attribution 4.0 International License