Enable COUCHDB as state Database in Hyperledger Fabric

Source: Internet
Author: User
Tags curl docker hub docker run couchdb hyperledger fabric

Looking back at one of my previous blogs, in Fabric 1.0, we have 3 types of data stores, one based on the file system Blockchain data, which is like Bitcoin, and bitcoin is also stored in file form. The blockchain in Fabric1.0 stores the transaction order read-write set. What exactly is read and write set? Write what? In fact, our state Database, also known as the World State, stores the business data we operate in Chaincode in the form of key-value pairs. There is also a database of historical data and a blockchain index.

Blockchain is a file system, which currently does not support changes, historical data and the index of the blockchain is leveldb, and this cannot be changed. For the state database, because of the business-related, it provides a replacement database, currently supports the default LEVELDB and user-selectable couchdb. Here to say 2 points, one is in 0.6 of the time its practical rockdb, but due to license considerations, so in 1.0 changed to Leveldb. In addition, COUCHDB is not necessarily the best, many people also consider MongoDB or MySQL, but because of the development of the fabric there is limited resources, so in 1.0 will not do, in the future may be achieved.

COUCHDB Installation

Let's talk about this couchdb.

COUCHDB is a key-value database for the full local restful API, which means that we do not need any clients and only need to operate the database via HTTP requests. LEVELDB is peer's local database, then it must be a one-to-peer relationship, then COUCHDB is a network database, what should be the relationship with peer? In a production environment, we deploy nodes for each organization, and in order to be highly available, multiple peers may be deployed in an organization. We also deploy multiple couchdb in an organization, one for each peer couchdb.

Hyperledger also released the COUCHDB image on the Docker hub, and in order to delve into the integration of couchdb and fabric, we used the officially released Couchdb.

Docker Pull Klaemo/couchdb

"Note that if we are Docker pull couchdb, we can only get the 1.6 version of Couchdb, and to get the latest version 2.0, you need to use this image." 】

The official COUCHDB image can be obtained. COUCHDB you need to specify a local folder to map to a COUCHDB data store folder when booting, so we can create a folder in the current user's directory to hold the data.

mkdir Couchdb

Once the download is complete, we only need to execute the following command to enable an instance of COUCHDB:

5984:5984 -D--name my-couchdb-e couchdb_user=admin-e couchdb_password=password-v ~/couchdb:/opt/ Couchdb/data Klaemo/couchdb
启动后我们打开浏览器,访问Linux的IP的5984端口的URL,比如我的Linux是192.168.100.129,那么URL是:
Http://192.168.100.129:5984/_utils
This time we can see the COUCHDB Web management interface. Enter the user name Admin password password can enter.
Now it's an empty database, and we'll see what happens when we combine couchdb and peer.
Configuring the Couchdb+fabric Environment
First delete the Couchdb container you just created:
RM -F MY-COUCHDB
First we are 4 peer+1orderer mode, so we first create 4 COUCHDB databases:
CD ~mkdircouchdb0mkdirCOUCHDB1mkdirCOUCHDB2mkdirCOUCHDB3 Docker Run-P5984:5984-D--name couchdb0-e couchdb_user=admin-e couchdb_password=password-v ~/couchdb0:/opt/couchdb/data klaemo/Couchdb Docker Run-P6984:5984-D--name couchdb1-e couchdb_user=admin-e couchdb_password=password-v ~/couchdb1:/opt/couchdb/data klaemo/Couchdb Docker Run-P7984:5984-D--name couchdb2-e couchdb_user=admin-e couchdb_password=password-v ~/couchdb2:/opt/couchdb/data klaemo/Couchdb Docker Run-P8984:5984-D--name couchdb3-e couchdb_user=admin-e couchdb_password=password-v ~/couchdb3:/opt/couchdb/data klaemo/couchdb

Then we need to start the fabric. The fabric preparation environment can be found in our blog: http://www.cnblogs.com/studyzy/p/6973334.html

