├── 0.stopNetwork.sh
├── 1-1.hy-sample.sh
├── 1-2.startNetwork.sh
├── 2.addOrg3.sh
├── 3-1.installNetcon.sh
├── 3-2.installEstateBook.sh
├── 3-3.installEstateTax.sh
├── 4-0.stopAppcli.sh
├── 4.startAppcli.sh
├── LICENSE
├── README.md
├── appcode
├── docker-compose-appcli.yaml
├── fcc-client
│ ├── README.md
│ ├── babel.config.js
│ ├── package.json
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── src
│ │ ├── App.vue
│ │ ├── assets
│ │ │ ├── guo.png
│ │ │ ├── logo.png
│ │ │ ├── logo.svg
│ │ │ └── zhengwu.png
│ │ ├── axios.js
│ │ ├── main.js
│ │ ├── plugins
│ │ │ └── vuetify.js
│ │ ├── router.js
│ │ ├── views
│ │ │ ├── Bigdata.vue
│ │ │ ├── EstateBook.vue
│ │ │ ├── EstateTax.vue
│ │ │ └── Netcon.vue
│ │ └── vue.config.js
│ ├── vue.config.js
│ └── yarn.lock
└── fccserver
│ └── src
│ ├── ccservice
│ ├── cccomm.go
│ ├── ccestatebook.go
│ ├── ccestatetax.go
│ ├── ccnetcon.go
│ └── common.go
│ ├── comm
│ └── webcomm.go
│ ├── config.yaml
│ ├── db
│ ├── dbservice.go
│ └── tbservice.go
│ ├── fccserver
│ ├── fccserver.go
│ ├── middleware
│ └── middleware.go
│ ├── routers
│ └── router.go
│ └── service
│ ├── cast.go
│ ├── caste.go
│ ├── estatebook.go
│ ├── estatetax.go
│ ├── netcon.go
│ └── system.go
└── chaincode
├── estatebook
└── estatebook.go
├── estatetax
└── estatetax.go
└── netcon
└── netcon.go
/0.stopNetwork.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Exit on first error
4 | set -e
5 |
6 | function clearContainers () {
7 | CONTAINER_IDS=$(docker ps -aq)
8 | if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then
9 | echo "---- No containers available for deletion ----"
10 | else
11 | docker rm -f $CONTAINER_IDS
12 | fi
13 | }
14 |
15 | function removeUnwantedImages() {
16 | DOCKER_IMAGE_IDS=$(docker images|awk '($1 ~ /dev-peer.*.example.*/) {print $3}')
17 | if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then
18 | echo "---- No images available for deletion ----"
19 | else
20 | docker rmi -f $DOCKER_IMAGE_IDS
21 | fi
22 | }
23 |
24 | clearContainers
25 | removeUnwantedImages
26 |
27 | cd ../first-network
28 | echo y | ./byfn.sh down
29 |
30 | cd ../fcc
31 | echo network stoped .
32 |
--------------------------------------------------------------------------------
/1-1.hy-sample.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright IBM Corp. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 | #
7 |
8 | # if version not passed in, default to latest released version
9 | VERSION=1.4.4
10 | # if ca version not passed in, default to latest released version
11 | CA_VERSION=1.4.4
12 | # current version of thirdparty images (couchdb, kafka and zookeeper) released
13 | THIRDPARTY_IMAGE_VERSION=0.4.18
14 | ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')")
15 | MARCH=$(uname -m)
16 |
17 | printHelp() {
18 | echo "Usage: bootstrap.sh [version [ca_version [thirdparty_version]]] [options]"
19 | echo
20 | echo "options:"
21 | echo "-h : this help"
22 | echo "-d : bypass docker image download"
23 | echo "-s : bypass fabric-samples repo clone"
24 | echo "-b : bypass download of platform-specific binaries"
25 | echo
26 | echo "e.g. bootstrap.sh 1.4.4 -s"
27 | echo "would download docker images and binaries for version 1.4.4"
28 | }
29 |
30 | # dockerPull() pulls docker images from fabric and chaincode repositories
31 | # note, if a docker image doesn't exist for a requested release, it will simply
32 | # be skipped, since this script doesn't terminate upon errors.
33 |
34 | dockerPull() {
35 | image_tag=$1
36 | shift
37 | while [[ $# -gt 0 ]]
38 | do
39 | image_name="$1"
40 | echo "====> hyperledger/fabric-$image_name:$image_tag"
41 | docker pull "hyperledger/fabric-$image_name:$image_tag"
42 | docker tag "hyperledger/fabric-$image_name:$image_tag" "hyperledger/fabric-$image_name"
43 | shift
44 | done
45 | }
46 |
47 | cloneSamplesRepo() {
48 | # clone (if needed) hyperledger/fabric-samples and checkout corresponding
49 | # version to the binaries and docker images to be downloaded
50 | if [ -d first-network ]; then
51 | # if we are in the fabric-samples repo, checkout corresponding version
52 | echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
53 | git checkout v${VERSION}
54 | elif [ -d fabric-samples ]; then
55 | # if fabric-samples repo already cloned and in current directory,
56 | # cd fabric-samples and checkout corresponding version
57 | echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
58 | cd fabric-samples && git checkout v${VERSION}
59 | else
60 | echo "===> Cloning hyperledger/fabric-samples repo and checkout v${VERSION}"
61 | git clone -b master https://github.com/hyperledger/fabric-samples.git && cd fabric-samples && git checkout v${VERSION}
62 | fi
63 | }
64 |
65 | # This will download the .tar.gz
66 | download() {
67 | local BINARY_FILE=$1
68 | local URL=$2
69 | echo "===> Downloading: " "${URL}"
70 | curl -s -L "${URL}" | tar xz || rc=$?
71 | if [ -n "$rc" ]; then
72 | echo "==> There was an error downloading the binary file."
73 | return 22
74 | else
75 | echo "==> Done."
76 | fi
77 | }
78 |
79 | pullBinaries() {
80 | echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
81 | download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
82 | if [ $? -eq 22 ]; then
83 | echo
84 | echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
85 | echo
86 | exit
87 | fi
88 |
89 | echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
90 | download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
91 | if [ $? -eq 22 ]; then
92 | echo
93 | echo "------> ${CA_TAG} fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----"
94 | echo
95 | exit
96 | fi
97 | }
98 |
99 | pullDockerImages() {
100 | command -v docker >& /dev/null
101 | NODOCKER=$?
102 | if [ "${NODOCKER}" == 0 ]; then
103 | FABRIC_IMAGES=(peer orderer ccenv tools)
104 | case "$VERSION" in
105 | 1.*)
106 | FABRIC_IMAGES+=(javaenv)
107 | shift
108 | ;;
109 | 2.*)
110 | FABRIC_IMAGES+=(nodeenv baseos javaenv)
111 | shift
112 | ;;
113 | esac
114 | echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
115 | echo "===> Pulling fabric Images"
116 | dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
117 | echo "===> Pulling fabric ca Image"
118 | CA_IMAGE=(ca)
119 | dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
120 | echo "===> Pulling thirdparty docker images"
121 | THIRDPARTY_IMAGES=(zookeeper kafka couchdb)
122 | dockerPull "${THIRDPARTY_TAG}" "${THIRDPARTY_IMAGES[@]}"
123 | echo
124 | echo "===> List out hyperledger docker images"
125 | docker images | grep hyperledger
126 | else
127 | echo "========================================================="
128 | echo "Docker not installed, bypassing download of Fabric images"
129 | echo "========================================================="
130 | fi
131 | }
132 |
133 | DOCKER=true
134 | SAMPLES=true
135 | BINARIES=true
136 |
137 | # Parse commandline args pull out
138 | # version and/or ca-version strings first
139 | if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
140 | VERSION=$1;shift
141 | if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
142 | CA_VERSION=$1;shift
143 | if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
144 | THIRDPARTY_IMAGE_VERSION=$1;shift
145 | fi
146 | fi
147 | fi
148 |
149 | # prior to 1.2.0 architecture was determined by uname -m
150 | if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
151 | export FABRIC_TAG=${MARCH}-${VERSION}
152 | export CA_TAG=${MARCH}-${CA_VERSION}
153 | export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
154 | else
155 | # starting with 1.2.0, multi-arch images will be default
156 | : "${CA_TAG:="$CA_VERSION"}"
157 | : "${FABRIC_TAG:="$VERSION"}"
158 | : "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
159 | fi
160 |
161 | BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz
162 | CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz
163 |
164 | # then parse opts
165 | while getopts "h?dsb" opt; do
166 | case "$opt" in
167 | h|\?)
168 | printHelp
169 | exit 0
170 | ;;
171 | d) DOCKER=false
172 | ;;
173 | s) SAMPLES=false
174 | ;;
175 | b) BINARIES=false
176 | ;;
177 | esac
178 | done
179 |
180 | if [ "$SAMPLES" == "true" ]; then
181 | echo
182 | echo "Clone hyperledger/fabric-samples repo"
183 | echo
184 | cloneSamplesRepo
185 | fi
186 | if [ "$BINARIES" == "true" ]; then
187 | echo
188 | echo "Pull Hyperledger Fabric binaries"
189 | echo
190 | pullBinaries
191 | fi
192 | if [ "$DOCKER" == "true" ]; then
193 | echo
194 | echo "Pull Hyperledger Fabric docker images"
195 | echo
196 | pullDockerImages
197 | fi
198 |
--------------------------------------------------------------------------------
/1-2.startNetwork.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright IBM Corp All Rights Reserved
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 | #
7 | # Exit on first error
8 | set -e
9 |
10 | # launch network; create channel and join peer to channel
11 | function clearContainers () {
12 | CONTAINER_IDS=$(docker ps -aq)
13 | if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then
14 | echo "---- No containers available for deletion ----"
15 | else
16 | docker rm -f $CONTAINER_IDS
17 | fi
18 | }
19 |
20 | # Delete any images that were generated as a part of this setup
21 | # specifically the following images are often left behind:
22 | # TODO list generated image naming patterns
23 | function removeUnwantedImages() {
24 | DOCKER_IMAGE_IDS=$(docker images|awk '($1 ~ /dev-peer.*.example.*/) {print $3}')
25 | if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then
26 | echo "---- No images available for deletion ----"
27 | else
28 | docker rmi -f $DOCKER_IMAGE_IDS
29 | fi
30 | }
31 |
32 | clearContainers
33 | removeUnwantedImages
34 |
35 | cd ../first-network
36 |
37 | echo y | ./byfn.sh down
38 | echo y | ./byfn.sh up -a -n -s couchdb
39 |
40 | cd ../fcc
41 | echo network started .
42 |
--------------------------------------------------------------------------------
/2.addOrg3.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | echo
3 | echo ===========================================
4 | echo === add Org3 to network
5 | echo ==========================================
6 | echo
7 |
8 | CHANNEL_NAME="mychannel"
9 |
10 | echo
11 | echo "========= Creating config transaction to add org3 to network =========== "
12 | echo
13 |
14 | echo "Generate the Org3 Crypto Material"
15 | cd ../first-network/org3-artifacts
16 | ../../bin/cryptogen generate --config=./org3-crypto.yaml
17 | export FABRIC_CFG_PATH=$PWD && ../../bin/configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json
18 | cp -r crypto-config/peerOrganizations/org3.example.com/ ../crypto-config/peerOrganizations/
19 | cd ../../fcc
20 |
21 | echo "add org3 join channel ...."
22 | export IMAGE_TAG=1.4.3 && export COMPOSE_PROJECT_NAME=net && docker-compose -f ../first-network/docker-compose-org3.yaml up -d
23 | docker exec cli /opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/step1org3.sh
24 | docker exec cli /opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/step2org3.sh
25 |
--------------------------------------------------------------------------------
/3-1.installNetcon.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | CC_RUNTIME_LANGUAGE=golang
4 | CC_SRC_PATH=github.com/chaincode/netcon
5 |
6 | CONFIG_ROOT=/opt/gopath/src/github.com/hyperledger/fabric/peer
7 | ORG1_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
8 | ORG1_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
9 | ORG2_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
10 | ORG2_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
11 | ORG3_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
12 | ORG3_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
13 | ORDERER_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
14 | set -x
15 |
16 | echo y |cp chaincode/netcon/netcon.go ../chaincode/netcon/
17 |
18 | echo "Installing smart contract on peer0.org1.example.com"
19 | docker exec \
20 | -e CORE_PEER_LOCALMSPID=Org1MSP \
21 | -e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \
22 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
23 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
24 | cli \
25 | peer chaincode install \
26 | -n netcon \
27 | -v 1.0 \
28 | -p "$CC_SRC_PATH" \
29 | -l "$CC_RUNTIME_LANGUAGE"
30 |
31 | echo "Installing smart contract on peer1.org1.example.com"
32 | docker exec \
33 | -e CORE_PEER_LOCALMSPID=Org1MSP \
34 | -e CORE_PEER_ADDRESS=peer1.org1.example.com:8051 \
35 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
36 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
37 | cli \
38 | peer chaincode install \
39 | -n netcon \
40 | -v 1.0 \
41 | -p "$CC_SRC_PATH" \
42 | -l "$CC_RUNTIME_LANGUAGE"
43 |
44 | echo "Installing smart contract on peer0.org2.example.com"
45 | docker exec \
46 | -e CORE_PEER_LOCALMSPID=Org2MSP \
47 | -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
48 | -e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
49 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
50 | cli \
51 | peer chaincode install \
52 | -n netcon \
53 | -v 1.0 \
54 | -p "$CC_SRC_PATH" \
55 | -l "$CC_RUNTIME_LANGUAGE"
56 |
57 | echo "Installing smart contract on peer1.org2.example.com"
58 | docker exec \
59 | -e CORE_PEER_LOCALMSPID=Org2MSP \
60 | -e CORE_PEER_ADDRESS=peer1.org2.example.com:10051 \
61 | -e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
62 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
63 | cli \
64 | peer chaincode install \
65 | -n netcon \
66 | -v 1.0 \
67 | -p "$CC_SRC_PATH" \
68 | -l "$CC_RUNTIME_LANGUAGE"
69 |
70 | echo "Installing smart contract on peer0.org3.example.com"
71 | docker exec \
72 | -e CORE_PEER_LOCALMSPID=Org3MSP \
73 | -e CORE_PEER_ADDRESS=peer0.org3.example.com:11051 \
74 | -e CORE_PEER_MSPCONFIGPATH=${ORG3_MSPCONFIGPATH} \
75 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG3_TLS_ROOTCERT_FILE} \
76 | cli \
77 | peer chaincode install \
78 | -n netcon \
79 | -v 1.0 \
80 | -p "$CC_SRC_PATH" \
81 | -l "$CC_RUNTIME_LANGUAGE"
82 |
83 | echo "Installing smart contract on peer1.org3.example.com"
84 | docker exec \
85 | -e CORE_PEER_LOCALMSPID=Org3MSP \
86 | -e CORE_PEER_ADDRESS=peer1.org3.example.com:12051 \
87 | -e CORE_PEER_MSPCONFIGPATH=${ORG3_MSPCONFIGPATH} \
88 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG3_TLS_ROOTCERT_FILE} \
89 | cli \
90 | peer chaincode install \
91 | -n netcon \
92 | -v 1.0 \
93 | -p "$CC_SRC_PATH" \
94 | -l "$CC_RUNTIME_LANGUAGE"
95 |
96 | echo "Instantiating smart contract on mychannel"
97 | docker exec \
98 | -e CORE_PEER_LOCALMSPID=Org1MSP \
99 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
100 | cli \
101 | peer chaincode instantiate \
102 | -o orderer.example.com:7050 \
103 | -C mychannel \
104 | -n netcon \
105 | -l "$CC_RUNTIME_LANGUAGE" \
106 | -v 1.0 \
107 | -c '{"Args":[]}' \
108 | -P "AND('Org1MSP.member','Org2MSP.member')" \
109 | --tls \
110 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
111 | --peerAddresses peer0.org1.example.com:7051 \
112 | --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE}
113 |
114 | echo "Waiting for instantiation request to be committed ..."
115 | sleep 10
116 |
117 | echo "Submitting init transaction to smart contract on mychannel"
118 | echo "The transaction is sent to all of the peers so that chaincode is built before receiving the following requests"
119 | docker exec \
120 | -e CORE_PEER_LOCALMSPID=Org1MSP \
121 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
122 | cli \
123 | peer chaincode invoke \
124 | -o orderer.example.com:7050 \
125 | -C mychannel \
126 | -n netcon \
127 | -c '{"function":"queryAll","Args":[]}' \
128 | --waitForEvent \
129 | --tls \
130 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
131 | # --peerAddresses peer0.org1.example.com:7051 \
132 | # --peerAddresses peer1.org1.example.com:8051 \
133 | # --peerAddresses peer0.org2.example.com:9051 \
134 | # --peerAddresses peer1.org2.example.com:10051 \
135 | # --peerAddresses peer0.org3.example.com:11051 \
136 | # --peerAddresses peer1.org3.example.com:12051 \
137 | # --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
138 | # --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
139 | # --tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE} \
140 | # --tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE} \
141 | # --tlsRootCertFiles ${ORG3_TLS_ROOTCERT_FILE} \
142 | # --tlsRootCertFiles ${ORG3_TLS_ROOTCERT_FILE}
143 |
144 | echo "List all instantiated chaincode in channal mychannel..."
145 | docker exec \
146 | -e CORE_PEER_LOCALMSPID=Org1MSP \
147 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
148 | cli \
149 | peer chaincode list --instantiated -C mychannel
150 |
151 | set +x
152 |
--------------------------------------------------------------------------------
/3-2.installEstateBook.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | CC_RUNTIME_LANGUAGE=golang
4 | CC_SRC_PATH=github.com/chaincode/estatebook
5 |
6 | CONFIG_ROOT=/opt/gopath/src/github.com/hyperledger/fabric/peer
7 | ORG1_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
8 | ORG1_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
9 | ORG2_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
10 | ORG2_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
11 | ORG3_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
12 | ORG3_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
13 | ORDERER_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
14 | set -x
15 |
16 | echo y |cp chaincode/estatebook/estatebook.go ../chaincode/estatebook/
17 |
18 | echo "Installing smart contract on peer0.org1.example.com"
19 | docker exec \
20 | -e CORE_PEER_LOCALMSPID=Org1MSP \
21 | -e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \
22 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
23 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
24 | cli \
25 | peer chaincode install \
26 | -n estatebook \
27 | -v 1.0 \
28 | -p "$CC_SRC_PATH" \
29 | -l "$CC_RUNTIME_LANGUAGE"
30 |
31 | echo "Installing smart contract on peer1.org1.example.com"
32 | docker exec \
33 | -e CORE_PEER_LOCALMSPID=Org1MSP \
34 | -e CORE_PEER_ADDRESS=peer1.org1.example.com:8051 \
35 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
36 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
37 | cli \
38 | peer chaincode install \
39 | -n estatebook \
40 | -v 1.0 \
41 | -p "$CC_SRC_PATH" \
42 | -l "$CC_RUNTIME_LANGUAGE"
43 |
44 | echo "Installing smart contract on peer0.org2.example.com"
45 | docker exec \
46 | -e CORE_PEER_LOCALMSPID=Org2MSP \
47 | -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
48 | -e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
49 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
50 | cli \
51 | peer chaincode install \
52 | -n estatebook \
53 | -v 1.0 \
54 | -p "$CC_SRC_PATH" \
55 | -l "$CC_RUNTIME_LANGUAGE"
56 |
57 | echo "Installing smart contract on peer1.org2.example.com"
58 | docker exec \
59 | -e CORE_PEER_LOCALMSPID=Org2MSP \
60 | -e CORE_PEER_ADDRESS=peer1.org2.example.com:10051 \
61 | -e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
62 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
63 | cli \
64 | peer chaincode install \
65 | -n estatebook \
66 | -v 1.0 \
67 | -p "$CC_SRC_PATH" \
68 | -l "$CC_RUNTIME_LANGUAGE"
69 |
70 | echo "Installing smart contract on peer0.org3.example.com"
71 | docker exec \
72 | -e CORE_PEER_LOCALMSPID=Org3MSP \
73 | -e CORE_PEER_ADDRESS=peer0.org3.example.com:11051 \
74 | -e CORE_PEER_MSPCONFIGPATH=${ORG3_MSPCONFIGPATH} \
75 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG3_TLS_ROOTCERT_FILE} \
76 | cli \
77 | peer chaincode install \
78 | -n estatebook \
79 | -v 1.0 \
80 | -p "$CC_SRC_PATH" \
81 | -l "$CC_RUNTIME_LANGUAGE"
82 |
83 | echo "Installing smart contract on peer1.org3.example.com"
84 | docker exec \
85 | -e CORE_PEER_LOCALMSPID=Org3MSP \
86 | -e CORE_PEER_ADDRESS=peer1.org3.example.com:12051 \
87 | -e CORE_PEER_MSPCONFIGPATH=${ORG3_MSPCONFIGPATH} \
88 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG3_TLS_ROOTCERT_FILE} \
89 | cli \
90 | peer chaincode install \
91 | -n estatebook \
92 | -v 1.0 \
93 | -p "$CC_SRC_PATH" \
94 | -l "$CC_RUNTIME_LANGUAGE"
95 |
96 | echo "Instantiating smart contract on mychannel"
97 | docker exec \
98 | -e CORE_PEER_LOCALMSPID=Org1MSP \
99 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
100 | cli \
101 | peer chaincode instantiate \
102 | -o orderer.example.com:7050 \
103 | -C mychannel \
104 | -n estatebook \
105 | -l "$CC_RUNTIME_LANGUAGE" \
106 | -v 1.0 \
107 | -c '{"Args":[]}' \
108 | -P "AND('Org1MSP.member','Org2MSP.member')" \
109 | --tls \
110 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
111 | --peerAddresses peer0.org1.example.com:7051 \
112 | --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE}
113 |
114 | echo "Waiting for instantiation request to be committed ..."
115 | sleep 10
116 |
117 | echo "Submitting init transaction to smart contract on mychannel"
118 | echo "The transaction is sent to all of the peers so that chaincode is built before receiving the following requests"
119 | docker exec \
120 | -e CORE_PEER_LOCALMSPID=Org1MSP \
121 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
122 | cli \
123 | peer chaincode invoke \
124 | -o orderer.example.com:7050 \
125 | -C mychannel \
126 | -n estatebook \
127 | -c '{"function":"queryAll","Args":[]}' \
128 | --waitForEvent \
129 | --tls \
130 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
131 | # --peerAddresses peer0.org1.example.com:7051 \
132 | # --peerAddresses peer1.org1.example.com:8051 \
133 | # --peerAddresses peer0.org2.example.com:9051 \
134 | # --peerAddresses peer1.org2.example.com:10051 \
135 | # --peerAddresses peer0.org3.example.com:11051 \
136 | # --peerAddresses peer1.org3.example.com:12051 \
137 | # --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
138 | # --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
139 | # --tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE} \
140 | # --tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE} \
141 | # --tlsRootCertFiles ${ORG3_TLS_ROOTCERT_FILE} \
142 | # --tlsRootCertFiles ${ORG3_TLS_ROOTCERT_FILE}
143 |
144 | echo "List all instantiated chaincode in channal mychannel..."
145 | docker exec \
146 | -e CORE_PEER_LOCALMSPID=Org1MSP \
147 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
148 | cli \
149 | peer chaincode list --instantiated -C mychannel
150 |
151 | set +x
152 |
--------------------------------------------------------------------------------
/3-3.installEstateTax.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | CC_RUNTIME_LANGUAGE=golang
4 | CC_SRC_PATH=github.com/chaincode/estatetax
5 |
6 | CONFIG_ROOT=/opt/gopath/src/github.com/hyperledger/fabric/peer
7 | ORG1_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
8 | ORG1_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
9 | ORG2_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
10 | ORG2_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
11 | ORG3_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
12 | ORG3_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
13 | ORDERER_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
14 | set -x
15 |
16 | echo y |cp chaincode/estatetax/estatetax.go ../chaincode/estatetax/
17 |
18 | echo "Installing smart contract on peer0.org1.example.com"
19 | docker exec \
20 | -e CORE_PEER_LOCALMSPID=Org1MSP \
21 | -e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \
22 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
23 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
24 | cli \
25 | peer chaincode install \
26 | -n estatetax \
27 | -v 1.0 \
28 | -p "$CC_SRC_PATH" \
29 | -l "$CC_RUNTIME_LANGUAGE"
30 |
31 | echo "Installing smart contract on peer1.org1.example.com"
32 | docker exec \
33 | -e CORE_PEER_LOCALMSPID=Org1MSP \
34 | -e CORE_PEER_ADDRESS=peer1.org1.example.com:8051 \
35 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
36 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG1_TLS_ROOTCERT_FILE} \
37 | cli \
38 | peer chaincode install \
39 | -n estatetax \
40 | -v 1.0 \
41 | -p "$CC_SRC_PATH" \
42 | -l "$CC_RUNTIME_LANGUAGE"
43 |
44 | echo "Installing smart contract on peer0.org2.example.com"
45 | docker exec \
46 | -e CORE_PEER_LOCALMSPID=Org2MSP \
47 | -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
48 | -e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
49 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
50 | cli \
51 | peer chaincode install \
52 | -n estatetax \
53 | -v 1.0 \
54 | -p "$CC_SRC_PATH" \
55 | -l "$CC_RUNTIME_LANGUAGE"
56 |
57 | echo "Installing smart contract on peer1.org2.example.com"
58 | docker exec \
59 | -e CORE_PEER_LOCALMSPID=Org2MSP \
60 | -e CORE_PEER_ADDRESS=peer1.org2.example.com:10051 \
61 | -e CORE_PEER_MSPCONFIGPATH=${ORG2_MSPCONFIGPATH} \
62 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG2_TLS_ROOTCERT_FILE} \
63 | cli \
64 | peer chaincode install \
65 | -n estatetax \
66 | -v 1.0 \
67 | -p "$CC_SRC_PATH" \
68 | -l "$CC_RUNTIME_LANGUAGE"
69 |
70 | echo "Installing smart contract on peer0.org3.example.com"
71 | docker exec \
72 | -e CORE_PEER_LOCALMSPID=Org3MSP \
73 | -e CORE_PEER_ADDRESS=peer0.org3.example.com:11051 \
74 | -e CORE_PEER_MSPCONFIGPATH=${ORG3_MSPCONFIGPATH} \
75 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG3_TLS_ROOTCERT_FILE} \
76 | cli \
77 | peer chaincode install \
78 | -n estatetax \
79 | -v 1.0 \
80 | -p "$CC_SRC_PATH" \
81 | -l "$CC_RUNTIME_LANGUAGE"
82 |
83 | echo "Installing smart contract on peer1.org3.example.com"
84 | docker exec \
85 | -e CORE_PEER_LOCALMSPID=Org3MSP \
86 | -e CORE_PEER_ADDRESS=peer1.org3.example.com:12051 \
87 | -e CORE_PEER_MSPCONFIGPATH=${ORG3_MSPCONFIGPATH} \
88 | -e CORE_PEER_TLS_ROOTCERT_FILE=${ORG3_TLS_ROOTCERT_FILE} \
89 | cli \
90 | peer chaincode install \
91 | -n estatetax \
92 | -v 1.0 \
93 | -p "$CC_SRC_PATH" \
94 | -l "$CC_RUNTIME_LANGUAGE"
95 |
96 | echo "Instantiating smart contract on mychannel"
97 | docker exec \
98 | -e CORE_PEER_LOCALMSPID=Org1MSP \
99 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
100 | cli \
101 | peer chaincode instantiate \
102 | -o orderer.example.com:7050 \
103 | -C mychannel \
104 | -n estatetax \
105 | -l "$CC_RUNTIME_LANGUAGE" \
106 | -v 1.0 \
107 | -c '{"Args":[]}' \
108 | -P "AND('Org1MSP.member','Org2MSP.member')" \
109 | --tls \
110 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
111 | --peerAddresses peer0.org1.example.com:7051 \
112 | --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE}
113 |
114 | echo "Waiting for instantiation request to be committed ..."
115 | sleep 10
116 |
117 | echo "Submitting init transaction to smart contract on mychannel"
118 | echo "The transaction is sent to all of the peers so that chaincode is built before receiving the following requests"
119 | docker exec \
120 | -e CORE_PEER_LOCALMSPID=Org1MSP \
121 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
122 | cli \
123 | peer chaincode invoke \
124 | -o orderer.example.com:7050 \
125 | -C mychannel \
126 | -n estatetax \
127 | -c '{"function":"queryAll","Args":[]}' \
128 | --waitForEvent \
129 | --tls \
130 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
131 | # --peerAddresses peer0.org1.example.com:7051 \
132 | # --peerAddresses peer1.org1.example.com:8051 \
133 | # --peerAddresses peer0.org2.example.com:9051 \
134 | # --peerAddresses peer1.org2.example.com:10051 \
135 | # --peerAddresses peer0.org3.example.com:11051 \
136 | # --peerAddresses peer1.org3.example.com:12051 \
137 | # --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
138 | # --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
139 | # --tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE} \
140 | # --tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE} \
141 | # --tlsRootCertFiles ${ORG3_TLS_ROOTCERT_FILE} \
142 | # --tlsRootCertFiles ${ORG3_TLS_ROOTCERT_FILE}
143 |
144 | echo "List all instantiated chaincode in channal mychannel..."
145 | docker exec \
146 | -e CORE_PEER_LOCALMSPID=Org1MSP \
147 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
148 | cli \
149 | peer chaincode list --instantiated -C mychannel
150 |
151 | set +x
152 |
--------------------------------------------------------------------------------
/4-0.stopAppcli.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | cd appcode
3 | docker-compose -f docker-compose-appcli.yaml down -v
4 | cd ..
5 |
--------------------------------------------------------------------------------
/4.startAppcli.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | cd appcode
3 | docker-compose -f docker-compose-appcli.yaml up -d
4 | cd ..
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### 以不动产登记业务为例,使用超级账本搭建政务数据区块链原型
2 |
3 | - ### 关于业务流程
4 | - 区域链(基于证书准入的联盟链)网络
5 | 
6 | - 业务流程时序
7 | 
8 | - ### 关于超级账本
9 | 关于区块链、超级账本、智能合约等概念,请自行谷哥和度娘。建议直接参考官网文档 https://hyperledger-fabric.readthedocs.io/en/release-1.4/
10 |
11 | - ### 关于本例说明
12 | - 本例仅限搭建原型用于验证技术可行性目的,远达不到产品级可用;
13 | - 本例采用了3个组织,每组织2个节点,用于不动产、房管、税务三个部门做背书节点;3份智能合约(网签合同、纳税凭证、不动产权证书)跑在1个通道;状态数据库采用CouchDB;
14 | - 本例DEMO: http://xujf000.tk:28888/ (VPS,1CPU 1G MEM)
15 |
16 | - ### 如何搭建区块链并部署运行智能合约
17 | 本例采用1.4.3版本。以下步骤在centos7上完成,并适用于ubuntu/MACOS/WINDOWS等
18 | 1. 安装环境(go1.3以上,docker-ce,docker-compose,git)
19 | ```bash
20 | cd /opt
21 | wget https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz
22 | tar zxvf go*.gz
23 | yum install -y yum-utils device-mapper-persistent-data lvm2
24 | wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
25 | yum install -y docker-ce docker-compose git
26 | ```
27 | 2. 下载超级账本官方超级账本网络示例
28 |
29 | 若带梯子,下载官方脚本执行:
30 | ```bash
31 | curl -sSL http://bit.ly/2ysbOFE | bash -s -- 1.4.3 1.4.3 0.4.15
32 | ```
33 | 若无梯子,直接运行已下载的脚本执行:
34 | ```bash
35 | ./1-1.hy-sample.sh -- 1.4.3 1.4.3 0.4.15
36 | ```
37 | 将会在当前/opt目录下生成fabric-samples目录,并自动下载命令工具和镜像。
38 |
39 | 3. 将fabric-samples/bin和/opt/go/bin 加入本地PATH
40 |
41 | 4. 下载本示例
42 | ```bash
43 | cd /opt/fabric-samples
44 | git clone https://github.com/fengzxu/fcc.git
45 | cd fcc
46 | ```
47 | 5. 启动示例网络,创建区块链网络(2个组织,每组织2个节点)
48 | ```bash
49 | chmod +x *.sh
50 | ./1-2.startNetwork.sh
51 | ```
52 | 完成后,结果显示:
53 | ```bash
54 | ========= All GOOD, BYFN execution completed ===========
55 | ```
56 | 6. 加入第3个组织,2个节点
57 | ```bash
58 | ./2.addOrg3.sh
59 | ```
60 | 完成后,结果显示:
61 | ```bash
62 | ========= Org3 is now halfway onto your first network =========
63 | ```
64 | 7. 部署政务智能合约,并实例化
65 | ```bash
66 | ./3-1.installNetcon.sh #合约:网签合同备案
67 | ./3-2.installEstateBook.sh #合约:不动产权证书
68 | ./3-3.installEstateTax.sh #合约:不动产业务缴税
69 | ```
70 | 完成后,结果显示:
71 | ```bash
72 | Get instantiated chaincodes on channel mychannel:
73 | Name: estatebook, Version: 1.0, Path: github.com/chaincode/estatebook, Escc: escc, Vscc: vscc
74 | Name: estatetax, Version: 1.0, Path: github.com/chaincode/estatetax, Escc: escc, Vscc: vscc
75 | Name: netcon, Version: 1.0, Path: github.com/chaincode/netcon, Escc: escc, Vscc: vscc
76 | ```
77 | 8. 编译后台。 代码位于appcode/fccserver/src 可自行编译,或直接使用已编译完成的可执行文件。
78 | ```bash
79 | chmod +x appcode/fccserver/src/fccserver
80 | ```
81 | 启动后台容器
82 | ```bash
83 | ./4.startAppcli.sh
84 | docker logs -f appcli
85 | ```
86 | 如果启动正常,会显示:
87 | ```bash
88 | [fcc-server] 2019/12/12 03:03:55 system db initiated successfully.
89 | [fcc-server] 2019/12/12 03:03:56 Chaincode client initialed successfully.
90 | [fcc-server] 2019/12/12 03:03:56 Server started on :1206
91 | ```
92 | 9. 编译和部署前端。 前端采用VUE,也可使用其它前端框架或HTML。使用GNINX或其它WEB服务器部署编译后的前端代码。注:当前未使用登录和权限设置。
93 | 
94 | 第一次操作数据上链时,区块链网络后端会根据背书节点和合约数量创建镜像并启动容器(本例为3*2) 大约耗时30-60秒,之后每次上链操作约1秒,查询小于1秒。
95 |
96 | 10. 重建后台容器或重建整个区块链网络:
97 | ```bash
98 | ./4-0.stopAppcli.sh #重建后台容器
99 | ./0.stopNetwork.sh #重建整个区块链网络
100 | ```
101 |
102 | - ### 产品化需要注意的几个问题
103 | - 背书节点与查询节点:涉及合约数据的变更操作(新建、修改、删除)需要多个背书节点(AND、OR策略),查询合约和节点可在同一通道或不同通道;
104 | - 共识:需要采用KAFKA+ZK集群或ETCD集群;
105 | - 证书与权限:通过CA集群和MSP来管理发放不同权限的证书,考虑用证书或其它方式实现基于RBAC的权限控制;
106 | - 如果可以,采用国产加密算法;
107 |
108 |
--------------------------------------------------------------------------------
/appcode/docker-compose-appcli.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | version: '2.1'
7 |
8 | networks:
9 | example.com:
10 | external:
11 | name: net_byfn
12 |
13 | volumes:
14 | appcli:
15 |
16 | services:
17 | appcli:
18 | container_name: appcli
19 | image: hyperledger/fabric-tools:1.4.3
20 | tty: true
21 | stdin_open: true
22 | # environment:
23 | # - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=net_byfn
24 | # - GOPATH=/opt/gopath
25 | # - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
26 | # - FABRIC_LOGGING_SPEC=DEBUG
27 | # - FABRIC_LOGGING_SPEC=INFO
28 | # - CORE_PEER_ID=appcli
29 | # - CA_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem
30 | # - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
31 | # - CORE_PEER_LOCALMSPID=Org1MSP
32 | # - CORE_PEER_TLS_ENABLED=true
33 | # - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
34 | # - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
35 | # - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
36 | # - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
37 | working_dir: /opt/
38 | command: ./fccserver
39 | volumes:
40 | # - /var/run/:/host/var/run/
41 | # - /opt/go/:/opt/go/
42 | - ./fccserver/src/fccserver:/opt/fccserver
43 | - ./fccserver/src/config.yaml:/opt/config.yaml
44 | - ../../first-network/crypto-config/:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
45 | # - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
46 | ports:
47 | - 1206:1206
48 | networks:
49 | - example.com
50 |
--------------------------------------------------------------------------------
/appcode/fcc-client/README.md:
--------------------------------------------------------------------------------
1 | # fcc-client
2 |
3 | ## Project setup
4 | ```
5 | yarn install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | yarn run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | yarn run build
16 | ```
17 |
18 | ### Run your tests
19 | ```
20 | yarn run test
21 | ```
22 |
23 | ### Lints and fixes files
24 | ```
25 | yarn run lint
26 | ```
27 |
28 | ### Customize configuration
29 | See [Configuration Reference](https://cli.vuejs.org/config/).
30 |
--------------------------------------------------------------------------------
/appcode/fcc-client/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/appcode/fcc-client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fcc-client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "@fortawesome/fontawesome-free": "^5.8.2",
12 | "axios": "^0.19.0",
13 | "core-js": "^3.4.3",
14 | "querystring": "^0.2.0",
15 | "roboto-fontface": "*",
16 | "vue": "^2.6.10",
17 | "vue-router": "^3.1.3",
18 | "vuetify": "^2.1.0"
19 | },
20 | "devDependencies": {
21 | "@vue/cli-plugin-babel": "^4.1.0",
22 | "@vue/cli-plugin-eslint": "^4.1.0",
23 | "@vue/cli-service": "^4.1.0",
24 | "babel-eslint": "^10.0.3",
25 | "eslint": "^5.16.0",
26 | "eslint-plugin-vue": "^5.0.0",
27 | "sass": "^1.19.0",
28 | "sass-loader": "^8.0.0",
29 | "vue-cli-plugin-vuetify": "^2.0.2",
30 | "vue-template-compiler": "^2.6.10",
31 | "vuetify-loader": "^1.3.0"
32 | },
33 | "eslintConfig": {
34 | "root": true,
35 | "env": {
36 | "node": true
37 | },
38 | "extends": [
39 | "plugin:vue/essential",
40 | "eslint:recommended"
41 | ],
42 | "rules": {},
43 | "parserOptions": {
44 | "parser": "babel-eslint"
45 | }
46 | },
47 | "browserslist": [
48 | "> 1%",
49 | "last 2 versions"
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/appcode/fcc-client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzxu/fcc/aa2c77e2e2cfc650d30f4b9c432d2035517db545/appcode/fcc-client/public/favicon.ico
--------------------------------------------------------------------------------
/appcode/fcc-client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 基于区块链的政务大数据
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {{link.icon}}
14 |
15 |
16 |
17 | {{link.text1}}
18 | {{link.text2}}
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 基于联盟区块链的政务大数据共享
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | © xujf000@gmail.com 2020
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/assets/guo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzxu/fcc/aa2c77e2e2cfc650d30f4b9c432d2035517db545/appcode/fcc-client/src/assets/guo.png
--------------------------------------------------------------------------------
/appcode/fcc-client/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzxu/fcc/aa2c77e2e2cfc650d30f4b9c432d2035517db545/appcode/fcc-client/src/assets/logo.png
--------------------------------------------------------------------------------
/appcode/fcc-client/src/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/assets/zhengwu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzxu/fcc/aa2c77e2e2cfc650d30f4b9c432d2035517db545/appcode/fcc-client/src/assets/zhengwu.png
--------------------------------------------------------------------------------
/appcode/fcc-client/src/axios.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | axios.interceptors.request.use(
3 | config => {
4 | return config;
5 | },
6 | error => {
7 | return Promise.reject(error);
8 | });
9 |
10 | axios.interceptors.response.use(
11 | response => {
12 | return response;
13 | },
14 | error => {
15 | return Promise.reject(error);
16 | }
17 | );
18 | export default axios;
19 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import vuetify from './plugins/vuetify';
4 | import router from './router'
5 | import axios from './axios'
6 | import querystring from 'querystring'
7 | import 'roboto-fontface/css/roboto/roboto-fontface.css'
8 | import '@fortawesome/fontawesome-free/css/all.css'
9 |
10 | Vue.config.productionTip = false
11 | //set axios form-data
12 | Vue.prototype.$qs = querystring;
13 | Vue.prototype.$axios = axios
14 |
15 | new Vue({
16 | vuetify,
17 | router,
18 | axios,
19 | render: h => h(App)
20 | }).$mount('#app')
21 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/plugins/vuetify.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import Vuetify from 'vuetify/lib';
3 |
4 | Vue.use(Vuetify);
5 |
6 | export default new Vuetify({
7 | icons: {
8 | iconfont: 'fa',
9 | },
10 | });
11 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 |
4 | Vue.use(Router)
5 |
6 | export default new Router({
7 | routes: [
8 | {
9 | path: '/',
10 | name: 'Netcon',
11 | component: () => import('@/views/Netcon.vue')
12 | },
13 | {
14 | path: '/estatebook',
15 | name: 'Estatebook',
16 | component: () => import('@/views/EstateBook.vue')
17 | },
18 | {
19 | path: '/bigdata',
20 | name: 'Bigdata',
21 | component: () => import('@/views/Bigdata.vue')
22 | },
23 | {
24 | path: '/estatetax',
25 | name: 'EstateTax',
26 | component: () => import('@/views/EstateTax.vue')
27 | },
28 | ]
29 | })
--------------------------------------------------------------------------------
/appcode/fcc-client/src/views/Bigdata.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | fas fa-file-alt
7 | 【链上数据】房屋交易合同备案
8 |
9 |
10 | fas fa-dollar-sign
11 | 【链上数据】不动产登记业务纳税凭证
12 |
13 |
14 | fas fa-id-badge
15 | 【链上数据】不动产权证书
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
176 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/views/EstateBook.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 不动产登记业务受理与证书发放
8 |
9 |
10 |
11 | fas fa-sync-alt
12 |
13 |
14 | fas fa-plus
15 |
16 |
17 |
18 |
19 | {{ item.BookID }}
20 |
21 |
22 | 上链
23 | 查链
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{getDialogTitle(dialogtype)}}
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 上链
62 | 保存
63 | 关闭
64 |
65 |
66 |
67 | {{sb.text}}
68 |
69 |
70 |
71 |
72 |
316 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/views/EstateTax.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 不动产登记业务缴税
8 |
9 |
10 |
11 | fas fa-sync-alt
12 |
13 |
14 | fas fa-plus
15 |
16 |
17 |
18 |
19 | {{ item.TaxID }}
20 |
21 |
22 | 上链
23 | 查链
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{getDialogTitle(dialogtype)}}
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | 上链
54 | 保存
55 | 关闭
56 |
57 |
58 |
59 | {{sb.text}}
60 |
61 |
62 |
63 |
64 |
259 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/views/Netcon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 房屋交易备案管理
7 |
8 |
9 |
10 | fas fa-sync-alt
11 |
12 |
13 | fas fa-plus
14 |
15 |
16 |
17 |
18 | {{ item.NetconID }}
19 |
20 |
21 | 上链
22 | 查链
23 |
24 |
25 |
26 |
27 |
28 |
29 | {{getDialogTitle(dialogtype)}}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | 上链
61 | 保存
62 | 关闭
63 |
64 |
65 |
66 | {{sb.text}}
67 |
68 |
69 |
70 |
71 |
282 |
--------------------------------------------------------------------------------
/appcode/fcc-client/src/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | productionSourceMap: false,
3 | configureWebpack: {
4 | devServer: {
5 | proxy: {
6 | '/api': {
7 | target: 'http://localhost:1206', //
8 | changeOrigin: true, //
9 | pathRewrite: {
10 | '^/api': '/api'
11 | }
12 | }
13 | }
14 | }
15 | },
16 | }
17 |
--------------------------------------------------------------------------------
/appcode/fcc-client/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "transpileDependencies": [
3 | "vuetify"
4 | ],
5 | productionSourceMap: false,
6 | configureWebpack: {
7 | devServer: {
8 | proxy: {
9 | '/api': {
10 | target: 'http://localhost:1206', //
11 | changeOrigin: true, //
12 | pathRewrite: {
13 | '^/api': '/api'
14 | }
15 | }
16 | }
17 | }
18 | },
19 | }
--------------------------------------------------------------------------------
/appcode/fccserver/src/ccservice/cccomm.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package ccservice
18 |
19 | import (
20 | "github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
21 | "github.com/hyperledger/fabric-sdk-go/pkg/core/config"
22 | "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
23 | "log"
24 | )
25 |
26 | var (
27 | ccFile = "./config.yaml"
28 | userName = "User1"
29 | orgName = "Org1"
30 | channelName = "mychannel"
31 | ccNetcon = "netcon"
32 | ccEstateBook = "estatebook"
33 | ccEstatetax = "estatetax"
34 | )
35 |
36 | var sdk *fabsdk.FabricSDK
37 | var cclient *channel.Client
38 |
39 | func InitCCOnStart() error {
40 | sdk, err := fabsdk.New(config.FromFile(ccFile))
41 | if err != nil {
42 | log.Println("WARN: init Chaincode SDK error:", err.Error())
43 | return err
44 | }
45 | clientContext := sdk.ChannelContext(channelName, fabsdk.WithUser(userName), fabsdk.WithOrg(orgName))
46 | if clientContext == nil {
47 | log.Println("WARN: init Chaincode clientContext error:", err.Error())
48 | return err
49 | } else {
50 | cclient, err = channel.New(clientContext)
51 | if err != nil {
52 | log.Println("WARN: init Chaincode cclient error:", err.Error())
53 | }
54 | }
55 | log.Println("Chaincode client initialed successfully.")
56 | return nil
57 | }
58 |
59 | func GetChannelClient() *channel.Client {
60 | return cclient
61 | }
62 |
63 | func CCinvoke(channelClient *channel.Client, ccname, fcn string, args []string) ([]byte, error) {
64 | var tempArgs [][]byte
65 | for i := 0; i < len(args); i++ {
66 | tempArgs = append(tempArgs, []byte(args[i]))
67 | }
68 | qrequest := channel.Request{
69 | ChaincodeID: ccname,
70 | Fcn: fcn,
71 | Args: tempArgs,
72 | TransientMap: nil,
73 | InvocationChain: nil,
74 | }
75 | //log.Println("cc exec request:",qrequest.ChaincodeID,"\t",qrequest.Fcn,"\t",qrequest.Args)
76 | response, err := channelClient.Execute(qrequest)
77 | if err != nil {
78 | return nil, err
79 | }
80 | return response.Payload, nil
81 | }
82 |
83 | func CCquery(channelClient *channel.Client, ccname, fcn string, args []string) ([]byte, error) {
84 | var tempArgs [][]byte
85 | if args == nil {
86 | tempArgs = nil
87 | } else {
88 | for i := 0; i < len(args); i++ {
89 | tempArgs = append(tempArgs, []byte(args[i]))
90 | }
91 | }
92 | qrequest := channel.Request{
93 | ChaincodeID: ccname,
94 | Fcn: fcn,
95 | Args: tempArgs,
96 | TransientMap: nil,
97 | InvocationChain: nil,
98 | }
99 | response, err := channelClient.Query(qrequest)
100 | if err != nil {
101 | return nil, err
102 | }
103 | return response.Payload, nil
104 | }
105 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/ccservice/ccestatebook.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package ccservice
18 |
19 | import (
20 | "comm"
21 | "encoding/json"
22 | )
23 |
24 | type CEstateBook struct {
25 | BookID string `json:"bookid"` //不动产证书编号
26 | Owner string `json:"owner"` //户主
27 | Addr string `json:"addr"` //房屋地址
28 | Area int `json:"area"` //房屋面积
29 | }
30 |
31 | func EstateBookCreate(uuid, bookid, owener, addr, area string) (res comm.ResResult) {
32 | cclient = GetChannelClient()
33 | if cclient == nil {
34 | res.Code = 1
35 | res.Status = "Chaincode service uninitialed."
36 | return
37 | }
38 | //check if bookid exist
39 | res = EstateBookQueryByBookid(bookid)
40 | if res.Code > 0 {
41 | return
42 | }
43 | ns := res.Status.([]CEstateBook)
44 | if len(ns) > 0 {
45 | res.Code = 1
46 | res.Status = bookid + " already exited!"
47 | return
48 | }
49 | //new
50 | bs, err := CCinvoke(cclient, ccEstateBook, "create",
51 | []string{uuid, bookid, owener, addr, area})
52 | if err != nil {
53 | res.Code = 1
54 | res.Status = err.Error()
55 | } else {
56 | res.Code = 0
57 | res.Status = string(bs)
58 | }
59 | return
60 | }
61 |
62 | func EstateBookQueryByBookid(bookid string) (res comm.ResResult) {
63 | cclient = GetChannelClient()
64 | if cclient == nil {
65 | res.Code = 1
66 | res.Status = "Chaincode service uninitialed."
67 | return
68 | }
69 | bs, err := CCquery(cclient, ccEstateBook, "queryByBookID", []string{bookid})
70 | if err != nil {
71 | res.Code = 1
72 | res.Status = err.Error()
73 | } else {
74 | res.Code = 0
75 | str := string(bs)
76 | var books []CEstateBook
77 | err = json.Unmarshal([]byte(str), &books)
78 | if err != nil {
79 | res.Code = 1
80 | res.Status = err.Error()
81 | } else {
82 | res.Status = books
83 | }
84 | }
85 | return
86 | }
87 |
88 | func EstateBookQueryAll() (res comm.ResResult) {
89 | cclient = GetChannelClient()
90 | if cclient == nil {
91 | res.Code = 1
92 | res.Status = "Chaincode service uninitialed."
93 | return
94 | }
95 | bs, err := CCquery(cclient, ccEstateBook, "queryAll", nil)
96 | if err != nil {
97 | res.Code = 1
98 | res.Status = err.Error()
99 | } else {
100 | res.Code = 0
101 | str := string(bs)
102 | var cs []CEstateBook
103 | err = json.Unmarshal([]byte(str), &cs)
104 | if err != nil {
105 | res.Code = 1
106 | res.Status = err.Error()
107 | } else {
108 | res.Status = cs
109 | }
110 | }
111 | return
112 | }
113 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/ccservice/ccestatetax.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package ccservice
18 |
19 | import (
20 | "comm"
21 | "encoding/json"
22 | )
23 |
24 | type CEstateTax struct {
25 | TaxID string `json:"taxid"` //核税编号
26 | BookID string `json:"bookid"` //不动产权证书编号
27 | Taxer string `json:"taxer"` //纳税人
28 | Area int `json:"area"` //房屋面积
29 | Tax int `json:"tax"` //纳税金额
30 | }
31 |
32 | func EstateTaxCreate(uuid, taxid, bookid, taxer, area, tax string) (res comm.ResResult) {
33 | cclient = GetChannelClient()
34 | if cclient == nil {
35 | res.Code = 1
36 | res.Status = "Chaincode service uninitialed."
37 | return
38 | }
39 | //check if taxid exist
40 | res = EstateTaxQueryByTaxid(taxid)
41 | if res.Code >0 {
42 | return
43 | }
44 | ns:=res.Status.([]CEstateTax)
45 | if len(ns)>0 {
46 | res.Code = 1
47 | res.Status = taxid+" already exited!"
48 | return
49 | }
50 | bs, err := CCinvoke(cclient, ccEstatetax, "create",
51 | []string{uuid, taxid, bookid, taxer, area, tax})
52 | if err != nil {
53 | res.Code = 1
54 | res.Status = err.Error()
55 | } else {
56 | res.Code = 0
57 | res.Status = string(bs)
58 | }
59 | return
60 | }
61 |
62 | func EstateTaxQueryByTaxid(taxid string) (res comm.ResResult) {
63 | cclient = GetChannelClient()
64 | if cclient == nil {
65 | res.Code = 1
66 | res.Status = "Chaincode service uninitialed."
67 | return
68 | }
69 | bs, err := CCquery(cclient, ccEstatetax, "queryByTaxID", []string{taxid})
70 | if err != nil {
71 | res.Code = 1
72 | res.Status = err.Error()
73 | } else {
74 | res.Code = 0
75 | str := string(bs)
76 | var cs []CEstateTax
77 | err = json.Unmarshal([]byte(str), &cs)
78 | if err != nil {
79 | res.Code = 1
80 | res.Status = err.Error()
81 | } else {
82 | res.Status = cs
83 | }
84 | }
85 | return
86 | }
87 |
88 | func EstateTaxQueryAll() (res comm.ResResult) {
89 | cclient = GetChannelClient()
90 | if cclient == nil {
91 | res.Code = 1
92 | res.Status = "Chaincode service uninitialed."
93 | return
94 | }
95 | bs, err := CCquery(cclient, ccEstatetax, "queryAll", nil)
96 | if err != nil {
97 | res.Code = 1
98 | res.Status = err.Error()
99 | } else {
100 | res.Code = 0
101 | str := string(bs)
102 | var cs []CEstateTax
103 | err = json.Unmarshal([]byte(str), &cs)
104 | if err != nil {
105 | res.Code = 1
106 | res.Status = err.Error()
107 | } else {
108 | res.Status = cs
109 | }
110 | }
111 | return
112 | }
113 |
114 | func EstateTaxQueryAllid() (res comm.ResResult) {
115 | res = EstateTaxQueryAll()
116 | if res.Code == 0 {
117 | ids := []string{}
118 | for _, con := range res.Status.([]CEstateTax) {
119 | ids = append(ids, con.TaxID)
120 | }
121 | res.Status = ids
122 | }
123 | return
124 | }
125 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/ccservice/ccnetcon.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package ccservice
18 |
19 | import (
20 | "comm"
21 | "encoding/json"
22 | )
23 |
24 | type CNetcon struct {
25 | NetconID string `json:"netconid"` //合同编号
26 | ApplyA string `json:"applya"` //受让方(买方)
27 | ApplyB string `json:"applyb"` //转让方(卖方)
28 | Addr string `json:"addr"` //房屋地址
29 | Area int `json:"area"` //房屋面积
30 | Balance int `json:"balance"` //转让金额
31 | }
32 |
33 | func NetconCreate(uuid, netconid, applya, applyb, addr, area, balance string) (res comm.ResResult) {
34 | cclient = GetChannelClient()
35 | if cclient == nil {
36 | res.Code = 1
37 | res.Status = "Chaincode service uninitialed."
38 | return
39 | }
40 | //check if netconid exist
41 | res = NetconQueryByNetconid(netconid)
42 | if res.Code >0 {
43 | return
44 | }
45 | ns:=res.Status.([]CNetcon)
46 | if len(ns)>0 {
47 | res.Code = 1
48 | res.Status = netconid+" already exited!"
49 | return
50 | }
51 | //new
52 | bs, err := CCinvoke(cclient, ccNetcon, "create",
53 | []string{uuid, netconid, applya, applyb, addr, area, balance})
54 | if err != nil {
55 | res.Code = 1
56 | res.Status = err.Error()
57 | } else {
58 | res.Code = 0
59 | res.Status = string(bs)
60 | }
61 | return
62 | }
63 |
64 | func NetconQueryByNetconid(netconid string) (res comm.ResResult) {
65 | cclient = GetChannelClient()
66 | if cclient == nil {
67 | res.Code = 1
68 | res.Status = "Chaincode service uninitialed."
69 | return
70 | }
71 | bs, err := CCquery(cclient, ccNetcon, "queryByNetconID", []string{netconid})
72 | if err != nil {
73 | res.Code = 1
74 | res.Status = err.Error()
75 | } else {
76 | res.Code = 0
77 | //res.Status = string(bs)
78 | str := string(bs)
79 | var ns []CNetcon
80 | err = json.Unmarshal([]byte(str), &ns)
81 | if err != nil {
82 | res.Code = 1
83 | res.Status = err.Error()
84 | } else {
85 | res.Status = ns
86 | }
87 | }
88 | return
89 | }
90 |
91 | func NetconQueryAll() (res comm.ResResult) {
92 | cclient = GetChannelClient()
93 | if cclient == nil {
94 | res.Code = 1
95 | res.Status = "Chaincode service uninitialed."
96 | return
97 | }
98 | bs, err := CCquery(cclient, ccNetcon, "queryAll", nil)
99 | if err != nil {
100 | res.Code = 1
101 | res.Status = err.Error()
102 | } else {
103 | res.Code = 0
104 | str := string(bs)
105 | var cs []CNetcon
106 | err = json.Unmarshal([]byte(str), &cs)
107 | if err != nil {
108 | res.Code = 1
109 | res.Status = err.Error()
110 | }else {
111 | res.Status = cs
112 | }
113 | }
114 | return
115 | }
116 |
117 | func NetconGetAllCCid() (res comm.ResResult) {
118 | res = NetconQueryAll()
119 | if res.Code == 0 {
120 | ids := []string{}
121 | for _, con := range res.Status.([]CNetcon) {
122 | ids = append(ids, con.NetconID)
123 | }
124 | res.Status = ids
125 | }
126 | return
127 | }
--------------------------------------------------------------------------------
/appcode/fccserver/src/ccservice/common.go:
--------------------------------------------------------------------------------
1 | package ccservice
2 |
3 | import (
4 | "errors"
5 | "github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
6 | "github.com/hyperledger/fabric-sdk-go/pkg/core/config"
7 | "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
8 | )
9 |
10 | var (
11 | ccFile = "./config_test.yaml"
12 | userName = "User1"
13 | orgName = "Org1"
14 | channelName = "mychannel"
15 | ccNetcon = "netcon"
16 | ccEstateBook = "estatebook"
17 | ccEstatetax = "estatetax"
18 | )
19 |
20 | var sdk *fabsdk.FabricSDK
21 | var cclient *channel.Client
22 |
23 | func GetSDK() (*fabsdk.FabricSDK, error) {
24 | if sdk != nil {
25 | return sdk, nil
26 | }
27 | sdk, err := fabsdk.New(config.FromFile(ccFile))
28 | if err != nil {
29 | return nil, err
30 | }
31 | return sdk, nil
32 | }
33 |
34 | func GetChannelClient() (*channel.Client, error) {
35 | if cclient != nil {
36 | return cclient, nil
37 | }
38 | sdk, err := GetSDK()
39 | if err != nil {
40 | return nil, err
41 | }
42 | clientContext := sdk.ChannelContext(channelName, fabsdk.WithUser(userName), fabsdk.WithOrg(orgName))
43 | if clientContext == nil {
44 | return nil, errors.New("get clientContext failed!")
45 | }
46 | cclient, err = channel.New(clientContext)
47 | return cclient, err
48 | }
49 |
50 | func CCinvoke(channelClient *channel.Client, ccname, fcn string, args []string) ([]byte, error) {
51 | var tempArgs [][]byte
52 | for i := 0; i < len(args); i++ {
53 | tempArgs = append(tempArgs, []byte(args[i]))
54 | }
55 | qrequest := channel.Request{
56 | ChaincodeID: ccname,
57 | Fcn: fcn,
58 | Args: tempArgs,
59 | TransientMap: nil,
60 | InvocationChain: nil,
61 | }
62 | response, err := channelClient.Execute(qrequest)
63 | if err != nil {
64 | return nil, err
65 | }
66 | return response.Payload, nil
67 | }
68 |
69 | func CCquery(channelClient *channel.Client, ccname, fcn string, args []string) ([]byte, error) {
70 | var tempArgs [][]byte
71 | if args == nil {
72 | tempArgs = nil
73 | } else {
74 | for i := 0; i < len(args); i++ {
75 | tempArgs = append(tempArgs, []byte(args[i]))
76 | }
77 | }
78 | qrequest := channel.Request{
79 | ChaincodeID: ccname,
80 | Fcn: fcn,
81 | Args: tempArgs,
82 | TransientMap: nil,
83 | InvocationChain: nil,
84 | }
85 | response, err := channelClient.Query(qrequest)
86 | if err != nil {
87 | return nil, err
88 | }
89 | return response.Payload, nil
90 | }
91 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/comm/webcomm.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package comm
18 |
19 | type ResResult struct {
20 | Code int
21 | Status interface{}
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/config.yaml:
--------------------------------------------------------------------------------
1 | version: 1.1.0
2 |
3 | client:
4 | organization: org1
5 |
6 | logging:
7 | level: info
8 |
9 | cryptoconfig:
10 | path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto
11 | credentialStore:
12 | path: /tmp/state-store
13 | cryptoStore:
14 | path: /tmp/msp
15 |
16 | BCCSP:
17 | security:
18 | enabled: true
19 | default:
20 | provider: "SW"
21 | hashAlgorithm: "SHA2"
22 | softVerify: true
23 | level: 256
24 |
25 | tlsCerts:
26 | systemCertPool: true
27 | client:
28 | keyfile: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/tls/client.key
29 | certfile: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/tls/client.crt
30 |
31 | channels:
32 | _default:
33 | peers:
34 | peer0.org1.example.com:
35 | endorsingPeer: true
36 | chaincodeQuery: true
37 | ledgerQuery: true
38 | eventSource: true
39 | peer0.org2.example.com:
40 | endorsingPeer: true
41 | chaincodeQuery: true
42 | ledgerQuery: true
43 | eventSource: true
44 | peer0.org3.example.com:
45 | endorsingPeer: true
46 | chaincodeQuery: true
47 | ledgerQuery: true
48 | eventSource: true
49 | policies:
50 | queryChannelConfig:
51 | minResponses: 1
52 | maxTargets: 1
53 | retryOpts:
54 | attempts: 5
55 | initialBackoff: 500ms
56 | maxBackoff: 5s
57 | backoffFactor: 2.0
58 | selection:
59 | SortingStrategy: BlockHeightPriority
60 | Balancer: RoundRobin
61 | BlockHeightLagThreshold: 5
62 | eventService:
63 | resolverStrategy: MinBlockHeight
64 | balancer: RoundRobin
65 | blockHeightLagThreshold: 4
66 | reconnectBlockHeightLagThreshold: 8
67 | peerMonitorPeriod: 6s
68 |
69 | mychannel:
70 | # orderers:
71 | # - orderer.example.com
72 |
73 | peers:
74 | peer0.org1.example.com:
75 | # peer1.org1.example.com:
76 | peer0.org2.example.com:
77 | # peer1.org2.example.com:
78 | peer0.org3.example.com:
79 | # peer1.org3.example.com:
80 |
81 |
82 |
83 | organizations:
84 | org1:
85 | mspid: Org1MSP
86 | cryptoPath: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp
87 | peers:
88 | - peer0.org1.example.com
89 | - peer1.org1.example.com
90 |
91 | org2:
92 | mspid: Org2MSP
93 | cryptoPath: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp
94 | peers:
95 | - peer0.org2.example.com
96 | - peer1.org2.example.com
97 |
98 | org3:
99 | mspid: Org3MSP
100 | cryptoPath: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/User1@org3.example.com/msp
101 | peers:
102 | - peer0.org3.example.com
103 | - peer1.org3.example.com
104 | # certificateAuthorities:
105 | # - ca.org2.example.com
106 |
107 | # Orderer Org name
108 | ordererorg:
109 | mspID: OrdererMSP
110 | cryptoPath: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/User1@example.com/msp/
111 |
112 | orderers:
113 | orderer.example.com:
114 | url: orderer.example.com:7050
115 | grpcOptions:
116 | ssl-target-name-override: orderer.example.com
117 | keep-alive-time: 0s
118 | keep-alive-timeout: 20s
119 | keep-alive-permit: false
120 | fail-fast: false
121 | allow-insecure: false
122 |
123 | tlsCACerts:
124 | path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem
125 |
126 | peers:
127 | _default:
128 | grpcOptions:
129 | keep-alive-time: 0s
130 | keep-alive-timeout: 20s
131 | keep-alive-permit: false
132 | fail-fast: false
133 | allow-insecure: false
134 |
135 | peer0.org1.example.com:
136 | url: peer0.org1.example.com:7051
137 | grpcOptions:
138 | ssl-target-name-override: peer0.org1.example.com
139 | tlsCACerts:
140 | path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
141 |
142 | peer1.org1.example.com:
143 | url: peer1.org1.example.com:8051
144 | grpcOptions:
145 | ssl-target-name-override: peer1.org1.example.com
146 | tlsCACerts:
147 | path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
148 |
149 | peer0.org2.example.com:
150 | url: peer0.org2.example.com:9051
151 | grpcOptions:
152 | ssl-target-name-override: peer0.org2.example.com
153 | tlsCACerts:
154 | path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem
155 |
156 | peer1.org2.example.com:
157 | url: peer1.org2.example.com:10051
158 | grpcOptions:
159 | ssl-target-name-override: peer1.org2.example.com
160 | tlsCACerts:
161 | path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem
162 |
163 | peer0.org3.example.com:
164 | url: peer0.org3.example.com:11051
165 | grpcOptions:
166 | ssl-target-name-override: peer0.org3.example.com
167 | tlsCACerts:
168 | path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem
169 |
170 | peer1.org3.example.com:
171 | url: peer1.org3.example.com:12051
172 | grpcOptions:
173 | ssl-target-name-override: peer1.org3.example.com
174 | tlsCACerts:
175 | path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem
176 |
177 |
178 | entityMatchers:
179 | orderer:
180 | - pattern: orderer(\w*).example.com:(\w*)
181 | urlSubstitutionExp: orderer${1}.example.com:${2}
182 | sslTargetOverrideUrlSubstitutionExp: orderer${1}.example.com
183 | mappedHost: orderer${1}.example.com
184 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/db/dbservice.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package db
18 |
19 | import (
20 | "github.com/go-xorm/xorm"
21 | _ "github.com/mattn/go-sqlite3"
22 | "log"
23 | "time"
24 | )
25 |
26 | var dbfile = "./server.db"
27 | var engins map[string]*xorm.Engine = make(map[string]*xorm.Engine)
28 |
29 | func SetEngin(orm *xorm.Engine, keys ...string) {
30 | if len(keys) == 0 {
31 | engins["default"] = orm
32 | } else {
33 | engins[keys[0]] = orm
34 | }
35 | }
36 |
37 | func GetEngin(keys ...string) (e *xorm.Engine) {
38 | if len(keys) == 0 {
39 | return engins["default"]
40 | } else {
41 | return engins[keys[0]]
42 | }
43 | }
44 |
45 | func InitDB() error {
46 | //init dabase
47 | orm, err := xorm.NewEngine("sqlite3", dbfile)
48 | if err != nil {
49 | log.Println("error on init db file:", err.Error())
50 | return err
51 | }
52 | orm.DatabaseTZ = time.Local //
53 | orm.TZLocation = time.Local //
54 | orm.SetMaxIdleConns(10)
55 | orm.SetMaxOpenConns(30)
56 | orm.ShowSQL(false)
57 | SetEngin(orm)
58 |
59 | //init tables
60 | err = initTables(orm)
61 | if err != nil {
62 | log.Println("system db error:", err.Error())
63 | } else {
64 | log.Println("system db initiated successfully.")
65 | }
66 | return err
67 | }
68 |
69 | func initTables(orm *xorm.Engine) (err error) {
70 |
71 | //create tables if not exits
72 | err = orm.CreateTables(
73 | &Netcon{},
74 | &EstateBook{},
75 | &EstateTax{},
76 | )
77 | return
78 | }
79 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/db/tbservice.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package db
18 |
19 | import (
20 | "log"
21 | "strconv"
22 | "time"
23 | )
24 |
25 | type Netcon struct {
26 | ID string `xorm:"pk 'id'"`
27 | CreateDT time.Time //生成时间
28 | NetconID string //合同编号
29 | ApplyA string //受让方(买方)
30 | ApplyB string //转让方(卖方)
31 | Addr string //房屋地址
32 | Area int //房屋面积
33 | Balance int //转让金额
34 | Operator string //操作人员
35 | IsCCed int //是否已上链
36 | }
37 |
38 | type EstateTax struct {
39 | ID string `xorm:"pk 'id'"`
40 | CreateDT time.Time //生成时间
41 | TaxID string //核税编号
42 | BookID string //不动产权证书编号
43 | Taxer string //纳税人
44 | Area int //房屋面积
45 | Tax int //纳税金额
46 | Operator string //操作人员
47 | IsCCed int //是否已上链
48 | }
49 |
50 | type EstateBook struct {
51 | ID string `xorm:"pk 'id'"`
52 | CreateDT time.Time //生成时间
53 | BookID string //不动产证书编号
54 | NetconID string //网签合同编号
55 | TaxID string //纳税凭证编号
56 | Owner string //户主
57 | Addr string //房屋地址
58 | Area int //房屋面积
59 | Operator string //操作人员
60 | IsCCed int //是否已上链
61 | }
62 |
63 | func NetconsAll() (netcons []Netcon, err error) {
64 | err = GetEngin().Find(&netcons)
65 | if err != nil {
66 | log.Println(err)
67 | }
68 | return
69 | }
70 |
71 | func NetconsCreate(netconid, applya, applyb, addr string, area, balance int, operator string) error {
72 | netcon := Netcon{
73 | ID: strconv.FormatInt(time.Now().Unix(), 10),
74 | CreateDT: time.Now(),
75 | NetconID: netconid,
76 | ApplyA: applya,
77 | ApplyB: applyb,
78 | Addr: addr,
79 | Area: area,
80 | Balance: balance,
81 | Operator: operator,
82 | }
83 | _, err := GetEngin().Insert(&netcon)
84 | return err
85 | }
86 |
87 | func NetconsUpdateCC(uuid string, iscced int) (err error) {
88 | netcon := &Netcon{}
89 | ok, err := GetEngin().ID(uuid).Get(netcon)
90 | if ok {
91 | netcon.IsCCed = iscced
92 | _, err = GetEngin().ID(uuid).Cols("is_c_ced").Update(netcon)
93 | }
94 | return
95 | }
96 |
97 | func EstateBookAll() (books []EstateBook, err error) {
98 | err = GetEngin().Find(&books)
99 | if err != nil {
100 | log.Println("error on EstateBookAll:", err.Error())
101 | }
102 | return
103 | }
104 |
105 | func EstateBookCreate(bookid, netconid, taxid, owner, addr string, area int, operator string) error {
106 | book := EstateBook{
107 | ID: strconv.FormatInt(time.Now().Unix(), 10),
108 | CreateDT: time.Now(),
109 | BookID: bookid,
110 | NetconID: netconid,
111 | TaxID: taxid,
112 | Owner: owner,
113 | Addr: addr,
114 | Area: area,
115 | Operator: operator,
116 | }
117 | _, err := GetEngin().Insert(&book)
118 | return err
119 | }
120 |
121 | func EstateBookUpdateCC(uuid string, iscced int) (err error) {
122 | book := &EstateBook{}
123 | ok, err := GetEngin().ID(uuid).Get(book)
124 | if ok {
125 | book.IsCCed = iscced
126 | _, err = GetEngin().ID(book.ID).Cols("is_c_ced").Update(book)
127 | }
128 | return
129 | }
130 |
131 | func EstateTaxAll() (taxs []EstateTax, err error) {
132 | err = GetEngin().Find(&taxs)
133 | if err != nil {
134 | log.Println(err)
135 | }
136 | return
137 | }
138 |
139 | func EstateTaxCreate(taxid, taxer string, area, tax int, operator string) error {
140 | newtax := EstateTax{
141 | CreateDT: time.Now(),
142 | ID: strconv.FormatInt(time.Now().Unix(), 10),
143 | TaxID: taxid,
144 | //BookID: bookid,
145 | Taxer: taxer,
146 | Area: area,
147 | Tax: tax,
148 | Operator: operator,
149 | }
150 | _, err := GetEngin().Insert(&newtax)
151 | return err
152 | }
153 |
154 | func EstateTaxUpdateCC(uuid string, iscced int) (err error) {
155 | tax := &EstateTax{}
156 | ok, err := GetEngin().ID(uuid).Get(tax)
157 | if ok {
158 | tax.IsCCed = iscced
159 | _, err = GetEngin().ID(tax.ID).Cols("is_c_ced").Update(tax)
160 | }
161 | return
162 | }
163 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/fccserver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fengzxu/fcc/aa2c77e2e2cfc650d30f4b9c432d2035517db545/appcode/fccserver/src/fccserver
--------------------------------------------------------------------------------
/appcode/fccserver/src/fccserver.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package main
18 |
19 | import (
20 | "github.com/gin-gonic/gin"
21 | "log"
22 | "middleware"
23 | "net/http"
24 | "routers"
25 | "service"
26 | "time"
27 | )
28 |
29 | func main() {
30 | //initlog()
31 |
32 | log.SetPrefix("[fcc-server] ")
33 | //init system
34 | err := service.InitOnSystemStart()
35 | if err != nil {
36 | log.Println("error on init system:", err.Error())
37 | return
38 | }
39 | //init http
40 | inithttp()
41 | //println("service started.")
42 | }
43 |
44 | func inithttp() {
45 | gin.SetMode(gin.ReleaseMode)
46 | app := gin.New()
47 | // recover
48 | app.Use(middleware.RecoveryMiddleware())
49 |
50 | // routers
51 | routers.RegisterRouter(app)
52 |
53 | //go initHTTPServer(app)
54 | initHTTPServer(app)
55 |
56 | }
57 |
58 | func initHTTPServer(handler http.Handler) {
59 | port := ":1206"
60 | srv := &http.Server{
61 | Addr: port,
62 | Handler: handler,
63 | ReadTimeout: 30 * time.Second,
64 | WriteTimeout: 10 * time.Second,
65 | IdleTimeout: 15 * time.Second,
66 | }
67 | log.Println("Server started on ", srv.Addr)
68 | srv.ListenAndServe()
69 | }
70 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/middleware/middleware.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package middleware
18 |
19 | import (
20 | "comm"
21 | "github.com/gin-gonic/gin"
22 | )
23 |
24 | // RecoveryMiddleware
25 | func RecoveryMiddleware() gin.HandlerFunc {
26 | return func(c *gin.Context) {
27 | defer func() {
28 | if err := recover(); err != nil {
29 | c.JSON(500, comm.ResResult{
30 | Code: 1,
31 | Status: "interal error.",
32 | })
33 | c.Abort()
34 | return
35 | }
36 | }()
37 | c.Next()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/routers/router.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package routers
18 |
19 | import (
20 | "ccservice"
21 | "github.com/gin-gonic/gin"
22 | "service"
23 | "strconv"
24 | )
25 |
26 | func RegisterRouter(app *gin.Engine) {
27 | //public frontend files
28 | //app.StaticFS("/html", http.Dir("public"))
29 |
30 | //registe all route path
31 | registerPath(app)
32 | }
33 |
34 | func registerPath(app *gin.Engine) {
35 |
36 | //root
37 | app.GET("/", func(c *gin.Context) {
38 | c.JSON(200, "fcc server.")
39 | })
40 | app.GET("/api", func(c *gin.Context) {
41 | c.JSON(200, "fcc api server.")
42 | })
43 |
44 | //netcon
45 | preNetcon := app.Group("/api/netcon")
46 | preNetcon.POST("/create", func(c *gin.Context) {
47 | netconid := c.PostForm("netconid")
48 | applya := c.PostForm("applya")
49 | applyb := c.PostForm("applyb")
50 | addr := c.PostForm("addr")
51 | area, _ := strconv.Atoi(c.DefaultPostForm("area", "0"))
52 | balance, _ := strconv.Atoi(c.DefaultPostForm("balance", "0"))
53 | c.JSON(200, service.NetconCreate(netconid, applya, applyb, addr, area, balance))
54 | })
55 | preNetcon.POST("/tocc", func(c *gin.Context) {
56 | uuid := c.PostForm("uuid")
57 | netconid := c.PostForm("netconid")
58 | applya := c.PostForm("applya")
59 | applyb := c.PostForm("applyb")
60 | addr := c.PostForm("addr")
61 | area := c.PostForm("area")
62 | balance := c.PostForm("balance")
63 | c.JSON(200, service.NetconToCC(uuid, netconid, applya, applyb, addr, area, balance))
64 | })
65 | preNetcon.GET("/queryall", func(c *gin.Context) {
66 | c.JSON(200, service.NetconGetAll())
67 | })
68 |
69 | //cc-netcon
70 | preCCNetcon := app.Group("/api/cc/netcon")
71 | preCCNetcon.GET("/querybynetconid", func(c *gin.Context) {
72 | netconid := c.Query("netconid")
73 | c.JSON(200, ccservice.NetconQueryByNetconid(netconid))
74 | })
75 | preCCNetcon.GET("/queryall", func(c *gin.Context) {
76 | c.JSON(200, ccservice.NetconQueryAll())
77 | })
78 | preCCNetcon.GET("/queryallid", func(c *gin.Context) {
79 | c.JSON(200, ccservice.NetconGetAllCCid())
80 | })
81 |
82 | //estatebook
83 | preEstatebook := app.Group("/api/estatebook")
84 | preEstatebook.POST("/create", func(c *gin.Context) {
85 | bookid := c.PostForm("bookid")
86 | netconid := c.PostForm("netconid")
87 | taxid := c.PostForm("taxid")
88 | owner := c.PostForm("owner")
89 | addr := c.PostForm("addr")
90 | area, _ := strconv.Atoi(c.DefaultPostForm("area", "0"))
91 | c.JSON(200, service.EstateBookCreate(bookid, netconid, taxid, owner, addr, area))
92 | })
93 | preEstatebook.GET("/queryall", func(c *gin.Context) {
94 | c.JSON(200, service.EstateBookGetAll())
95 | })
96 | preEstatebook.POST("/tocc", func(c *gin.Context) {
97 | uuid := c.PostForm("uuid")
98 | bookid := c.PostForm("bookid")
99 | owner := c.PostForm("owner")
100 | area := c.PostForm("area")
101 | addr := c.PostForm("addr")
102 | c.JSON(200, service.EstateBookToCC(uuid, bookid, owner, addr, area))
103 | })
104 |
105 | //cc-estatebook
106 | preCCEstatebook := app.Group("/api/cc/estatebook")
107 | preCCEstatebook.GET("/querybybookid", func(c *gin.Context) {
108 | bookid := c.Query("bookid")
109 | c.JSON(200, ccservice.EstateBookQueryByBookid(bookid))
110 | })
111 | preCCEstatebook.GET("/queryall", func(c *gin.Context) {
112 | c.JSON(200, ccservice.EstateBookQueryAll())
113 | })
114 |
115 | //estatetax
116 | preEstatetax := app.Group("/api/estatetax")
117 | preEstatetax.POST("/create", func(c *gin.Context) {
118 | taxid := c.PostForm("taxid")
119 | taxer := c.PostForm("taxer")
120 | area, _ := strconv.Atoi(c.DefaultPostForm("area", "0"))
121 | tax, _ := strconv.Atoi(c.DefaultPostForm("tax", "0"))
122 | c.JSON(200, service.EstateTaxCreate(taxid, taxer, area, tax))
123 | })
124 | preEstatetax.POST("/tocc", func(c *gin.Context) {
125 | uuid := c.PostForm("uuid")
126 | taxid := c.PostForm("taxid")
127 | taxer := c.PostForm("taxer")
128 | area := c.PostForm("area")
129 | tax := c.PostForm("tax")
130 | c.JSON(200, service.EstateTaxToCC(uuid, taxid, taxer, area, tax))
131 | })
132 | preEstatetax.GET("/queryall", func(c *gin.Context) {
133 | c.JSON(200, service.EstateTaxGetAll())
134 | })
135 |
136 | //cc-estatetax
137 | preCCEstatetax := app.Group("/api/cc/estatetax")
138 | preCCEstatetax.GET("/querybytaxid", func(c *gin.Context) {
139 | taxid := c.Query("taxid")
140 | c.JSON(200, ccservice.EstateTaxQueryByTaxid(taxid))
141 | })
142 | preCCEstatetax.GET("/queryall", func(c *gin.Context) {
143 | c.JSON(200, ccservice.EstateTaxQueryAll())
144 | })
145 | preCCEstatetax.GET("/queryallid", func(c *gin.Context) {
146 | c.JSON(200, ccservice.EstateTaxQueryAllid())
147 | })
148 | }
149 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/service/cast.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import "time"
4 |
5 | // ToBool casts an interface to a bool type.
6 | func ToBool(i interface{}) bool {
7 | v, _ := ToBoolE(i)
8 | return v
9 | }
10 |
11 | // ToTime casts an interface to a time.Time type.
12 | func ToTime(i interface{}) time.Time {
13 | v, _ := ToTimeE(i)
14 | return v
15 | }
16 |
17 | // ToDuration casts an interface to a time.Duration type.
18 | func ToDuration(i interface{}) time.Duration {
19 | v, _ := ToDurationE(i)
20 | return v
21 | }
22 |
23 | // ToFloat64 casts an interface to a float64 type.
24 | func ToFloat64(i interface{}) float64 {
25 | v, _ := ToFloat64E(i)
26 | return v
27 | }
28 |
29 | // ToFloat32 casts an interface to a float32 type.
30 | func ToFloat32(i interface{}) float32 {
31 | v, _ := ToFloat32E(i)
32 | return v
33 | }
34 |
35 | // ToInt64 casts an interface to an int64 type.
36 | func ToInt64(i interface{}) int64 {
37 | v, _ := ToInt64E(i)
38 | return v
39 | }
40 |
41 | // ToInt32 casts an interface to an int32 type.
42 | func ToInt32(i interface{}) int32 {
43 | v, _ := ToInt32E(i)
44 | return v
45 | }
46 |
47 | // ToInt16 casts an interface to an int16 type.
48 | func ToInt16(i interface{}) int16 {
49 | v, _ := ToInt16E(i)
50 | return v
51 | }
52 |
53 | // ToInt8 casts an interface to an int8 type.
54 | func ToInt8(i interface{}) int8 {
55 | v, _ := ToInt8E(i)
56 | return v
57 | }
58 |
59 | // ToInt casts an interface to an int type.
60 | func ToInt(i interface{}) int {
61 | v, _ := ToIntE(i)
62 | return v
63 | }
64 |
65 | // ToUint casts an interface to a uint type.
66 | func ToUint(i interface{}) uint {
67 | v, _ := ToUintE(i)
68 | return v
69 | }
70 |
71 | // ToUint64 casts an interface to a uint64 type.
72 | func ToUint64(i interface{}) uint64 {
73 | v, _ := ToUint64E(i)
74 | return v
75 | }
76 |
77 | // ToUint32 casts an interface to a uint32 type.
78 | func ToUint32(i interface{}) uint32 {
79 | v, _ := ToUint32E(i)
80 | return v
81 | }
82 |
83 | // ToUint16 casts an interface to a uint16 type.
84 | func ToUint16(i interface{}) uint16 {
85 | v, _ := ToUint16E(i)
86 | return v
87 | }
88 |
89 | // ToUint8 casts an interface to a uint8 type.
90 | func ToUint8(i interface{}) uint8 {
91 | v, _ := ToUint8E(i)
92 | return v
93 | }
94 |
95 | // ToString casts an interface to a string type.
96 | func ToString(i interface{}) string {
97 | v, _ := ToStringE(i)
98 | return v
99 | }
100 |
101 | // ToStringMapString casts an interface to a map[string]string type.
102 | func ToStringMapString(i interface{}) map[string]string {
103 | v, _ := ToStringMapStringE(i)
104 | return v
105 | }
106 |
107 | // ToStringMapStringSlice casts an interface to a map[string][]string type.
108 | func ToStringMapStringSlice(i interface{}) map[string][]string {
109 | v, _ := ToStringMapStringSliceE(i)
110 | return v
111 | }
112 |
113 | // ToStringMapBool casts an interface to a map[string]bool type.
114 | func ToStringMapBool(i interface{}) map[string]bool {
115 | v, _ := ToStringMapBoolE(i)
116 | return v
117 | }
118 |
119 | // ToStringMapInt casts an interface to a map[string]int type.
120 | func ToStringMapInt(i interface{}) map[string]int {
121 | v, _ := ToStringMapIntE(i)
122 | return v
123 | }
124 |
125 | // ToStringMapInt64 casts an interface to a map[string]int64 type.
126 | func ToStringMapInt64(i interface{}) map[string]int64 {
127 | v, _ := ToStringMapInt64E(i)
128 | return v
129 | }
130 |
131 | // ToStringMap casts an interface to a map[string]interface{} type.
132 | func ToStringMap(i interface{}) map[string]interface{} {
133 | v, _ := ToStringMapE(i)
134 | return v
135 | }
136 |
137 | // ToSlice casts an interface to a []interface{} type.
138 | func ToSlice(i interface{}) []interface{} {
139 | v, _ := ToSliceE(i)
140 | return v
141 | }
142 |
143 | // ToBoolSlice casts an interface to a []bool type.
144 | func ToBoolSlice(i interface{}) []bool {
145 | v, _ := ToBoolSliceE(i)
146 | return v
147 | }
148 |
149 | // ToStringSlice casts an interface to a []string type.
150 | func ToStringSlice(i interface{}) []string {
151 | v, _ := ToStringSliceE(i)
152 | return v
153 | }
154 |
155 | // ToIntSlice casts an interface to a []int type.
156 | func ToIntSlice(i interface{}) []int {
157 | v, _ := ToIntSliceE(i)
158 | return v
159 | }
160 |
161 | // ToDurationSlice casts an interface to a []time.Duration type.
162 | func ToDurationSlice(i interface{}) []time.Duration {
163 | v, _ := ToDurationSliceE(i)
164 | return v
165 | }
166 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/service/caste.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import (
4 | "encoding/json"
5 | "errors"
6 | "fmt"
7 | "html/template"
8 | "reflect"
9 | "strconv"
10 | "strings"
11 | "time"
12 | )
13 |
14 | var errNegativeNotAllowed = errors.New("unable to cast negative value")
15 |
16 | // ToTimeE casts an interface to a time.Time type.
17 | func ToTimeE(i interface{}) (tim time.Time, err error) {
18 | i = indirect(i)
19 |
20 | switch v := i.(type) {
21 | case time.Time:
22 | return v, nil
23 | case string:
24 | return StringToDate(v)
25 | case int:
26 | return time.Unix(int64(v), 0), nil
27 | case int64:
28 | return time.Unix(v, 0), nil
29 | case int32:
30 | return time.Unix(int64(v), 0), nil
31 | case uint:
32 | return time.Unix(int64(v), 0), nil
33 | case uint64:
34 | return time.Unix(int64(v), 0), nil
35 | case uint32:
36 | return time.Unix(int64(v), 0), nil
37 | default:
38 | return time.Time{}, fmt.Errorf("unable to cast %#v of type %T to Time", i, i)
39 | }
40 | }
41 |
42 | // ToDurationE casts an interface to a time.Duration type.
43 | func ToDurationE(i interface{}) (d time.Duration, err error) {
44 | i = indirect(i)
45 |
46 | switch s := i.(type) {
47 | case time.Duration:
48 | return s, nil
49 | case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
50 | d = time.Duration(ToInt64(s))
51 | return
52 | case float32, float64:
53 | d = time.Duration(ToFloat64(s))
54 | return
55 | case string:
56 | if strings.ContainsAny(s, "nsuµmh") {
57 | d, err = time.ParseDuration(s)
58 | } else {
59 | d, err = time.ParseDuration(s + "ns")
60 | }
61 | return
62 | default:
63 | err = fmt.Errorf("unable to cast %#v of type %T to Duration", i, i)
64 | return
65 | }
66 | }
67 |
68 | // ToBoolE casts an interface to a bool type.
69 | func ToBoolE(i interface{}) (bool, error) {
70 | i = indirect(i)
71 |
72 | switch b := i.(type) {
73 | case bool:
74 | return b, nil
75 | case nil:
76 | return false, nil
77 | case int:
78 | if i.(int) != 0 {
79 | return true, nil
80 | }
81 | return false, nil
82 | case string:
83 | return strconv.ParseBool(i.(string))
84 | default:
85 | return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
86 | }
87 | }
88 |
89 | // ToFloat64E casts an interface to a float64 type.
90 | func ToFloat64E(i interface{}) (float64, error) {
91 | i = indirect(i)
92 |
93 | switch s := i.(type) {
94 | case float64:
95 | return s, nil
96 | case float32:
97 | return float64(s), nil
98 | case int:
99 | return float64(s), nil
100 | case int64:
101 | return float64(s), nil
102 | case int32:
103 | return float64(s), nil
104 | case int16:
105 | return float64(s), nil
106 | case int8:
107 | return float64(s), nil
108 | case uint:
109 | return float64(s), nil
110 | case uint64:
111 | return float64(s), nil
112 | case uint32:
113 | return float64(s), nil
114 | case uint16:
115 | return float64(s), nil
116 | case uint8:
117 | return float64(s), nil
118 | case string:
119 | v, err := strconv.ParseFloat(s, 64)
120 | if err == nil {
121 | return v, nil
122 | }
123 | return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
124 | case bool:
125 | if s {
126 | return 1, nil
127 | }
128 | return 0, nil
129 | default:
130 | return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)
131 | }
132 | }
133 |
134 | // ToFloat32E casts an interface to a float32 type.
135 | func ToFloat32E(i interface{}) (float32, error) {
136 | i = indirect(i)
137 |
138 | switch s := i.(type) {
139 | case float64:
140 | return float32(s), nil
141 | case float32:
142 | return s, nil
143 | case int:
144 | return float32(s), nil
145 | case int64:
146 | return float32(s), nil
147 | case int32:
148 | return float32(s), nil
149 | case int16:
150 | return float32(s), nil
151 | case int8:
152 | return float32(s), nil
153 | case uint:
154 | return float32(s), nil
155 | case uint64:
156 | return float32(s), nil
157 | case uint32:
158 | return float32(s), nil
159 | case uint16:
160 | return float32(s), nil
161 | case uint8:
162 | return float32(s), nil
163 | case string:
164 | v, err := strconv.ParseFloat(s, 32)
165 | if err == nil {
166 | return float32(v), nil
167 | }
168 | return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
169 | case bool:
170 | if s {
171 | return 1, nil
172 | }
173 | return 0, nil
174 | default:
175 | return 0, fmt.Errorf("unable to cast %#v of type %T to float32", i, i)
176 | }
177 | }
178 |
179 | // ToInt64E casts an interface to an int64 type.
180 | func ToInt64E(i interface{}) (int64, error) {
181 | i = indirect(i)
182 |
183 | switch s := i.(type) {
184 | case int:
185 | return int64(s), nil
186 | case int64:
187 | return s, nil
188 | case int32:
189 | return int64(s), nil
190 | case int16:
191 | return int64(s), nil
192 | case int8:
193 | return int64(s), nil
194 | case uint:
195 | return int64(s), nil
196 | case uint64:
197 | return int64(s), nil
198 | case uint32:
199 | return int64(s), nil
200 | case uint16:
201 | return int64(s), nil
202 | case uint8:
203 | return int64(s), nil
204 | case float64:
205 | return int64(s), nil
206 | case float32:
207 | return int64(s), nil
208 | case string:
209 | v, err := strconv.ParseInt(s, 0, 0)
210 | if err == nil {
211 | return v, nil
212 | }
213 | return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
214 | case bool:
215 | if s {
216 | return 1, nil
217 | }
218 | return 0, nil
219 | case nil:
220 | return 0, nil
221 | default:
222 | return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
223 | }
224 | }
225 |
226 | // ToInt32E casts an interface to an int32 type.
227 | func ToInt32E(i interface{}) (int32, error) {
228 | i = indirect(i)
229 |
230 | switch s := i.(type) {
231 | case int:
232 | return int32(s), nil
233 | case int64:
234 | return int32(s), nil
235 | case int32:
236 | return s, nil
237 | case int16:
238 | return int32(s), nil
239 | case int8:
240 | return int32(s), nil
241 | case uint:
242 | return int32(s), nil
243 | case uint64:
244 | return int32(s), nil
245 | case uint32:
246 | return int32(s), nil
247 | case uint16:
248 | return int32(s), nil
249 | case uint8:
250 | return int32(s), nil
251 | case float64:
252 | return int32(s), nil
253 | case float32:
254 | return int32(s), nil
255 | case string:
256 | v, err := strconv.ParseInt(s, 0, 0)
257 | if err == nil {
258 | return int32(v), nil
259 | }
260 | return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
261 | case bool:
262 | if s {
263 | return 1, nil
264 | }
265 | return 0, nil
266 | case nil:
267 | return 0, nil
268 | default:
269 | return 0, fmt.Errorf("unable to cast %#v of type %T to int32", i, i)
270 | }
271 | }
272 |
273 | // ToInt16E casts an interface to an int16 type.
274 | func ToInt16E(i interface{}) (int16, error) {
275 | i = indirect(i)
276 |
277 | switch s := i.(type) {
278 | case int:
279 | return int16(s), nil
280 | case int64:
281 | return int16(s), nil
282 | case int32:
283 | return int16(s), nil
284 | case int16:
285 | return s, nil
286 | case int8:
287 | return int16(s), nil
288 | case uint:
289 | return int16(s), nil
290 | case uint64:
291 | return int16(s), nil
292 | case uint32:
293 | return int16(s), nil
294 | case uint16:
295 | return int16(s), nil
296 | case uint8:
297 | return int16(s), nil
298 | case float64:
299 | return int16(s), nil
300 | case float32:
301 | return int16(s), nil
302 | case string:
303 | v, err := strconv.ParseInt(s, 0, 0)
304 | if err == nil {
305 | return int16(v), nil
306 | }
307 | return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
308 | case bool:
309 | if s {
310 | return 1, nil
311 | }
312 | return 0, nil
313 | case nil:
314 | return 0, nil
315 | default:
316 | return 0, fmt.Errorf("unable to cast %#v of type %T to int16", i, i)
317 | }
318 | }
319 |
320 | // ToInt8E casts an interface to an int8 type.
321 | func ToInt8E(i interface{}) (int8, error) {
322 | i = indirect(i)
323 |
324 | switch s := i.(type) {
325 | case int:
326 | return int8(s), nil
327 | case int64:
328 | return int8(s), nil
329 | case int32:
330 | return int8(s), nil
331 | case int16:
332 | return int8(s), nil
333 | case int8:
334 | return s, nil
335 | case uint:
336 | return int8(s), nil
337 | case uint64:
338 | return int8(s), nil
339 | case uint32:
340 | return int8(s), nil
341 | case uint16:
342 | return int8(s), nil
343 | case uint8:
344 | return int8(s), nil
345 | case float64:
346 | return int8(s), nil
347 | case float32:
348 | return int8(s), nil
349 | case string:
350 | v, err := strconv.ParseInt(s, 0, 0)
351 | if err == nil {
352 | return int8(v), nil
353 | }
354 | return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
355 | case bool:
356 | if s {
357 | return 1, nil
358 | }
359 | return 0, nil
360 | case nil:
361 | return 0, nil
362 | default:
363 | return 0, fmt.Errorf("unable to cast %#v of type %T to int8", i, i)
364 | }
365 | }
366 |
367 | // ToIntE casts an interface to an int type.
368 | func ToIntE(i interface{}) (int, error) {
369 | i = indirect(i)
370 |
371 | switch s := i.(type) {
372 | case int:
373 | return s, nil
374 | case int64:
375 | return int(s), nil
376 | case int32:
377 | return int(s), nil
378 | case int16:
379 | return int(s), nil
380 | case int8:
381 | return int(s), nil
382 | case uint:
383 | return int(s), nil
384 | case uint64:
385 | return int(s), nil
386 | case uint32:
387 | return int(s), nil
388 | case uint16:
389 | return int(s), nil
390 | case uint8:
391 | return int(s), nil
392 | case float64:
393 | return int(s), nil
394 | case float32:
395 | return int(s), nil
396 | case string:
397 | v, err := strconv.ParseInt(s, 0, 0)
398 | if err == nil {
399 | return int(v), nil
400 | }
401 | return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
402 | case bool:
403 | if s {
404 | return 1, nil
405 | }
406 | return 0, nil
407 | case nil:
408 | return 0, nil
409 | default:
410 | return 0, fmt.Errorf("unable to cast %#v of type %T to int", i, i)
411 | }
412 | }
413 |
414 | // ToUintE casts an interface to a uint type.
415 | func ToUintE(i interface{}) (uint, error) {
416 | i = indirect(i)
417 |
418 | switch s := i.(type) {
419 | case string:
420 | v, err := strconv.ParseUint(s, 0, 0)
421 | if err == nil {
422 | return uint(v), nil
423 | }
424 | return 0, fmt.Errorf("unable to cast %#v to uint: %s", i, err)
425 | case int:
426 | if s < 0 {
427 | return 0, errNegativeNotAllowed
428 | }
429 | return uint(s), nil
430 | case int64:
431 | if s < 0 {
432 | return 0, errNegativeNotAllowed
433 | }
434 | return uint(s), nil
435 | case int32:
436 | if s < 0 {
437 | return 0, errNegativeNotAllowed
438 | }
439 | return uint(s), nil
440 | case int16:
441 | if s < 0 {
442 | return 0, errNegativeNotAllowed
443 | }
444 | return uint(s), nil
445 | case int8:
446 | if s < 0 {
447 | return 0, errNegativeNotAllowed
448 | }
449 | return uint(s), nil
450 | case uint:
451 | return s, nil
452 | case uint64:
453 | return uint(s), nil
454 | case uint32:
455 | return uint(s), nil
456 | case uint16:
457 | return uint(s), nil
458 | case uint8:
459 | return uint(s), nil
460 | case float64:
461 | if s < 0 {
462 | return 0, errNegativeNotAllowed
463 | }
464 | return uint(s), nil
465 | case float32:
466 | if s < 0 {
467 | return 0, errNegativeNotAllowed
468 | }
469 | return uint(s), nil
470 | case bool:
471 | if s {
472 | return 1, nil
473 | }
474 | return 0, nil
475 | case nil:
476 | return 0, nil
477 | default:
478 | return 0, fmt.Errorf("unable to cast %#v of type %T to uint", i, i)
479 | }
480 | }
481 |
482 | // ToUint64E casts an interface to a uint64 type.
483 | func ToUint64E(i interface{}) (uint64, error) {
484 | i = indirect(i)
485 |
486 | switch s := i.(type) {
487 | case string:
488 | v, err := strconv.ParseUint(s, 0, 64)
489 | if err == nil {
490 | return v, nil
491 | }
492 | return 0, fmt.Errorf("unable to cast %#v to uint64: %s", i, err)
493 | case int:
494 | if s < 0 {
495 | return 0, errNegativeNotAllowed
496 | }
497 | return uint64(s), nil
498 | case int64:
499 | if s < 0 {
500 | return 0, errNegativeNotAllowed
501 | }
502 | return uint64(s), nil
503 | case int32:
504 | if s < 0 {
505 | return 0, errNegativeNotAllowed
506 | }
507 | return uint64(s), nil
508 | case int16:
509 | if s < 0 {
510 | return 0, errNegativeNotAllowed
511 | }
512 | return uint64(s), nil
513 | case int8:
514 | if s < 0 {
515 | return 0, errNegativeNotAllowed
516 | }
517 | return uint64(s), nil
518 | case uint:
519 | return uint64(s), nil
520 | case uint64:
521 | return s, nil
522 | case uint32:
523 | return uint64(s), nil
524 | case uint16:
525 | return uint64(s), nil
526 | case uint8:
527 | return uint64(s), nil
528 | case float32:
529 | if s < 0 {
530 | return 0, errNegativeNotAllowed
531 | }
532 | return uint64(s), nil
533 | case float64:
534 | if s < 0 {
535 | return 0, errNegativeNotAllowed
536 | }
537 | return uint64(s), nil
538 | case bool:
539 | if s {
540 | return 1, nil
541 | }
542 | return 0, nil
543 | case nil:
544 | return 0, nil
545 | default:
546 | return 0, fmt.Errorf("unable to cast %#v of type %T to uint64", i, i)
547 | }
548 | }
549 |
550 | // ToUint32E casts an interface to a uint32 type.
551 | func ToUint32E(i interface{}) (uint32, error) {
552 | i = indirect(i)
553 |
554 | switch s := i.(type) {
555 | case string:
556 | v, err := strconv.ParseUint(s, 0, 32)
557 | if err == nil {
558 | return uint32(v), nil
559 | }
560 | return 0, fmt.Errorf("unable to cast %#v to uint32: %s", i, err)
561 | case int:
562 | if s < 0 {
563 | return 0, errNegativeNotAllowed
564 | }
565 | return uint32(s), nil
566 | case int64:
567 | if s < 0 {
568 | return 0, errNegativeNotAllowed
569 | }
570 | return uint32(s), nil
571 | case int32:
572 | if s < 0 {
573 | return 0, errNegativeNotAllowed
574 | }
575 | return uint32(s), nil
576 | case int16:
577 | if s < 0 {
578 | return 0, errNegativeNotAllowed
579 | }
580 | return uint32(s), nil
581 | case int8:
582 | if s < 0 {
583 | return 0, errNegativeNotAllowed
584 | }
585 | return uint32(s), nil
586 | case uint:
587 | return uint32(s), nil
588 | case uint64:
589 | return uint32(s), nil
590 | case uint32:
591 | return s, nil
592 | case uint16:
593 | return uint32(s), nil
594 | case uint8:
595 | return uint32(s), nil
596 | case float64:
597 | if s < 0 {
598 | return 0, errNegativeNotAllowed
599 | }
600 | return uint32(s), nil
601 | case float32:
602 | if s < 0 {
603 | return 0, errNegativeNotAllowed
604 | }
605 | return uint32(s), nil
606 | case bool:
607 | if s {
608 | return 1, nil
609 | }
610 | return 0, nil
611 | case nil:
612 | return 0, nil
613 | default:
614 | return 0, fmt.Errorf("unable to cast %#v of type %T to uint32", i, i)
615 | }
616 | }
617 |
618 | // ToUint16E casts an interface to a uint16 type.
619 | func ToUint16E(i interface{}) (uint16, error) {
620 | i = indirect(i)
621 |
622 | switch s := i.(type) {
623 | case string:
624 | v, err := strconv.ParseUint(s, 0, 16)
625 | if err == nil {
626 | return uint16(v), nil
627 | }
628 | return 0, fmt.Errorf("unable to cast %#v to uint16: %s", i, err)
629 | case int:
630 | if s < 0 {
631 | return 0, errNegativeNotAllowed
632 | }
633 | return uint16(s), nil
634 | case int64:
635 | if s < 0 {
636 | return 0, errNegativeNotAllowed
637 | }
638 | return uint16(s), nil
639 | case int32:
640 | if s < 0 {
641 | return 0, errNegativeNotAllowed
642 | }
643 | return uint16(s), nil
644 | case int16:
645 | if s < 0 {
646 | return 0, errNegativeNotAllowed
647 | }
648 | return uint16(s), nil
649 | case int8:
650 | if s < 0 {
651 | return 0, errNegativeNotAllowed
652 | }
653 | return uint16(s), nil
654 | case uint:
655 | return uint16(s), nil
656 | case uint64:
657 | return uint16(s), nil
658 | case uint32:
659 | return uint16(s), nil
660 | case uint16:
661 | return s, nil
662 | case uint8:
663 | return uint16(s), nil
664 | case float64:
665 | if s < 0 {
666 | return 0, errNegativeNotAllowed
667 | }
668 | return uint16(s), nil
669 | case float32:
670 | if s < 0 {
671 | return 0, errNegativeNotAllowed
672 | }
673 | return uint16(s), nil
674 | case bool:
675 | if s {
676 | return 1, nil
677 | }
678 | return 0, nil
679 | case nil:
680 | return 0, nil
681 | default:
682 | return 0, fmt.Errorf("unable to cast %#v of type %T to uint16", i, i)
683 | }
684 | }
685 |
686 | // ToUint8E casts an interface to a uint type.
687 | func ToUint8E(i interface{}) (uint8, error) {
688 | i = indirect(i)
689 |
690 | switch s := i.(type) {
691 | case string:
692 | v, err := strconv.ParseUint(s, 0, 8)
693 | if err == nil {
694 | return uint8(v), nil
695 | }
696 | return 0, fmt.Errorf("unable to cast %#v to uint8: %s", i, err)
697 | case int:
698 | if s < 0 {
699 | return 0, errNegativeNotAllowed
700 | }
701 | return uint8(s), nil
702 | case int64:
703 | if s < 0 {
704 | return 0, errNegativeNotAllowed
705 | }
706 | return uint8(s), nil
707 | case int32:
708 | if s < 0 {
709 | return 0, errNegativeNotAllowed
710 | }
711 | return uint8(s), nil
712 | case int16:
713 | if s < 0 {
714 | return 0, errNegativeNotAllowed
715 | }
716 | return uint8(s), nil
717 | case int8:
718 | if s < 0 {
719 | return 0, errNegativeNotAllowed
720 | }
721 | return uint8(s), nil
722 | case uint:
723 | return uint8(s), nil
724 | case uint64:
725 | return uint8(s), nil
726 | case uint32:
727 | return uint8(s), nil
728 | case uint16:
729 | return uint8(s), nil
730 | case uint8:
731 | return s, nil
732 | case float64:
733 | if s < 0 {
734 | return 0, errNegativeNotAllowed
735 | }
736 | return uint8(s), nil
737 | case float32:
738 | if s < 0 {
739 | return 0, errNegativeNotAllowed
740 | }
741 | return uint8(s), nil
742 | case bool:
743 | if s {
744 | return 1, nil
745 | }
746 | return 0, nil
747 | case nil:
748 | return 0, nil
749 | default:
750 | return 0, fmt.Errorf("unable to cast %#v of type %T to uint8", i, i)
751 | }
752 | }
753 |
754 | // From html/template/content.go
755 | // Copyright 2011 The Go Authors. All rights reserved.
756 | // indirect returns the value, after dereferencing as many times
757 | // as necessary to reach the base type (or nil).
758 | func indirect(a interface{}) interface{} {
759 | if a == nil {
760 | return nil
761 | }
762 | if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
763 | // Avoid creating a reflect.Value if it's not a pointer.
764 | return a
765 | }
766 | v := reflect.ValueOf(a)
767 | for v.Kind() == reflect.Ptr && !v.IsNil() {
768 | v = v.Elem()
769 | }
770 | return v.Interface()
771 | }
772 |
773 | // From html/template/content.go
774 | // Copyright 2011 The Go Authors. All rights reserved.
775 | // indirectToStringerOrError returns the value, after dereferencing as many times
776 | // as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
777 | // or error,
778 | func indirectToStringerOrError(a interface{}) interface{} {
779 | if a == nil {
780 | return nil
781 | }
782 |
783 | var errorType = reflect.TypeOf((*error)(nil)).Elem()
784 | var fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
785 |
786 | v := reflect.ValueOf(a)
787 | for !v.Type().Implements(fmtStringerType) && !v.Type().Implements(errorType) && v.Kind() == reflect.Ptr && !v.IsNil() {
788 | v = v.Elem()
789 | }
790 | return v.Interface()
791 | }
792 |
793 | // ToStringE casts an interface to a string type.
794 | func ToStringE(i interface{}) (string, error) {
795 | i = indirectToStringerOrError(i)
796 |
797 | switch s := i.(type) {
798 | case string:
799 | return s, nil
800 | case bool:
801 | return strconv.FormatBool(s), nil
802 | case float64:
803 | return strconv.FormatFloat(s, 'f', -1, 64), nil
804 | case float32:
805 | return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
806 | case int:
807 | return strconv.Itoa(s), nil
808 | case int64:
809 | return strconv.FormatInt(s, 10), nil
810 | case int32:
811 | return strconv.Itoa(int(s)), nil
812 | case int16:
813 | return strconv.FormatInt(int64(s), 10), nil
814 | case int8:
815 | return strconv.FormatInt(int64(s), 10), nil
816 | case uint:
817 | return strconv.FormatInt(int64(s), 10), nil
818 | case uint64:
819 | return strconv.FormatInt(int64(s), 10), nil
820 | case uint32:
821 | return strconv.FormatInt(int64(s), 10), nil
822 | case uint16:
823 | return strconv.FormatInt(int64(s), 10), nil
824 | case uint8:
825 | return strconv.FormatInt(int64(s), 10), nil
826 | case []byte:
827 | return string(s), nil
828 | case template.HTML:
829 | return string(s), nil
830 | case template.URL:
831 | return string(s), nil
832 | case template.JS:
833 | return string(s), nil
834 | case template.CSS:
835 | return string(s), nil
836 | case template.HTMLAttr:
837 | return string(s), nil
838 | case nil:
839 | return "", nil
840 | case fmt.Stringer:
841 | return s.String(), nil
842 | case error:
843 | return s.Error(), nil
844 | default:
845 | return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
846 | }
847 | }
848 |
849 | // ToStringMapStringE casts an interface to a map[string]string type.
850 | func ToStringMapStringE(i interface{}) (map[string]string, error) {
851 | var m = map[string]string{}
852 |
853 | switch v := i.(type) {
854 | case map[string]string:
855 | return v, nil
856 | case map[string]interface{}:
857 | for k, val := range v {
858 | m[ToString(k)] = ToString(val)
859 | }
860 | return m, nil
861 | case map[interface{}]string:
862 | for k, val := range v {
863 | m[ToString(k)] = ToString(val)
864 | }
865 | return m, nil
866 | case map[interface{}]interface{}:
867 | for k, val := range v {
868 | m[ToString(k)] = ToString(val)
869 | }
870 | return m, nil
871 | case string:
872 | err := jsonStringToObject(v, &m)
873 | return m, err
874 | default:
875 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]string", i, i)
876 | }
877 | }
878 |
879 | // ToStringMapStringSliceE casts an interface to a map[string][]string type.
880 | func ToStringMapStringSliceE(i interface{}) (map[string][]string, error) {
881 | var m = map[string][]string{}
882 |
883 | switch v := i.(type) {
884 | case map[string][]string:
885 | return v, nil
886 | case map[string][]interface{}:
887 | for k, val := range v {
888 | m[ToString(k)] = ToStringSlice(val)
889 | }
890 | return m, nil
891 | case map[string]string:
892 | for k, val := range v {
893 | m[ToString(k)] = []string{val}
894 | }
895 | case map[string]interface{}:
896 | for k, val := range v {
897 | switch vt := val.(type) {
898 | case []interface{}:
899 | m[ToString(k)] = ToStringSlice(vt)
900 | case []string:
901 | m[ToString(k)] = vt
902 | default:
903 | m[ToString(k)] = []string{ToString(val)}
904 | }
905 | }
906 | return m, nil
907 | case map[interface{}][]string:
908 | for k, val := range v {
909 | m[ToString(k)] = ToStringSlice(val)
910 | }
911 | return m, nil
912 | case map[interface{}]string:
913 | for k, val := range v {
914 | m[ToString(k)] = ToStringSlice(val)
915 | }
916 | return m, nil
917 | case map[interface{}][]interface{}:
918 | for k, val := range v {
919 | m[ToString(k)] = ToStringSlice(val)
920 | }
921 | return m, nil
922 | case map[interface{}]interface{}:
923 | for k, val := range v {
924 | key, err := ToStringE(k)
925 | if err != nil {
926 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
927 | }
928 | value, err := ToStringSliceE(val)
929 | if err != nil {
930 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
931 | }
932 | m[key] = value
933 | }
934 | case string:
935 | err := jsonStringToObject(v, &m)
936 | return m, err
937 | default:
938 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string][]string", i, i)
939 | }
940 | return m, nil
941 | }
942 |
943 | // ToStringMapBoolE casts an interface to a map[string]bool type.
944 | func ToStringMapBoolE(i interface{}) (map[string]bool, error) {
945 | var m = map[string]bool{}
946 |
947 | switch v := i.(type) {
948 | case map[interface{}]interface{}:
949 | for k, val := range v {
950 | m[ToString(k)] = ToBool(val)
951 | }
952 | return m, nil
953 | case map[string]interface{}:
954 | for k, val := range v {
955 | m[ToString(k)] = ToBool(val)
956 | }
957 | return m, nil
958 | case map[string]bool:
959 | return v, nil
960 | case string:
961 | err := jsonStringToObject(v, &m)
962 | return m, err
963 | default:
964 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]bool", i, i)
965 | }
966 | }
967 |
968 | // ToStringMapE casts an interface to a map[string]interface{} type.
969 | func ToStringMapE(i interface{}) (map[string]interface{}, error) {
970 | var m = map[string]interface{}{}
971 |
972 | switch v := i.(type) {
973 | case map[interface{}]interface{}:
974 | for k, val := range v {
975 | m[ToString(k)] = val
976 | }
977 | return m, nil
978 | case map[string]interface{}:
979 | return v, nil
980 | case string:
981 | err := jsonStringToObject(v, &m)
982 | return m, err
983 | default:
984 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]interface{}", i, i)
985 | }
986 | }
987 |
988 | // ToStringMapIntE casts an interface to a map[string]int{} type.
989 | func ToStringMapIntE(i interface{}) (map[string]int, error) {
990 | var m = map[string]int{}
991 | if i == nil {
992 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
993 | }
994 |
995 | switch v := i.(type) {
996 | case map[interface{}]interface{}:
997 | for k, val := range v {
998 | m[ToString(k)] = ToInt(val)
999 | }
1000 | return m, nil
1001 | case map[string]interface{}:
1002 | for k, val := range v {
1003 | m[k] = ToInt(val)
1004 | }
1005 | return m, nil
1006 | case map[string]int:
1007 | return v, nil
1008 | case string:
1009 | err := jsonStringToObject(v, &m)
1010 | return m, err
1011 | }
1012 |
1013 | if reflect.TypeOf(i).Kind() != reflect.Map {
1014 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
1015 | }
1016 |
1017 | mVal := reflect.ValueOf(m)
1018 | v := reflect.ValueOf(i)
1019 | for _, keyVal := range v.MapKeys() {
1020 | val, err := ToIntE(v.MapIndex(keyVal).Interface())
1021 | if err != nil {
1022 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int", i, i)
1023 | }
1024 | mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
1025 | }
1026 | return m, nil
1027 | }
1028 |
1029 | // ToStringMapInt64E casts an interface to a map[string]int64{} type.
1030 | func ToStringMapInt64E(i interface{}) (map[string]int64, error) {
1031 | var m = map[string]int64{}
1032 | if i == nil {
1033 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1034 | }
1035 |
1036 | switch v := i.(type) {
1037 | case map[interface{}]interface{}:
1038 | for k, val := range v {
1039 | m[ToString(k)] = ToInt64(val)
1040 | }
1041 | return m, nil
1042 | case map[string]interface{}:
1043 | for k, val := range v {
1044 | m[k] = ToInt64(val)
1045 | }
1046 | return m, nil
1047 | case map[string]int64:
1048 | return v, nil
1049 | case string:
1050 | err := jsonStringToObject(v, &m)
1051 | return m, err
1052 | }
1053 |
1054 | if reflect.TypeOf(i).Kind() != reflect.Map {
1055 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1056 | }
1057 | mVal := reflect.ValueOf(m)
1058 | v := reflect.ValueOf(i)
1059 | for _, keyVal := range v.MapKeys() {
1060 | val, err := ToInt64E(v.MapIndex(keyVal).Interface())
1061 | if err != nil {
1062 | return m, fmt.Errorf("unable to cast %#v of type %T to map[string]int64", i, i)
1063 | }
1064 | mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
1065 | }
1066 | return m, nil
1067 | }
1068 |
1069 | // ToSliceE casts an interface to a []interface{} type.
1070 | func ToSliceE(i interface{}) ([]interface{}, error) {
1071 | var s []interface{}
1072 |
1073 | switch v := i.(type) {
1074 | case []interface{}:
1075 | return append(s, v...), nil
1076 | case []map[string]interface{}:
1077 | for _, u := range v {
1078 | s = append(s, u)
1079 | }
1080 | return s, nil
1081 | default:
1082 | return s, fmt.Errorf("unable to cast %#v of type %T to []interface{}", i, i)
1083 | }
1084 | }
1085 |
1086 | // ToBoolSliceE casts an interface to a []bool type.
1087 | func ToBoolSliceE(i interface{}) ([]bool, error) {
1088 | if i == nil {
1089 | return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1090 | }
1091 |
1092 | switch v := i.(type) {
1093 | case []bool:
1094 | return v, nil
1095 | }
1096 |
1097 | kind := reflect.TypeOf(i).Kind()
1098 | switch kind {
1099 | case reflect.Slice, reflect.Array:
1100 | s := reflect.ValueOf(i)
1101 | a := make([]bool, s.Len())
1102 | for j := 0; j < s.Len(); j++ {
1103 | val, err := ToBoolE(s.Index(j).Interface())
1104 | if err != nil {
1105 | return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1106 | }
1107 | a[j] = val
1108 | }
1109 | return a, nil
1110 | default:
1111 | return []bool{}, fmt.Errorf("unable to cast %#v of type %T to []bool", i, i)
1112 | }
1113 | }
1114 |
1115 | // ToStringSliceE casts an interface to a []string type.
1116 | func ToStringSliceE(i interface{}) ([]string, error) {
1117 | var a []string
1118 |
1119 | switch v := i.(type) {
1120 | case []interface{}:
1121 | for _, u := range v {
1122 | a = append(a, ToString(u))
1123 | }
1124 | return a, nil
1125 | case []string:
1126 | return v, nil
1127 | case string:
1128 | return strings.Fields(v), nil
1129 | case interface{}:
1130 | str, err := ToStringE(v)
1131 | if err != nil {
1132 | return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
1133 | }
1134 | return []string{str}, nil
1135 | default:
1136 | return a, fmt.Errorf("unable to cast %#v of type %T to []string", i, i)
1137 | }
1138 | }
1139 |
1140 | // ToIntSliceE casts an interface to a []int type.
1141 | func ToIntSliceE(i interface{}) ([]int, error) {
1142 | if i == nil {
1143 | return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1144 | }
1145 |
1146 | switch v := i.(type) {
1147 | case []int:
1148 | return v, nil
1149 | }
1150 |
1151 | kind := reflect.TypeOf(i).Kind()
1152 | switch kind {
1153 | case reflect.Slice, reflect.Array:
1154 | s := reflect.ValueOf(i)
1155 | a := make([]int, s.Len())
1156 | for j := 0; j < s.Len(); j++ {
1157 | val, err := ToIntE(s.Index(j).Interface())
1158 | if err != nil {
1159 | return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1160 | }
1161 | a[j] = val
1162 | }
1163 | return a, nil
1164 | default:
1165 | return []int{}, fmt.Errorf("unable to cast %#v of type %T to []int", i, i)
1166 | }
1167 | }
1168 |
1169 | // ToDurationSliceE casts an interface to a []time.Duration type.
1170 | func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
1171 | if i == nil {
1172 | return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1173 | }
1174 |
1175 | switch v := i.(type) {
1176 | case []time.Duration:
1177 | return v, nil
1178 | }
1179 |
1180 | kind := reflect.TypeOf(i).Kind()
1181 | switch kind {
1182 | case reflect.Slice, reflect.Array:
1183 | s := reflect.ValueOf(i)
1184 | a := make([]time.Duration, s.Len())
1185 | for j := 0; j < s.Len(); j++ {
1186 | val, err := ToDurationE(s.Index(j).Interface())
1187 | if err != nil {
1188 | return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1189 | }
1190 | a[j] = val
1191 | }
1192 | return a, nil
1193 | default:
1194 | return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
1195 | }
1196 | }
1197 |
1198 | // StringToDate attempts to parse a string into a time.Time type using a
1199 | // predefined list of formats. If no suitable format is found, an error is
1200 | // returned.
1201 | func StringToDate(s string) (time.Time, error) {
1202 | return parseDateWith(s, []string{
1203 | time.RFC3339,
1204 | "2006-01-02T15:04:05", // iso8601 without timezone
1205 | time.RFC1123Z,
1206 | time.RFC1123,
1207 | time.RFC822Z,
1208 | time.RFC822,
1209 | time.RFC850,
1210 | time.ANSIC,
1211 | time.UnixDate,
1212 | time.RubyDate,
1213 | "2006-01-02 15:04:05.999999999 -0700 MST", // Time.String()
1214 | "2006-01-02",
1215 | "02 Jan 2006",
1216 | "2006-01-02T15:04:05-0700", // RFC3339 without timezone hh:mm colon
1217 | "2006-01-02 15:04:05 -07:00",
1218 | "2006-01-02 15:04:05 -0700",
1219 | "2006-01-02 15:04:05Z07:00", // RFC3339 without T
1220 | "2006-01-02 15:04:05Z0700", // RFC3339 without T or timezone hh:mm colon
1221 | "2006-01-02 15:04:05",
1222 | time.Kitchen,
1223 | time.Stamp,
1224 | time.StampMilli,
1225 | time.StampMicro,
1226 | time.StampNano,
1227 | })
1228 | }
1229 |
1230 | func parseDateWith(s string, dates []string) (d time.Time, e error) {
1231 | for _, dateType := range dates {
1232 | if d, e = time.Parse(dateType, s); e == nil {
1233 | return
1234 | }
1235 | }
1236 | return d, fmt.Errorf("unable to parse date: %s", s)
1237 | }
1238 |
1239 | // jsonStringToObject attempts to unmarshall a string as JSON into
1240 | // the object passed as pointer.
1241 | func jsonStringToObject(s string, v interface{}) error {
1242 | data := []byte(s)
1243 | return json.Unmarshal(data, v)
1244 | }
1245 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/service/estatebook.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package service
18 |
19 | import (
20 | "ccservice"
21 | "comm"
22 | "db"
23 | )
24 |
25 | func EstateBookGetAll() (res comm.ResResult) {
26 | books, err := db.EstateBookAll()
27 | if err != nil {
28 | res.Code = 1
29 | res.Status = err.Error()
30 | } else {
31 | res.Code = 0
32 | res.Status = books
33 | }
34 | return
35 | }
36 |
37 | func EstateBookCreate(bookid, netconid, taxid, owener, addr string, area int) (res comm.ResResult) {
38 | err := db.EstateBookCreate(bookid, netconid, taxid, owener, addr, area, GetOperator())
39 | if err != nil {
40 | res.Code = 1
41 | res.Status = err.Error()
42 | } else {
43 | res.Code = 0
44 | }
45 | return
46 | }
47 |
48 | func EstateBookToCC(uuid, bookid, owner, addr, area string) (res comm.ResResult) {
49 | res = ccservice.EstateBookCreate(uuid, bookid,owner, addr, area)
50 | if res.Code == 0 {
51 | err := db.EstateBookUpdateCC(uuid, 1)
52 | if err != nil {
53 | res.Code = 1
54 | res.Status = "上链成功,但更新业务数据库中的上链标志失败:" + err.Error()
55 | }
56 | }
57 | return
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/service/estatetax.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package service
18 |
19 | import (
20 | "ccservice"
21 | "comm"
22 | "db"
23 | )
24 |
25 | func EstateTaxGetAll() (res comm.ResResult) {
26 | taxs, err := db.EstateTaxAll()
27 | if err != nil {
28 | res.Code = 1
29 | res.Status = err.Error()
30 | } else {
31 | res.Code = 0
32 | res.Status = taxs
33 | }
34 | return
35 | }
36 |
37 | func EstateTaxCreate(taxid, taxer string, area, tax int) (res comm.ResResult) {
38 | err := db.EstateTaxCreate(taxid, taxer, area, tax, GetOperator())
39 | if err != nil {
40 | res.Code = 1
41 | res.Status = err.Error()
42 | } else {
43 | res.Code = 0
44 | }
45 | return
46 | }
47 |
48 | func EstateTaxToCC(uuid, taxid, taxer, area, tax string) (res comm.ResResult) {
49 | res = ccservice.EstateTaxCreate(uuid, taxid, "", taxer, area, tax)
50 | if res.Code == 0 {
51 | err := db.EstateTaxUpdateCC(uuid, 1)
52 | if err != nil {
53 | res.Code = 1
54 | res.Status = "上链成功,但更新业务数据库中的上链标志失败:" + err.Error()
55 | }
56 | }
57 | return
58 | }
59 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/service/netcon.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package service
18 |
19 | import (
20 | "ccservice"
21 | "comm"
22 | "db"
23 | )
24 |
25 | func NetconGetAll() (res comm.ResResult) {
26 | netcons, err := db.NetconsAll()
27 | if err != nil {
28 | res.Code = 1
29 | res.Status = err.Error()
30 | } else {
31 | res.Code = 0
32 | res.Status = netcons
33 | }
34 | return
35 | }
36 |
37 | func NetconCreate(netconid, applya, applyb, addr string, area, balance int) (res comm.ResResult) {
38 | err := db.NetconsCreate(netconid, applya, applyb, addr, area, balance, GetOperator())
39 | if err != nil {
40 | res.Code = 1
41 | res.Status = err.Error()
42 | } else {
43 | res.Code = 0
44 | }
45 | return
46 | }
47 |
48 | func NetconToCC(uuid, netconid, applya, applyb, addr, area, balance string) (res comm.ResResult) {
49 | res = ccservice.NetconCreate(uuid, netconid, applya, applyb, addr, area, balance)
50 | if res.Code == 0 {
51 | err := db.NetconsUpdateCC(uuid, 1)
52 | if err != nil {
53 | res.Code = 1
54 | res.Status = "上链成功,但更新业务数据库中的上链标志失败:" + err.Error()
55 | }
56 | }
57 | return
58 | }
59 |
--------------------------------------------------------------------------------
/appcode/fccserver/src/service/system.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright xujf000@gmail.com .2020. All Rights Reserved.
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 | package service
18 |
19 | import (
20 | "ccservice"
21 | "db"
22 | )
23 |
24 | // InitOnSystemStart
25 | func InitOnSystemStart() (err error) {
26 | err = db.InitDB()
27 | if err != nil {
28 | return
29 | }
30 | //for now ,if Chaincode service initial failed ,don't break startup process.
31 | // give system a chance to reinitial on later.
32 | ccservice.InitCCOnStart()
33 | return nil
34 | }
35 |
36 | //get current operator
37 | func GetOperator() string {
38 | return "SystemOperator1"
39 | }
40 |
--------------------------------------------------------------------------------
/chaincode/estatebook/estatebook.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bytes"
5 | "encoding/json"
6 | "fmt"
7 | "github.com/hyperledger/fabric/core/chaincode/shim"
8 | peer "github.com/hyperledger/fabric/protos/peer"
9 | "strconv"
10 | )
11 |
12 | // Define the Smart Contract structure
13 | type EstateBookContract struct {
14 | }
15 |
16 | type EstateBook struct {
17 | BookID string `json:"bookid"` //不动产证书编号
18 | Owner string `json:"owner"` //户主
19 | Addr string `json:"addr"` //房屋地址
20 | Area int `json:"area"` //房屋面积
21 | }
22 |
23 | type RecordsInfo struct {
24 | Size uint64
25 | Start string
26 | End string
27 | }
28 |
29 | var key_recordinfo = "recordeinfo"
30 | var evn_estatebook = "evn_estatebook"
31 |
32 | func (s *EstateBookContract) Init(APIstub shim.ChaincodeStubInterface) peer.Response {
33 | return shim.Success(nil)
34 | }
35 |
36 | func (s *EstateBookContract) Invoke(APIstub shim.ChaincodeStubInterface) peer.Response {
37 | function, args := APIstub.GetFunctionAndParameters()
38 | switch function {
39 | case "create":
40 | return s.create(APIstub, args)
41 | case "queryByBookID":
42 | return s.queryByBookID(APIstub, args)
43 | case "queryByPara":
44 | return s.queryByPara(APIstub, args)
45 | case "queryAll":
46 | return s.queryAll(APIstub, args)
47 | default:
48 | return shim.Error("Invalid Smart Contract function name.")
49 | }
50 | }
51 |
52 | func (s *EstateBookContract) create(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
53 | if len(args) != 5 {
54 | return shim.Error("Incorrect number of arguments. Expecting 5. ")
55 | }
56 | key := args[0]
57 | area, err := strconv.Atoi(args[4])
58 | if err != nil {
59 | return shim.Error("area value wrong.")
60 | }
61 | estateBook := &EstateBook{
62 | BookID: args[1],
63 | Owner: args[2],
64 | Addr: args[3],
65 | Area: area,
66 | }
67 | jsBytes, err := json.Marshal(estateBook)
68 | if err != nil {
69 | return shim.Error("marshal json error:" + err.Error())
70 | }
71 | err = APIstub.PutState(key, jsBytes)
72 | if err != nil {
73 | return shim.Error("error on putstate:" + err.Error())
74 | }
75 | //update recodeinfo
76 | recordInfo := &RecordsInfo{}
77 | rebs, err := APIstub.GetState(key_recordinfo)
78 | if len(rebs) == 0 {
79 | recordInfo.Size = 1
80 | recordInfo.Start = key
81 | recordInfo.End = key
82 | } else {
83 | err = json.Unmarshal(rebs, &recordInfo)
84 | if err != nil {
85 | return shim.Error("error on unmarsh recorderinfo:" + err.Error())
86 | }
87 | recordInfo.Size = recordInfo.Size + 1
88 | recordInfo.End = key
89 | }
90 | rebs, err = json.Marshal(recordInfo)
91 | if err != nil {
92 | return shim.Error("error on marsh new recorderinfo:" + err.Error())
93 | }
94 | err = APIstub.PutState(key_recordinfo, rebs)
95 | if err != nil {
96 | return shim.Error("error on put new recorderinfo:" + err.Error())
97 | }
98 | //broadcast event
99 | err = APIstub.SetEvent(evn_estatebook, []byte("new estatebook created with key:"+key))
100 | if err != nil {
101 | return shim.Error(err.Error())
102 | }
103 | return shim.Success([]byte("new estatebook created with key:" + key))
104 | }
105 |
106 | func (s *EstateBookContract) queryByBookID(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
107 | if len(args) != 1 {
108 | return shim.Error("Incorrect number of arguments. Expecting 1 ")
109 | }
110 | queryString := fmt.Sprintf("{\"selector\":{\"bookid\":\"%s\"}}", args[0])
111 | qis, err := APIstub.GetQueryResult(queryString)
112 | if err != nil {
113 | return shim.Error("queryByBookID error:" + err.Error())
114 | }
115 | defer qis.Close()
116 | var buffer bytes.Buffer
117 | buffer.WriteString("[")
118 | bArrayMemberAlreadyWritten := false
119 | for qis.HasNext() {
120 | queryResponse, err := qis.Next()
121 | if err != nil {
122 | return shim.Error(err.Error())
123 | }
124 | if bArrayMemberAlreadyWritten == true {
125 | buffer.WriteString(",")
126 | }
127 | buffer.WriteString(string(queryResponse.Value))
128 | bArrayMemberAlreadyWritten = true
129 | }
130 | buffer.WriteString("]")
131 | return shim.Success(buffer.Bytes())
132 | }
133 |
134 | func (s *EstateBookContract) queryByPara(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
135 | if len(args) != 2 {
136 | return shim.Error("Incorrect number of arguments. Expecting 2 ")
137 | }
138 | queryString := fmt.Sprintf("{\"selector\":{\""+args[0]+"\":\"%s\"}}", args[1])
139 | qis, err := APIstub.GetQueryResult(queryString)
140 | if err != nil {
141 | return shim.Error("queryByPara error:" + err.Error())
142 | }
143 | defer qis.Close()
144 | resultsIterator, err := APIstub.GetQueryResult(queryString)
145 | if err != nil {
146 | return shim.Error(err.Error())
147 | }
148 | defer resultsIterator.Close()
149 |
150 | var buffer bytes.Buffer
151 | buffer.WriteString("[")
152 | bArrayMemberAlreadyWritten := false
153 | for resultsIterator.HasNext() {
154 | queryResponse, err := resultsIterator.Next()
155 | if err != nil {
156 | return shim.Error(err.Error())
157 | }
158 | if bArrayMemberAlreadyWritten == true {
159 | buffer.WriteString(",")
160 | }
161 | buffer.WriteString(string(queryResponse.Value))
162 | bArrayMemberAlreadyWritten = true
163 | }
164 | buffer.WriteString("]")
165 | return shim.Success(buffer.Bytes())
166 | }
167 |
168 | func (s *EstateBookContract) queryAll(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
169 | rebs, err := APIstub.GetState(key_recordinfo)
170 | if err != nil {
171 | return shim.Error("error on get recorderinfo:" + err.Error())
172 | }
173 | recordInfo := &RecordsInfo{}
174 | if len(rebs) == 0 {
175 | return shim.Success([]byte{})
176 | }
177 | err = json.Unmarshal(rebs, &recordInfo)
178 | if err != nil {
179 | return shim.Error("error on unmarsh recorderinfo:" + err.Error())
180 | }
181 | resultsIterator, err := APIstub.GetStateByRange(recordInfo.Start, recordInfo.End+"1")
182 | if err != nil {
183 | return shim.Error(err.Error())
184 | }
185 | defer resultsIterator.Close()
186 |
187 | var buffer bytes.Buffer
188 | buffer.WriteString("[")
189 | bArrayMemberAlreadyWritten := false
190 | for resultsIterator.HasNext() {
191 | queryResponse, err := resultsIterator.Next()
192 | if err != nil {
193 | return shim.Error(err.Error())
194 | }
195 | if bArrayMemberAlreadyWritten == true {
196 | buffer.WriteString(",")
197 | }
198 | buffer.WriteString(string(queryResponse.Value))
199 | bArrayMemberAlreadyWritten = true
200 | }
201 | buffer.WriteString("]")
202 | println("size:" + strconv.FormatUint(recordInfo.Size, 10) + " start:" + recordInfo.Start + " end:" + recordInfo.End)
203 | return shim.Success(buffer.Bytes())
204 | }
205 |
206 | func main() {
207 | err := shim.Start(new(EstateBookContract))
208 | if err != nil {
209 | fmt.Printf("Error creating new Smart Contract: %s", err)
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/chaincode/estatetax/estatetax.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bytes"
5 | "encoding/json"
6 | "fmt"
7 | "github.com/hyperledger/fabric/core/chaincode/shim"
8 | peer "github.com/hyperledger/fabric/protos/peer"
9 | "strconv"
10 | )
11 |
12 | // Define the Smart Contract structure
13 | type EstateTaxContract struct {
14 | }
15 |
16 | type EstateTax struct {
17 | TaxID string `json:"taxid"` //核税编号
18 | BookID string `json:"bookid"` //不动产权证书编号
19 | Taxer string `json:"taxer"` //纳税人
20 | Area int `json:"area"` //房屋面积
21 | Tax int `json:"tax"` //纳税金额
22 | }
23 |
24 | type RecordsInfo struct {
25 | Size uint64
26 | Start string
27 | End string
28 | }
29 |
30 | var key_recordinfo = "recordeinfo"
31 | var evn_estatetax = "evn_estatetax"
32 |
33 | func (s *EstateTaxContract) Init(APIstub shim.ChaincodeStubInterface) peer.Response {
34 | return shim.Success(nil)
35 | }
36 |
37 | func (s *EstateTaxContract) Invoke(APIstub shim.ChaincodeStubInterface) peer.Response {
38 | function, args := APIstub.GetFunctionAndParameters()
39 | switch function {
40 | case "create":
41 | return s.create(APIstub, args)
42 | case "queryByTaxID":
43 | return s.queryByTaxID(APIstub, args)
44 | case "queryByPara":
45 | return s.queryByPara(APIstub, args)
46 | case "queryAll":
47 | return s.queryAll(APIstub, args)
48 | default:
49 | return shim.Error("Invalid Smart Contract function name.")
50 | }
51 | }
52 |
53 | func (s *EstateTaxContract) create(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
54 | if len(args) != 6 {
55 | return shim.Error("Incorrect number of arguments. Expecting 6. ")
56 | }
57 | key := args[0]
58 | area, err := strconv.Atoi(args[4])
59 | if err != nil {
60 | return shim.Error("area value wrong.")
61 | }
62 | tax, err := strconv.Atoi(args[5])
63 | if err != nil {
64 | return shim.Error("area value wrong.")
65 | }
66 | EstateTax := &EstateTax{
67 | TaxID: args[1],
68 | BookID: args[2],
69 | Taxer: args[3],
70 | Area: area,
71 | Tax: tax,
72 | }
73 | jsBytes, err := json.Marshal(EstateTax)
74 | if err != nil {
75 | return shim.Error("marshal json error:" + err.Error())
76 | }
77 | err = APIstub.PutState(key, jsBytes)
78 | if err != nil {
79 | return shim.Error("error on putstate:" + err.Error())
80 | }
81 | //update recodeinfo
82 | recordInfo := &RecordsInfo{}
83 | rebs, err := APIstub.GetState(key_recordinfo)
84 | if len(rebs) == 0 {
85 | recordInfo.Size = 1
86 | recordInfo.Start = key
87 | recordInfo.End = key
88 | } else {
89 | err = json.Unmarshal(rebs, &recordInfo)
90 | if err != nil {
91 | return shim.Error("error on unmarsh recorderinfo:" + err.Error())
92 | }
93 | recordInfo.Size = recordInfo.Size + 1
94 | recordInfo.End = key
95 | }
96 | rebs, err = json.Marshal(recordInfo)
97 | if err != nil {
98 | return shim.Error("error on marsh new recorderinfo:" + err.Error())
99 | }
100 | err = APIstub.PutState(key_recordinfo, rebs)
101 | if err != nil {
102 | return shim.Error("error on put new recorderinfo:" + err.Error())
103 | }
104 | //broadcast event
105 | err = APIstub.SetEvent(evn_estatetax, []byte("new EstateTax created with key:"+key))
106 | if err != nil {
107 | return shim.Error(err.Error())
108 | }
109 | return shim.Success([]byte("new EstateTax created with key:" + key))
110 | }
111 |
112 | func (s *EstateTaxContract) queryByTaxID(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
113 | if len(args) != 1 {
114 | return shim.Error("Incorrect number of arguments. Expecting 1 ")
115 | }
116 | queryString := fmt.Sprintf("{\"selector\":{\"taxid\":\"%s\"}}", args[0])
117 | qis, err := APIstub.GetQueryResult(queryString)
118 | if err != nil {
119 | return shim.Error("queryByTaxID error:" + err.Error())
120 | }
121 | defer qis.Close()
122 | var buffer bytes.Buffer
123 | buffer.WriteString("[")
124 | bArrayMemberAlreadyWritten := false
125 | for qis.HasNext() {
126 | queryResponse, err := qis.Next()
127 | if err != nil {
128 | return shim.Error(err.Error())
129 | }
130 | if bArrayMemberAlreadyWritten == true {
131 | buffer.WriteString(",")
132 | }
133 | buffer.WriteString(string(queryResponse.Value))
134 | bArrayMemberAlreadyWritten = true
135 | }
136 | buffer.WriteString("]")
137 | return shim.Success(buffer.Bytes())
138 | }
139 |
140 | func (s *EstateTaxContract) queryByPara(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
141 | if len(args) != 2 {
142 | return shim.Error("Incorrect number of arguments. Expecting 2 ")
143 | }
144 | queryString := fmt.Sprintf("{\"selector\":{\""+args[0]+"\":\"%s\"}}", args[1])
145 | qis, err := APIstub.GetQueryResult(queryString)
146 | if err != nil {
147 | return shim.Error("queryByPara error:" + err.Error())
148 | }
149 | defer qis.Close()
150 | resultsIterator, err := APIstub.GetQueryResult(queryString)
151 | if err != nil {
152 | return shim.Error(err.Error())
153 | }
154 | defer resultsIterator.Close()
155 |
156 | var buffer bytes.Buffer
157 | buffer.WriteString("[")
158 | bArrayMemberAlreadyWritten := false
159 | for resultsIterator.HasNext() {
160 | queryResponse, err := resultsIterator.Next()
161 | if err != nil {
162 | return shim.Error(err.Error())
163 | }
164 | if bArrayMemberAlreadyWritten == true {
165 | buffer.WriteString(",")
166 | }
167 | buffer.WriteString(string(queryResponse.Value))
168 | bArrayMemberAlreadyWritten = true
169 | }
170 | buffer.WriteString("]")
171 | return shim.Success(buffer.Bytes())
172 | }
173 |
174 | func (s *EstateTaxContract) queryAll(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
175 | rebs, err := APIstub.GetState(key_recordinfo)
176 | if err != nil {
177 | return shim.Error("error on get recorderinfo:" + err.Error())
178 | }
179 | recordInfo := &RecordsInfo{}
180 | if len(rebs) == 0 {
181 | return shim.Success([]byte{})
182 | }
183 | err = json.Unmarshal(rebs, &recordInfo)
184 | if err != nil {
185 | return shim.Error("error on unmarsh recorderinfo:" + err.Error())
186 | }
187 | resultsIterator, err := APIstub.GetStateByRange(recordInfo.Start, recordInfo.End+"1")
188 | if err != nil {
189 | return shim.Error(err.Error())
190 | }
191 | defer resultsIterator.Close()
192 |
193 | var buffer bytes.Buffer
194 | buffer.WriteString("[")
195 | bArrayMemberAlreadyWritten := false
196 | for resultsIterator.HasNext() {
197 | queryResponse, err := resultsIterator.Next()
198 | if err != nil {
199 | return shim.Error(err.Error())
200 | }
201 | if bArrayMemberAlreadyWritten == true {
202 | buffer.WriteString(",")
203 | }
204 | buffer.WriteString(string(queryResponse.Value))
205 | bArrayMemberAlreadyWritten = true
206 | }
207 | buffer.WriteString("]")
208 | println(" size:" + strconv.FormatUint(recordInfo.Size, 10) + " start:" + recordInfo.Start + " end:" + recordInfo.End)
209 | return shim.Success(buffer.Bytes())
210 | }
211 |
212 | func main() {
213 | err := shim.Start(new(EstateTaxContract))
214 | if err != nil {
215 | fmt.Printf("Error creating new Smart Contract: %s", err)
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/chaincode/netcon/netcon.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bytes"
5 | "encoding/json"
6 | "fmt"
7 | "github.com/hyperledger/fabric/core/chaincode/shim"
8 | peer "github.com/hyperledger/fabric/protos/peer"
9 | "strconv"
10 | )
11 |
12 | // Define the Smart Contract structure
13 | type NetconContract struct {
14 | }
15 |
16 | type Netcon struct {
17 | NetconID string `json:"netconid"` //合同编号
18 | ApplyA string `json:"applya"` //受让方(买方)
19 | ApplyB string `json:"applyb"` //转让方(卖方)
20 | Addr string `json:"addr"` //房屋地址
21 | Area int `json:"area"` //房屋面积
22 | Balance int `json:"balance"` //转让金额
23 | }
24 |
25 | type RecordsInfo struct {
26 | Size uint64
27 | Start string
28 | End string
29 | }
30 |
31 | var key_recordinfo = "recordeinfo"
32 | var evn_netcon = "evn_netcon"
33 |
34 | func (s *NetconContract) Init(APIstub shim.ChaincodeStubInterface) peer.Response {
35 | return shim.Success(nil)
36 | }
37 |
38 | func (s *NetconContract) Invoke(APIstub shim.ChaincodeStubInterface) peer.Response {
39 | function, args := APIstub.GetFunctionAndParameters()
40 | switch function {
41 | case "create":
42 | return s.create(APIstub, args)
43 | case "queryByNetconID":
44 | return s.queryByNetconID(APIstub, args)
45 | case "queryByPara":
46 | return s.queryByPara(APIstub, args)
47 | case "queryAll":
48 | return s.queryAll(APIstub, args)
49 | default:
50 | return shim.Error("Invalid Smart Contract function name.")
51 | }
52 | }
53 |
54 | func (s *NetconContract) create(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
55 | if len(args) != 7 {
56 | return shim.Error("Incorrect number of arguments. Expecting 7. ")
57 | }
58 | area, err := strconv.Atoi(args[5])
59 | if err != nil {
60 | return shim.Error("area value wrong.")
61 | }
62 | balance, err := strconv.Atoi(args[6])
63 | if err != nil {
64 | return shim.Error("balance value wrong.")
65 | }
66 | netCon := &Netcon{
67 | NetconID: args[1],
68 | ApplyA: args[2],
69 | ApplyB: args[3],
70 | Addr: args[4],
71 | Area: area,
72 | Balance: balance,
73 | }
74 | jsBytes, err := json.Marshal(netCon)
75 | if err != nil {
76 | return shim.Error("marshal json error:" + err.Error())
77 | }
78 | err = APIstub.PutState(args[0], jsBytes)
79 | if err != nil {
80 | return shim.Error("error on putstate:" + err.Error())
81 | }
82 | //update recodeinfo
83 | recordInfo := &RecordsInfo{}
84 | rebs, err := APIstub.GetState(key_recordinfo)
85 | if len(rebs) == 0 {
86 | recordInfo.Size = 1
87 | recordInfo.Start = args[0]
88 | recordInfo.End = args[0]
89 | } else {
90 | err = json.Unmarshal(rebs, &recordInfo)
91 | if err != nil {
92 | return shim.Error("error on unmarsh recorderinfo:" + err.Error())
93 | }
94 | recordInfo.Size = recordInfo.Size + 1
95 | recordInfo.End = args[0]
96 | }
97 | rebs, err = json.Marshal(recordInfo)
98 | if err != nil {
99 | return shim.Error("error on marsh new recorderinfo:" + err.Error())
100 | }
101 | err = APIstub.PutState(key_recordinfo, rebs)
102 | if err != nil {
103 | return shim.Error("error on put new recorderinfo:" + err.Error())
104 | }
105 | //broadcast event
106 | err = APIstub.SetEvent(evn_netcon, []byte("new netcon created with key:"+args[0]))
107 | if err != nil {
108 | return shim.Error(err.Error())
109 | }
110 | return shim.Success([]byte("new netcon created with key:" + args[0]))
111 | }
112 |
113 | func (s *NetconContract) queryByNetconID(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
114 | if len(args) != 1 {
115 | return shim.Error("Incorrect number of arguments. Expecting 1 ")
116 | }
117 | queryString := fmt.Sprintf("{\"selector\":{\"netconid\":\"%s\"}}", args[0])
118 | qis, err := APIstub.GetQueryResult(queryString)
119 | if err != nil {
120 | return shim.Error("queryByNetconID error:" + err.Error())
121 | }
122 | defer qis.Close()
123 | var buffer bytes.Buffer
124 | buffer.WriteString("[")
125 | bArrayMemberAlreadyWritten := false
126 | for qis.HasNext() {
127 | queryResponse, err := qis.Next()
128 | if err != nil {
129 | return shim.Error(err.Error())
130 | }
131 | if bArrayMemberAlreadyWritten == true {
132 | buffer.WriteString(",")
133 | }
134 | buffer.WriteString(string(queryResponse.Value))
135 | bArrayMemberAlreadyWritten = true
136 | }
137 | buffer.WriteString("]")
138 | return shim.Success(buffer.Bytes())
139 | }
140 |
141 | func (s *NetconContract) queryByPara(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
142 | if len(args) != 2 {
143 | return shim.Error("Incorrect number of arguments. Expecting 2 ")
144 | }
145 | queryString := fmt.Sprintf("{\"selector\":{\""+args[0]+"\":\"%s\"}}", args[1])
146 | qis, err := APIstub.GetQueryResult(queryString)
147 | if err != nil {
148 | return shim.Error("queryByNetconID error:" + err.Error())
149 | }
150 | defer qis.Close()
151 | resultsIterator, err := APIstub.GetQueryResult(queryString)
152 | if err != nil {
153 | return shim.Error(err.Error())
154 | }
155 | defer resultsIterator.Close()
156 |
157 | var buffer bytes.Buffer
158 | buffer.WriteString("[")
159 | bArrayMemberAlreadyWritten := false
160 | for resultsIterator.HasNext() {
161 | queryResponse, err := resultsIterator.Next()
162 | if err != nil {
163 | return shim.Error(err.Error())
164 | }
165 | if bArrayMemberAlreadyWritten == true {
166 | buffer.WriteString(",")
167 | }
168 | buffer.WriteString(string(queryResponse.Value))
169 | bArrayMemberAlreadyWritten = true
170 | }
171 | buffer.WriteString("]")
172 | return shim.Success(buffer.Bytes())
173 | }
174 |
175 | func (s *NetconContract) queryAll(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
176 | rebs, err := APIstub.GetState(key_recordinfo)
177 | if err != nil {
178 | return shim.Error("error on get recorderinfo:" + err.Error())
179 | }
180 | recordInfo := &RecordsInfo{}
181 | if len(rebs) == 0 {
182 | return shim.Success([]byte{})
183 | }
184 | err = json.Unmarshal(rebs, &recordInfo)
185 | if err != nil {
186 | return shim.Error("error on unmarsh recorderinfo:" + err.Error())
187 | }
188 | resultsIterator, err := APIstub.GetStateByRange(recordInfo.Start, recordInfo.End+"1")
189 | if err != nil {
190 | return shim.Error(err.Error())
191 | }
192 | defer resultsIterator.Close()
193 |
194 | var buffer bytes.Buffer
195 | buffer.WriteString("[")
196 | bArrayMemberAlreadyWritten := false
197 | for resultsIterator.HasNext() {
198 | queryResponse, err := resultsIterator.Next()
199 | if err != nil {
200 | return shim.Error(err.Error())
201 | }
202 | if bArrayMemberAlreadyWritten == true {
203 | buffer.WriteString(",")
204 | }
205 | buffer.WriteString(string(queryResponse.Value))
206 | bArrayMemberAlreadyWritten = true
207 | }
208 | buffer.WriteString("]")
209 | println("size:" + strconv.FormatUint(recordInfo.Size, 10) + " start:" + recordInfo.Start + " end:" + recordInfo.End)
210 | return shim.Success(buffer.Bytes())
211 | }
212 |
213 | func main() {
214 | err := shim.Start(new(NetconContract))
215 | if err != nil {
216 | fmt.Printf("Error creating new Smart Contract: %s", err)
217 | }
218 | }
219 |
--------------------------------------------------------------------------------