The official has provided multiple docker-compose files, if we are using the./network_setup.sh up command, then the Docker-compose-cli.yaml file is enabled. If you want to enable COUCHDB peer based on this Yaml file, open the file and edit the peer node in the following form:

Peer0.org1.example.com:
Container_name:peer0.org1.example.com
Environment:
-Core_ledger_state_statedatabase=couchdb
-core_ledger_state_couchdbconfig_couchdbaddress=192.168.100.129:5984
-Core_ledger_state_couchdbconfig_username=admin
-Core_ledger_state_couchdbconfig_password=password
Extends
File:base/docker-compose-base.yaml
Service:peer0.org1.example.com

The 192.168.100.129:5984 here is the IP address and IP of Linux after I mapped couchdb. The user name and password are then set. After changing the configuration of the 4 peers, save, we try to enable fabric:

./network_setup. SH up

After the fabric starts and runs the Chaincode test, we refresh http://192.168.100.129:5984/_utils, we can see the database created with the channel name, and several more are the system databases.

Click into the MyChannel database and we can see the contents of the data. Click "Mango Query" to write a query, the default provided query can click the Run Query button to query all data results:
Direct query for COUCHDB
Next we use the Linux curl to query the COUCHDB database.
For example, we want to see what data is in the MyChannel database:
Curl Http://192.168.100.129:5984/mychannel/_all_docs
You can see that I ran some chaincode after the state database results:

{"Total_rows": 7, "offset": 0, "Rows": [
{"id": "devincc\u0000a", "Key": "devincc\u0000a", "value": {"Rev": "2-a979bf6c2716ecae6d106999f833a59c"}},
{"id": "devincc\u0000b", "Key": "devincc\u0000b", "value": {"Rev": "2-ad1c549305fd277097180405f96bdcd8"}},
{"id": "LSCC\U0000DEVINCC", "Key": "LSCC\U0000DEVINCC", "value": {"Rev": "1-05d2cd0b344c4dd8a8d1a3ffd7332544"}},
{"id": "LSCC\U0000MYCC", "Key": "LSCC\U0000MYCC", "value": {"Rev": "1-2cba0344b1610b9d9254bbafbda5e9b1"}},
{"id": "mycc\u0000a", "Key": "mycc\u0000a", "value": {"Rev": "2-588a45b289359afa9dc6e5e7866eaf97"}},
{"id": "mycc\u0000b", "Key": "mycc\u0000b", "value": {"Rev": "2-54e6639a858b0f91298c9a354484513a"}},
{"id": "statedb_savepoint", "Key": "Statedb_savepoint", "value": {"Rev": "10-6ccde2a55c71d7d6a70d9333d119fc8e"}}
]}

If we want to query one of the data, we just need to use/channelid/id to query, such as query: Statedb_savepoint

Curl http://192.168.100.129:5984/mychannel/statedb_savepoint

Results returned:
{"_id": "Statedb_savepoint", "_rev": "10-6ccde2a55c71d7d6a70d9333d119fc8e", "Blocknum": 4, "Txnum": 0, "updateseq": "19 -g1aaaaezejzlywbg4mhgtmhgzcvpy09jdcjlz8gvlskbcjmlmitj____ Pyurayecjaugmwqpvsocs40dse08wa0jljujidx1eo3kywgsda1acqhspif1cydq9mclsujvdwci7j4h8x5a1ahdx5kfai6sywk "}

The trouble is that the business data is the ID of the format "chaincodename\u0000 data", and if we want to query through this ID, then we can't find it at all!

Curl http://192.168.100.129:5984/mychannel/mycc\u0000a
{"Error": "Not_found", "Reason": "Missing"}

The correct approach is to replace \u0000 with%00, which means that our query should be:

Curl http://192.168.100.129:5984/mychannel/mycc%00a

Return the result correctly:
{"_id": "mycc\u0000a", "_rev": "2-588a45b289359afa9dc6e5e7866eaf97", "Chaincodeid": "MYCC", "Version": "4:0", "_ Attachments ": {" valuebytes ": {" Content_Type ":" Application/octet-stream "," Revpos ": 2," Digest ":" md5-hhoyxsseupdxrmq56hm7kg== "," Length ": 2," Stub ": True}}}

Issues that you may encounter with fabric
Although the blockchain is a database that can only be inserted and queried, but our business data is stored in the state database, if we directly modify the COUCHDB data, then the next query and transaction is directly based on the modified COUCHDB, does not examine the records in the blockchain, so it is theoretically possible to modify the business data by directly changing the COUCHDB.
Let's take the official marble as an example and see what happens when we change couchdb.
The following are the steps:
1.install,instantiate and initializing data:
Peer ChaincodeInstall-N marbles02-v1.0-P github.com/hyperledger/fabric/examples/chaincode/go/Marbles02peer Chaincode Instantiate-O orderer.example.com:7050--tls $CORE _peer_tls_enabled--cafile/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ Ordererorganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem-c Mychannel-n Marbles02-v1.0-P Github.com/hyperledger/fabric/examples/chaincode/go/marbles02-c'{"Args": ["Init"]}'-P"OR (' Org1msp.member ', ' org2msp.member ')"Peer Chaincode Invoke-O orderer.example.com:7050--tls $CORE _peer_tls_enabled--cafile/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ Ordererorganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem-c Mychannel-n Marbles02-c'{"Args": ["initmarble", "Marble2", "Red", "$", "Tom"]}'Peer Chaincode Query-C Mychannel-n marbles02-c'{"Args": ["readmarble", "Marble2"]}'

We can see that the data in COUCHDB is queried directly through Curl:

Curl Http://192.168.100.129:5984/mychannel/marbles02%00marble2

{"_id": "Marbles02\u0000marble2", "_rev": "1-a1844f47b9ed94294b430c9a9a6f543b", "Chaincodeid": "Marbles02", "data": { "DocType": "Marble", "name": "Marble2", "Color": "Red", "size": "Owner": "Tom"}, "version": "6:0"}

If we want to change the data, change the color to green and size to 10, then we can run:

Curl-x PUT http://192.168.100.129:5984/mychannel/marbles02%00marble2-d ' {"_id": "Marbles02\ U0000marble2 "," _rev ":" 1-a1844f47b9ed94294b430c9a9a6f543b "," Chaincodeid ":" Marbles02 "," data ": {" DocType ":" Marble " , "name": "Marble2", "Color": "Green", "size": Ten, "owner": "Tom"}, "version": "6:0"} '

The system returns the result:
{"OK": true, "id": "Marbles02\u0000marble2", "Rev": "2-6ffc6652cfc707f8352a5f06c3ce1ce6"}

We ran this command in 4 couchdb and changed the data for all 4 databases.
Next we'll look through the chaincode to see what happens.
' {"Args": ["readmarble", "Marble2"]} '
return Result:
Query Result: {"color": "Green", "docType": "Marble", "name": "Marble2", "owner": "Tom", "Size": 10}
You can see that the data has become a new value, so what happens next when you run the other transaction? Let's try a transfer operation:
Peer Chaincode invoke-o orderer.example.com:7050  --tls $CORE _peer_tls_enabled--cafile/opt/gopath/src/ github.com/hyperledger/fabric/peer/crypto/ordererorganizations/example.com/orderers/orderer.example.com/msp/ Cacerts/ca.example.com-cert.pem  '{"Args": ["transfermarble", "Marble2", "Jerry"]}'
The system returns successfully, let's check it again.
' {"Args": ["readmarble", "Marble2"]} '
Query Result: {"color": "Green", "docType": "Marble", "name": "Marble2", "owner": "Jerry", "Size": 10}
So our changes to the COUCHDB database are valid, and in fabric it doesn't seem to be that we changed the COUCHDB content.

Enable COUCHDB as state Database in Hyperledger Fabric

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.