├── .gitignore
├── LICENSE
├── README.md
├── origin_dairyfarm
└── origin_dairyfarm_cc.go
├── origin_machining
└── origin_machining_cc.go
├── origin_salesterminal
└── origin_salesterminal_cc.go
├── scfinance
└── scfinancecc.go
├── simpledemo
├── .idea
│ ├── modules.xml
│ ├── simpledemo.iml
│ └── workspace.xml
├── simplechaincode.go
└── simplechaincode_test.go
├── simpledemo2
└── simplechaincode2.go
├── simplegyljr
└── simplechaincode.go
└── study
└── chaincodetest.go
/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, build with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
--------------------------------------------------------------------------------
/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 | 本项目是区块链开发实战丛书 《区块链开发实战 Hyperledger Fabric关键技术与案例分析》 第七章的部分的相关代码
4 |
5 | ## 本书介绍
6 |
7 | 《区块链开发实战 Hyperledger Fabric关键技术与案例分析》
8 |
9 |
10 |
11 |
12 | 如果您觉得本丛书的代码对您有帮助请购买本正版图书,谢谢。
13 |
14 | [购买链接](https://item.jd.com/12380456.html)
15 |
16 | ## 问题反馈,
17 |
18 | 为了帮助读者更好的阅读本书,我们跟中国最大的区块链技术社区区块链兄弟合作,在区块链兄弟上面开设了专栏。如果您在阅读本丛书的过程遇到的问题,可以通过以下连接提交问题
19 |
20 | 点击,提交阅读本书的过程中遇到的问题
21 |
22 |
23 | ## 丛书介绍
24 |
25 | 区块链开发实战系列丛书简介
26 |
--------------------------------------------------------------------------------
/origin_dairyfarm/origin_dairyfarm_cc.go:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | Copyright xuehuiit Corp. 2018 All Rights Reserved.
4 |
5 | http://www.xuehuiit.com
6 |
7 | QQ 411321681
8 |
9 | */
10 |
11 | package main
12 |
13 | import (
14 |
15 | "github.com/hyperledger/fabric/core/chaincode/shim"
16 | pb "github.com/hyperledger/fabric/protos/peer"
17 | "fmt"
18 | "time"
19 | "encoding/json"
20 | )
21 |
22 |
23 | type dairyfarm struct {}
24 |
25 |
26 | /**
27 | 系统初始化
28 | */
29 | func (t *dairyfarm) Init(stub shim.ChaincodeStubInterface) pb.Response {
30 |
31 |
32 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
33 |
34 |
35 | }
36 |
37 | /**
38 | 系统invoke方法
39 | */
40 | func (t *dairyfarm) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
41 |
42 | _,args := stub.GetFunctionAndParameters()
43 |
44 | var opttype = args[0]
45 | var assetname = args[1]
46 | var optcontont = args[2]
47 |
48 | fmt.Printf(" parm is %s %s %s \n " , opttype , assetname , optcontont )
49 |
50 |
51 | if opttype == "putvalue" { //设置
52 |
53 | stub.PutState(assetname,[]byte(optcontont))
54 | return shim.Success( []byte( "success put " + optcontont ) )
55 |
56 |
57 | }else if opttype == "getlastvalue"{ //取值
58 |
59 |
60 | var keyvalue []byte
61 | var err error
62 | keyvalue,err = stub.GetState(assetname)
63 |
64 | if( err != nil ){
65 |
66 | return shim.Error(" finad error! ")
67 | }
68 |
69 | return shim.Success( keyvalue )
70 |
71 |
72 |
73 | }else if opttype == "gethistory"{ //获取交易记录
74 |
75 |
76 | keysIter, err := stub.GetHistoryForKey( assetname );
77 |
78 | if err != nil {
79 | return shim.Error(fmt.Sprintf("GetHistoryForKey failed. Error accessing state: %s", err))
80 | }
81 | defer keysIter.Close()
82 |
83 | var keys []string
84 |
85 | for keysIter.HasNext() {
86 |
87 | response, iterErr := keysIter.Next()
88 | if iterErr != nil {
89 | return shim.Error(fmt.Sprintf("GetHistoryForKey operation failed. Error accessing state: %s", err))
90 | }
91 | //交易编号
92 | txid := response.TxId
93 | //交易的值
94 | txvalue := response.Value
95 | //当前交易的状态
96 | txstatus := response.IsDelete
97 | //交易发生的时间戳
98 | txtimesamp :=response.Timestamp
99 |
100 | tm := time.Unix(txtimesamp.Seconds, 0)
101 | datestr := tm.Format("2006-01-02 03:04:05 PM")
102 |
103 | fmt.Printf(" Tx info - txid : %s value : %s if delete: %t datetime : %s \n ", txid , string(txvalue) , txstatus , datestr )
104 | keys = append( keys , string(txvalue) + ":" + datestr)
105 |
106 | }
107 |
108 |
109 | jsonKeys, err := json.Marshal(keys)
110 | if err != nil {
111 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
112 | }
113 |
114 | return shim.Success(jsonKeys)
115 |
116 |
117 | }else{
118 |
119 | return shim.Success([]byte("success invok and No operation !!!!!!!! "))
120 |
121 |
122 | }
123 | }
124 |
125 |
126 |
127 | func main() {
128 | err := shim.Start( new( dairyfarm ) )
129 | if err != nil {
130 | fmt.Printf("Error starting Simple chaincode: %s", err)
131 | }
132 | }
133 |
134 |
135 |
--------------------------------------------------------------------------------
/origin_machining/origin_machining_cc.go:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | Copyright xuehuiit Corp. 2018 All Rights Reserved.
4 |
5 | http://www.xuehuiit.com
6 |
7 | QQ 411321681
8 |
9 | */
10 |
11 | package main
12 |
13 | import (
14 |
15 | "github.com/hyperledger/fabric/core/chaincode/shim"
16 | pb "github.com/hyperledger/fabric/protos/peer"
17 | "fmt"
18 | "time"
19 | "encoding/json"
20 | )
21 |
22 |
23 | type machining struct {}
24 |
25 |
26 | /**
27 | 系统初始化
28 | */
29 | func (t *machining) Init(stub shim.ChaincodeStubInterface) pb.Response {
30 |
31 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
32 |
33 |
34 | }
35 |
36 | /**
37 | 系统invoke方法
38 | */
39 | func (t *machining) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
40 |
41 |
42 | _,args := stub.GetFunctionAndParameters()
43 |
44 | var opttype = args[0]
45 | var assetname = args[1]
46 | var optcontont = args[2]
47 |
48 | fmt.Printf(" parm is %s %s %s \n " , opttype , assetname , optcontont )
49 |
50 |
51 | if opttype == "putvalue" { //设置
52 |
53 | stub.PutState(assetname,[]byte(optcontont))
54 | return shim.Success( []byte( "success put " + optcontont ) )
55 |
56 |
57 | }else if opttype == "getlastvalue"{ //取值
58 |
59 |
60 | var keyvalue []byte
61 | var err error
62 | keyvalue,err = stub.GetState(assetname)
63 |
64 | if( err != nil ){
65 |
66 | return shim.Error(" finad error! ")
67 | }
68 |
69 | return shim.Success( keyvalue )
70 |
71 |
72 |
73 | }else if opttype == "gethistory"{ //获取交易记录
74 |
75 |
76 | keysIter, err := stub.GetHistoryForKey( assetname );
77 |
78 |
79 | if err != nil {
80 | return shim.Error(fmt.Sprintf("GetHistoryForKey failed. Error accessing state: %s", err))
81 | }
82 | defer keysIter.Close()
83 |
84 | var keys []string
85 |
86 | for keysIter.HasNext() {
87 |
88 | response, iterErr := keysIter.Next()
89 | if iterErr != nil {
90 | return shim.Error(fmt.Sprintf("GetHistoryForKey operation failed. Error accessing state: %s", err))
91 | }
92 | //交易编号
93 | txid := response.TxId
94 | //交易的值
95 | txvalue := response.Value
96 | //当前交易的状态
97 | txstatus := response.IsDelete
98 | //交易发生的时间戳
99 | txtimesamp :=response.Timestamp
100 |
101 | tm := time.Unix(txtimesamp.Seconds, 0)
102 | datestr := tm.Format("2006-01-02 03:04:05 PM")
103 |
104 | fmt.Printf(" Tx info - txid : %s value : %s if delete: %t datetime : %s \n ", txid , string(txvalue) , txstatus , datestr )
105 |
106 | keys = append( keys , string(txvalue) + ":" + datestr )
107 |
108 | }
109 |
110 |
111 | jsonKeys, err := json.Marshal(keys)
112 | if err != nil {
113 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
114 | }
115 |
116 | return shim.Success(jsonKeys)
117 |
118 |
119 | }else{
120 |
121 | return shim.Success([]byte("success invok and No operation !!!!!!!! "))
122 |
123 |
124 | }
125 |
126 |
127 | }
128 |
129 | func main() {
130 | err := shim.Start(new( machining ))
131 | if err != nil {
132 | fmt.Printf("Error starting Simple chaincode: %s", err)
133 | }
134 | }
135 |
136 |
137 |
--------------------------------------------------------------------------------
/origin_salesterminal/origin_salesterminal_cc.go:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | Copyright xuehuiit Corp. 2018 All Rights Reserved.
4 |
5 | http://www.xuehuiit.com
6 |
7 | QQ 411321681
8 |
9 | */
10 |
11 | package main
12 |
13 | import (
14 |
15 | "github.com/hyperledger/fabric/core/chaincode/shim"
16 | pb "github.com/hyperledger/fabric/protos/peer"
17 | "fmt"
18 | "time"
19 | "encoding/json"
20 |
21 | "strings"
22 | )
23 |
24 |
25 | type salesterminal struct {}
26 |
27 |
28 | /**
29 | 系统初始化
30 | */
31 | func (t *salesterminal) Init(stub shim.ChaincodeStubInterface) pb.Response {
32 |
33 | _,args := stub.GetFunctionAndParameters()
34 |
35 | var a_parm = args[0]
36 | var b_parm = args[1]
37 | var c_parm = args[2]
38 |
39 |
40 | fmt.Printf(" parm is %s %s %s \n " , a_parm , b_parm , c_parm )
41 |
42 |
43 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
44 |
45 |
46 | }
47 |
48 | /**
49 | 系统invoke方法
50 | */
51 | func (t *salesterminal) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
52 |
53 |
54 | _,args := stub.GetFunctionAndParameters()
55 |
56 | var opttype = args[0]
57 | var assetname = args[1]
58 | var optcontont = args[2]
59 |
60 | fmt.Printf(" parm is %s %s %s \n " , opttype , assetname , optcontont )
61 |
62 |
63 | if opttype == "putvalue" { //设置
64 |
65 | stub.PutState(assetname,[]byte(optcontont))
66 | return shim.Success( []byte( "success put " + optcontont ) )
67 |
68 |
69 | }else if opttype == "getlastvalue"{ //取值
70 |
71 |
72 | var keyvalue []byte
73 | var err error
74 | keyvalue,err = stub.GetState(assetname)
75 |
76 | if( err != nil ){
77 |
78 | return shim.Error(" finad error! ")
79 | }
80 |
81 | return shim.Success( keyvalue )
82 |
83 |
84 |
85 | }else if opttype == "gethistory"{
86 |
87 |
88 | keysIter, err := stub.GetHistoryForKey( assetname );
89 |
90 | if err != nil {
91 | return shim.Error(fmt.Sprintf("GetHistoryForKey failed. Error accessing state: %s", err))
92 | }
93 | defer keysIter.Close()
94 |
95 | var keys []string
96 |
97 | for keysIter.HasNext() {
98 |
99 | response, iterErr := keysIter.Next()
100 | if iterErr != nil {
101 | return shim.Error(fmt.Sprintf("GetHistoryForKey operation failed. Error accessing state: %s", err))
102 | }
103 | //交易编号
104 | txid := response.TxId
105 | //交易的值
106 | txvalue := response.Value
107 | //当前交易的状态
108 | txstatus := response.IsDelete
109 | //交易发生的时间戳
110 | txtimesamp :=response.Timestamp
111 |
112 | tm := time.Unix(txtimesamp.Seconds, 0)
113 | datestr := tm.Format("2006-01-02 03:04:05 PM")
114 |
115 | fmt.Printf(" Tx info - txid : %s value : %s if delete: %t datetime : %s \n ", txid , string(txvalue) , txstatus , datestr )
116 | keys = append( keys , string(txvalue) + ":" + datestr )
117 |
118 |
119 | }
120 |
121 |
122 | jsonKeys, err := json.Marshal(keys)
123 | if err != nil {
124 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
125 | }
126 |
127 | return shim.Success(jsonKeys)
128 |
129 |
130 | }else if opttype == "getmilkhistory"{ //获取交易记录
131 |
132 |
133 | //获取销售终端的历史记录
134 |
135 | keysIter, err := stub.GetHistoryForKey( assetname );
136 |
137 |
138 | if err != nil {
139 | return shim.Error(fmt.Sprintf("GetHistoryForKey failed. Error accessing state: %s", err))
140 | }
141 | defer keysIter.Close()
142 |
143 | var keys []string
144 | var values []string
145 |
146 | for keysIter.HasNext() {
147 |
148 | response, iterErr := keysIter.Next()
149 | if iterErr != nil {
150 | return shim.Error(fmt.Sprintf("GetHistoryForKey operation failed. Error accessing state: %s", err))
151 | }
152 | //交易编号
153 | txid := response.TxId
154 | //交易的值
155 | txvalue := response.Value
156 | //当前交易的状态
157 | txstatus := response.IsDelete
158 | //交易发生的时间戳
159 | txtimesamp :=response.Timestamp
160 |
161 | tm := time.Unix(txtimesamp.Seconds, 0)
162 | datestr := tm.Format("2006-01-02 03:04:05 PM")
163 |
164 | fmt.Printf(" Tx info - txid : %s value : %s if delete: %t datetime : %s \n ", txid , string(txvalue) , txstatus , datestr )
165 |
166 | keys = append( keys , string(txvalue) + ":" + datestr )
167 |
168 | values = append( values,string(txvalue))
169 |
170 | }
171 |
172 | //获取工厂编号
173 | machiningid := values[0]
174 |
175 | //调用加工厂的chaincode获取加工厂的溯源信息
176 | machining_history_parm := []string{"invoke","gethistory",machiningid,"a"}
177 | queryArgs := make([][]byte, len(machining_history_parm))
178 | for i, arg := range machining_history_parm {
179 | queryArgs[i] = []byte(arg)
180 | }
181 |
182 |
183 | response := stub.InvokeChaincode("cc_machining",queryArgs,"roberttestchannel12")
184 |
185 | if response.Status != shim.OK {
186 | errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload)
187 | fmt.Printf(errStr)
188 | return shim.Error(errStr)
189 | }
190 |
191 | //获取加工的信息
192 | result := string(response.Payload)
193 |
194 | fmt.Printf(" maching info - result : %s \n ", result )
195 |
196 |
197 | var machinginfos []string
198 | if err := json.Unmarshal( []byte(result), &machinginfos); err != nil {
199 |
200 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
201 |
202 | }
203 |
204 |
205 | for _,v := range machinginfos{
206 |
207 | keys = append( keys,v)
208 |
209 | }
210 |
211 |
212 |
213 | milid := machinginfos[0]
214 | fmt.Printf(" mil info - milid : %s \n ", milid )
215 |
216 |
217 | milidarr := strings.Split(milid, ":")
218 | cowid := milidarr[0]
219 |
220 | fmt.Printf(" mil info - cowid : %s \n ", cowid )
221 |
222 | ///=== 通过奶牛的编号获取奶牛的的溯源信息
223 | cow_parms := []string{"invoke","gethistory",cowid,"a"}
224 | queryArgs1 := make([][]byte, len(cow_parms))
225 | for i, arg := range cow_parms {
226 | queryArgs1[i] = []byte(arg)
227 | }
228 |
229 |
230 | cow_response := stub.InvokeChaincode("cc_dairyfarm",queryArgs1,"roberttestchannel12")
231 |
232 | if cow_response.Status != shim.OK {
233 | errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", cow_response.Payload)
234 | fmt.Printf(errStr)
235 | return shim.Error(errStr)
236 | }
237 |
238 |
239 |
240 | cow_result := string(cow_response.Payload)
241 |
242 | fmt.Printf(" cow info - result : %s \n ", cow_result )
243 |
244 |
245 | var cowhistorys []string
246 | if err := json.Unmarshal( []byte(cow_result), &cowhistorys); err != nil {
247 |
248 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
249 |
250 | }
251 |
252 |
253 | for _,v1 := range cowhistorys{
254 |
255 | keys = append( keys,v1)
256 |
257 | }
258 |
259 |
260 |
261 | jsonKeys, err := json.Marshal(keys)
262 | if err != nil {
263 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
264 | }
265 |
266 | return shim.Success(jsonKeys)
267 |
268 |
269 | }else{
270 |
271 | return shim.Success([]byte("success invok and No operation !!!!!!!! "))
272 |
273 |
274 | }
275 |
276 |
277 |
278 | }
279 |
280 |
281 | func main() {
282 | err := shim.Start(new(salesterminal))
283 | if err != nil {
284 | fmt.Printf("Error starting Simple chaincode: %s", err)
285 | }
286 | }
287 |
288 |
289 |
--------------------------------------------------------------------------------
/scfinance/scfinancecc.go:
--------------------------------------------------------------------------------
1 | /**
2 | Copyright xuehuiit Corp. 2018 All Rights Reserved.
3 | http://www.xuehuiit.com
4 | QQ 411321681
5 | */
6 |
7 | package main
8 |
9 | import (
10 |
11 | "github.com/hyperledger/fabric/core/chaincode/shim"
12 | pb "github.com/hyperledger/fabric/protos/peer"
13 | "fmt"
14 | "encoding/json"
15 | "time"
16 | )
17 |
18 |
19 | var asset_name ="asset_name_a"
20 |
21 | type scfinancechaincode struct {}
22 |
23 |
24 | /**
25 | 系统初始化
26 | */
27 | func (t *scfinancechaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
28 |
29 |
30 | fmt.Printf(" Init success \n " )
31 | return shim.Success([]byte(" Init success !!!!!!!! "))
32 |
33 |
34 | }
35 |
36 | /**
37 | 系统invoke方法
38 | */
39 | func (t *scfinancechaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
40 |
41 | _,args := stub.GetFunctionAndParameters()
42 |
43 | var opttype = args[0]
44 | var assetname = args[1]
45 | var optcontont = args[2]
46 |
47 | fmt.Printf(" parm is %s %s %s \n " , opttype , assetname , optcontont )
48 |
49 |
50 | if opttype == "putvalue" { //设置
51 |
52 | stub.PutState(assetname,[]byte(optcontont))
53 | return shim.Success( []byte( "success put " + optcontont ) )
54 |
55 |
56 | }else if opttype == "getlastvalue"{ //取值
57 |
58 |
59 | var keyvalue []byte
60 | var err error
61 | keyvalue,err = stub.GetState(assetname)
62 |
63 | if( err != nil ){
64 |
65 | return shim.Error(" finad error! ")
66 | }
67 |
68 | return shim.Success( keyvalue )
69 |
70 |
71 |
72 | }else if opttype == "gethistory"{ //获取交易记录
73 |
74 |
75 | keysIter, err := stub.GetHistoryForKey( assetname );
76 |
77 |
78 | if err != nil {
79 | return shim.Error(fmt.Sprintf("GetHistoryForKey failed. Error accessing state: %s", err))
80 | }
81 | defer keysIter.Close()
82 |
83 | var keys []string
84 |
85 | for keysIter.HasNext() {
86 |
87 | response, iterErr := keysIter.Next()
88 | if iterErr != nil {
89 | return shim.Error(fmt.Sprintf("GetHistoryForKey operation failed. Error accessing state: %s", err))
90 | }
91 | //交易编号
92 | txid := response.TxId
93 | //交易的值
94 | txvalue := response.Value
95 | //当前交易的状态
96 | txstatus := response.IsDelete
97 | //交易发生的时间戳
98 | txtimesamp :=response.Timestamp
99 |
100 | tm := time.Unix(txtimesamp.Seconds, 0)
101 | datestr := tm.Format("2006-01-02 03:04:05 PM")
102 |
103 | fmt.Printf(" Tx info - txid : %s value : %s if delete: %t datetime : %s \n ", txid , string(txvalue) , txstatus , datestr )
104 | keys = append( keys , txid)
105 |
106 | }
107 |
108 |
109 | jsonKeys, err := json.Marshal(keys)
110 | if err != nil {
111 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
112 | }
113 |
114 | return shim.Success(jsonKeys)
115 |
116 |
117 | }else{
118 |
119 | return shim.Success([]byte("success invok and No operation !!!!!!!! "))
120 |
121 |
122 | }
123 |
124 |
125 |
126 |
127 |
128 | }
129 |
130 |
--------------------------------------------------------------------------------
/simpledemo/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/simpledemo/.idea/simpledemo.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/simpledemo/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | true
31 | DEFINITION_ORDER
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 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/simpledemo/simplechaincode.go:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | Copyright xuehuiit Corp. 2018 All Rights Reserved.
4 |
5 | http://www.xuehuiit.com
6 |
7 | QQ 41132168111
8 |
9 | */
10 |
11 | package main
12 |
13 | import (
14 |
15 | "fmt"
16 | "github.com/hyperledger/fabric/core/chaincode/shim"
17 | pb "github.com/hyperledger/fabric/protos/peer"
18 | //"github.com/hyperledger/fabric/common/util"
19 | "encoding/json"
20 | "strings"
21 | "time"
22 | )
23 |
24 | //定义一个机构体,作为chaincode的主对象,可以是任何符合go语言规范的命名方式
25 | type simplechaincode struct {
26 |
27 | }
28 |
29 |
30 | /**
31 |
32 | 系统初始化方法, 在部署chaincode的过程中当执行命令
33 |
34 | peer chaincode instantiate -o orderer.robertfabrictest.com:7050 -C
35 | roberttestchannel -n r_test_cc6 -v 1.0 -c '{"Args":["init","a","100","b","200"]}'
36 | -P "OR ('Org1MSP.member','Org2MSP.member')"
37 |
38 | 的时候会调用该方法
39 |
40 |
41 | https://github.com/hyperledger/fabric/blob/release/core/chaincode/shim/interfaces.go 所有的注释这里
42 |
43 | */
44 | func (t *simplechaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
45 |
46 | fmt.Println(" << ======== success init it is view in docker ========== >> ")
47 | return shim.Success([]byte("success init "))
48 | }
49 |
50 | /**
51 |
52 | 主业务逻辑,在执行命令
53 | peer chaincode invoke -o 192.168.23.212:7050 -C roberttestchannel -n r_test_cc6 -c '{"Args":["invoke","a","b","1"]}'
54 |
55 | 的时候系统会调用该方法并传入相关的参数,注意 "invoke" 之后的参数是需要传入的参数
56 |
57 |
58 | */
59 | func (t *simplechaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
60 |
61 |
62 | _,args := stub.GetFunctionAndParameters()
63 |
64 | var a_parm = args[0]
65 | var b_parm = args[1]
66 | var c_parm = args[2]
67 |
68 |
69 | fmt.Println(" ======== 1、success it is view in docker ========== ")
70 | fmt.Println(" ======== 2、success it is view in docker ========== ")
71 | fmt.Println(" ======== 3、success it is view in docker ========== ")
72 | fmt.Println(" ======== 4、success it is view in docker ========== ")
73 |
74 |
75 | fmt.Printf(" parm is %s %s %s \n " , a_parm , b_parm , c_parm )
76 |
77 |
78 | // 设定值
79 | if a_parm == "set"{
80 |
81 | stub.PutState(b_parm,[]byte(c_parm))
82 | return shim.Success( []byte( "success invok " + c_parm ) )
83 |
84 | }else if a_parm == "get"{ //取单个值
85 |
86 | var keyvalue []byte
87 | var err error
88 | keyvalue,err = stub.GetState(b_parm)
89 |
90 | if( err != nil ){
91 |
92 | return shim.Error(" finad error! ")
93 | }
94 |
95 |
96 | return shim.Success( keyvalue )
97 |
98 |
99 |
100 | }else if a_parm == "CreateCompositeKeyandset" { // 设置一个复合键的值
101 |
102 | //parms := []string{ "c_1" , "d_1" , "e_1","f_1","g_1","h_1" }
103 | parms := strings.Split(c_parm,",")
104 | ckey ,_ := stub.CreateCompositeKey(b_parm,parms)
105 |
106 | fmt.Println(" ======== GetStateByPartialCompositeKey ========== ",ckey)
107 |
108 |
109 | err := stub.PutState(ckey , []byte(c_parm) )
110 |
111 | if err !=nil{
112 |
113 | fmt.Println("CreateCompositeKeyandset() : Error inserting Object into State Database %s", err)
114 | }
115 |
116 |
117 | return shim.Success([]byte(ckey))
118 |
119 |
120 |
121 | }else if a_parm == "GetStateByPartialCompositeKey" { // 设置一个复合键的值
122 |
123 |
124 | fmt.Println(" ======== GetStateByPartialCompositeKey ========== ")
125 |
126 | searchparm := strings.Split(c_parm,",")
127 | rs, err := stub.GetStateByPartialCompositeKey(b_parm,searchparm)
128 | if err != nil {
129 | error_str := fmt.Sprintf("GetListOfInitAucs operation failed. Error marshaling JSON: %s", err)
130 | return shim.Error(error_str)
131 | }
132 |
133 | defer rs.Close()
134 |
135 | // Iterate through result set
136 | var i int
137 | var tlist []string // Define a list
138 | for i = 0; rs.HasNext(); i++ {
139 |
140 | // We can process whichever return value is of interest
141 | responseRange, err := rs.Next()
142 |
143 | if err != nil {
144 | error_str := fmt.Sprintf("GetListOfInitAucs() operation failed - Unmarshall Error. %s", err)
145 | fmt.Println(error_str)
146 | return shim.Error(error_str)
147 | }
148 |
149 | objectType, compositeKeyParts, _ := stub.SplitCompositeKey(responseRange.Key)
150 |
151 | /*fmt.Println(" objectType value is "+objectType)
152 | fmt.Println(compositeKeyParts)*/
153 |
154 | returnedColor := compositeKeyParts[0]
155 | returnedMarbleName := compositeKeyParts[1]
156 | fmt.Printf("- found a marble from index:%s color:%s name:%s\n", objectType, returnedColor, returnedMarbleName)
157 |
158 | /*for index, attr := range attributes {
159 |
160 | fmt.Sprintf(" The arrt is : index: => %d , the arrt -> %s " ,index,attr)
161 |
162 | }*/
163 |
164 |
165 | tlist = append(tlist, responseRange.Key)
166 | }
167 |
168 | jsonRows, err := json.Marshal(tlist)
169 | if err != nil {
170 | error_str := fmt.Sprintf("GetListOfInitAucs() operation failed - Unmarshall Error. %s", err)
171 | fmt.Println(error_str)
172 | return shim.Error(error_str)
173 | }
174 |
175 |
176 |
177 | //fmt.Println("List of Auctions Requested : ", jsonRows)
178 | return shim.Success(jsonRows)
179 |
180 | //return shim.Success([]byte("dddd"))
181 |
182 |
183 |
184 | }else if a_parm == "delete" { //删除某个值
185 |
186 |
187 | fmt.Println(" ======== delete ========== %s ",b_parm)
188 |
189 | err := stub.DelState(b_parm)
190 |
191 | if err != nil {
192 | return shim.Error(" 删除出现错误!!!!!")
193 | }
194 |
195 | return shim.Success([]byte(" 删除正确!!!!! "))
196 |
197 |
198 | }else if a_parm == "getStatebyrange" { //查询制定范围内的键值 ,目前没有
199 |
200 |
201 | fmt.Println(" ======== getStatebyrange ========== ")
202 |
203 | startkey := b_parm
204 | endkey := c_parm
205 |
206 | keysIter, err := stub.GetStateByRange( startkey , endkey )
207 |
208 | if err != nil {
209 | return shim.Error(fmt.Sprintf("keys operation failed. Error accessing state: %s", err))
210 | }
211 |
212 | defer keysIter.Close()
213 |
214 | var keys []string
215 |
216 | for keysIter.HasNext(){
217 |
218 | response,iterErr := keysIter.Next()
219 |
220 | if iterErr != nil{
221 | return shim.Error(fmt.Sprintf("find an error %s",iterErr))
222 | }
223 |
224 | keys = append(keys, response.Key)
225 |
226 | }
227 |
228 | for key, value := range keys {
229 | fmt.Printf("key %d contains %s\n", key, value)
230 | }
231 |
232 |
233 | jsonKeys, err := json.Marshal(keys)
234 | if err != nil {
235 | return shim.Error(fmt.Sprintf("keys operation failed. Error marshaling JSON: %s", err))
236 | }
237 |
238 | return shim.Success(jsonKeys)
239 |
240 |
241 |
242 | }else if a_parm == "GetHistoryForKey" { //取单个值的历史记录
243 |
244 | keysIter, err := stub.GetHistoryForKey(b_parm);
245 |
246 |
247 | if err != nil {
248 | return shim.Error(fmt.Sprintf("GetHistoryForKey failed. Error accessing state: %s", err))
249 | }
250 | defer keysIter.Close()
251 |
252 | var keys []string
253 |
254 | for keysIter.HasNext() {
255 |
256 | response, iterErr := keysIter.Next()
257 | if iterErr != nil {
258 | return shim.Error(fmt.Sprintf("GetHistoryForKey operation failed. Error accessing state: %s", err))
259 | }
260 |
261 | //交易编号
262 | txid := response.TxId
263 | //交易的值
264 | txvalue := response.Value
265 | //当前交易的状态
266 | txstatus := response.IsDelete
267 | //交易发生的时间戳
268 | txtimesamp :=response.Timestamp
269 |
270 | tm := time.Unix(txtimesamp.Seconds, 0)
271 | datestr := tm.Format("2006-01-02 03:04:05 PM")
272 |
273 |
274 | fmt.Printf(" Tx info - txid : %s value : %s if delete: %t datetime : %s \n ", txid , string(txvalue) , txstatus , datestr )
275 |
276 | keys = append( keys , txid)
277 |
278 | }
279 |
280 |
281 | jsonKeys, err := json.Marshal(keys)
282 | if err != nil {
283 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
284 | }
285 |
286 | return shim.Success(jsonKeys)
287 |
288 |
289 | }else if a_parm == "GetTxID" { //获取当前交易的编号
290 |
291 | txid := stub.GetTxID();
292 | fmt.Println(" ======== GetTxID ========== %s ",txid)
293 | return shim.Success([]byte(txid))
294 |
295 |
296 | }else if a_parm == "GetTxTimestamp" { //获取当前时间
297 |
298 |
299 | txtime,err:= stub.GetTxTimestamp()
300 | if err != nil {
301 | fmt.Printf("Error getting transaction timestamp: %s", err)
302 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err))
303 | }
304 |
305 |
306 | tm := time.Unix(txtime.Seconds, 0)
307 |
308 | fmt.Printf("Transaction Time: %v \n ", tm.Format("2006-01-02 03:04:05 PM"))
309 |
310 | return shim.Success([]byte(fmt.Sprint(" time is : %s ",tm.Format("2006-01-02 15:04:05"))))
311 |
312 |
313 | }else if a_parm == "GetBinding" { //取单个值
314 |
315 |
316 | bindtype , err := stub.GetBinding()
317 |
318 | if err != nil {
319 | fmt.Printf("Error getting transaction timestamp: %s", err)
320 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err))
321 | }
322 |
323 | fmt.Printf("GetBinding : %s \n ", string(bindtype[:]) )
324 |
325 | return shim.Success(bindtype)
326 |
327 | }else if a_parm == "GetSignedProposal" { //取单个值
328 |
329 |
330 | stub.GetSignedProposal()
331 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
332 |
333 |
334 | }else if a_parm == "GetCreator" { //取访问请求者的证书
335 |
336 | createbytes , err := stub.GetCreator()
337 |
338 | if err != nil {
339 | fmt.Printf("Error getting transaction timestamp: %s", err)
340 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err))
341 | }
342 |
343 | return shim.Success(createbytes)
344 |
345 |
346 | }else if a_parm == "GetTransient" { //获取单个值的方式
347 |
348 | transient,err := stub.GetTransient()
349 |
350 | if err != nil {
351 | fmt.Printf("Error getting transaction timestamp: %s", err)
352 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err))
353 | }
354 |
355 | for key := range transient {
356 | fmt.Printf(" the %s and value is %s \n", key, string(transient[key]));
357 | }
358 |
359 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
360 |
361 | }else if a_parm == "setloglevel" { //获取单个值的方式
362 |
363 | logleve , _ := shim.LogLevel("dubug")
364 | shim.SetLoggingLevel(logleve)
365 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
366 |
367 | }else if a_parm == "InvokeChaincode" { //获取单个值的方式
368 |
369 |
370 | //queryArgs := util.ToChaincodeArgs("query", "GetCreator","akeym","11234343")
371 |
372 | //parms1 := []string{ "query", "GetCreator","akeym","11234343" }
373 | parms1 := []string{"query","a"}
374 | queryArgs := make([][]byte, len(parms1))
375 | for i, arg := range parms1 {
376 | queryArgs[i] = []byte(arg)
377 | }
378 |
379 |
380 | response := stub.InvokeChaincode("cc_endfinlshed",queryArgs,"roberttestchannel12")
381 |
382 | if response.Status != shim.OK {
383 | errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload)
384 | fmt.Printf(errStr)
385 | return shim.Error(errStr)
386 | }
387 |
388 | result := string(response.Payload)
389 |
390 |
391 |
392 | fmt.Printf(" invoke chaincode %s " ,result)
393 |
394 | return shim.Success([]byte("success InvokeChaincode and Not opter !!!!!!!! " + result))
395 |
396 | }else{
397 |
398 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
399 |
400 | }
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 | }
410 |
411 |
412 | func main() {
413 | err := shim.Start(new(simplechaincode))
414 | if err != nil {
415 | fmt.Printf("Error starting Simple chaincode: %s", err)
416 | }
417 | }
418 |
419 |
420 |
--------------------------------------------------------------------------------
/simpledemo/simplechaincode_test.go:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | Copyright xuehuiit Corp. 2018 All Rights Reserved.
4 |
5 | http://www.xuehuiit.com
6 |
7 | QQ 411321681
8 |
9 | */
10 |
11 | package main
12 |
13 | import (
14 | //"fmt"
15 | "testing"
16 | "github.com/hyperledger/fabric/core/chaincode/shim"
17 | "fmt"
18 | )
19 |
20 |
21 | func checkInit(t *testing.T, stub *shim.MockStub, args [][]byte){
22 |
23 | res := stub.MockInit("1", args)
24 | if res.Status != shim.OK {
25 | fmt.Println("Init failed", string(res.Message))
26 | t.FailNow()
27 | }
28 | }
29 |
30 |
31 | func TestExample02_Init(t *testing.T) {
32 |
33 | scc := new(simplechaincode)
34 | stub := shim.NewMockStub("ex02", scc)
35 |
36 |
37 | checkInit(t, stub, [][]byte{[]byte("init"), []byte("A"), []byte("123"), []byte("B"), []byte("234")})
38 |
39 |
40 | }
--------------------------------------------------------------------------------
/simpledemo2/simplechaincode2.go:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | Copyright xuehuiit Corp. 2018 All Rights Reserved.
4 |
5 | http://www.xuehuiit.com
6 |
7 | QQ 41132168111
8 |
9 | */
10 |
11 | package main
12 |
13 | import (
14 |
15 | "fmt"
16 | "github.com/hyperledger/fabric/core/chaincode/shim"
17 | pb "github.com/hyperledger/fabric/protos/peer"
18 | //"github.com/hyperledger/fabric/common/util"
19 | "encoding/json"
20 | "strings"
21 | "time"
22 | )
23 |
24 | //定义一个机构体,作为chaincode的主对象,可以是任何符合go语言规范的命名方式
25 | type simplechaincode struct {
26 |
27 | }
28 |
29 |
30 | /**
31 |
32 | 系统初始化方法, 在部署chaincode的过程中当执行命令
33 |
34 | peer chaincode instantiate -o orderer.robertfabrictest.com:7050 -C
35 | roberttestchannel -n r_test_cc6 -v 1.0 -c '{"Args":["init","a","100","b","200"]}'
36 | -P "OR ('Org1MSP.member','Org2MSP.member')"
37 |
38 | 的时候会调用该方法
39 |
40 |
41 | https://github.com/hyperledger/fabric/blob/release/core/chaincode/shim/interfaces.go 所有的注释这里
42 |
43 | */
44 | func (t *simplechaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
45 |
46 | fmt.Println(" << ======== success init it is view in docker ========== >> ")
47 | return shim.Success([]byte("success init "))
48 | }
49 |
50 | /**
51 |
52 | 主业务逻辑,在执行命令
53 | peer chaincode invoke -o 192.168.23.212:7050 -C roberttestchannel -n r_test_cc6 -c '{"Args":["invoke","a","b","1"]}'
54 |
55 | 的时候系统会调用该方法并传入相关的参数,注意 "invoke" 之后的参数是需要传入的参数
56 |
57 |
58 | */
59 | func (t *simplechaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
60 |
61 |
62 | _,args := stub.GetFunctionAndParameters()
63 |
64 | var a_parm = args[0]
65 | var b_parm = args[1]
66 | var c_parm = args[2]
67 |
68 |
69 | fmt.Println(" ======== 1、success it is view in docker ========== ")
70 | fmt.Println(" ======== 2、success it is view in docker ========== ")
71 | fmt.Println(" ======== 3、success it is view in docker ========== ")
72 | fmt.Println(" ======== 4、success it is view in docker ========== ")
73 |
74 |
75 | fmt.Printf(" parm is %s %s %s \n " , a_parm , b_parm , c_parm )
76 |
77 |
78 | // 设定值
79 | if a_parm == "set"{
80 |
81 | stub.PutState(b_parm,[]byte(c_parm))
82 | return shim.Success( []byte( "success invok " + c_parm ) )
83 |
84 | }else if a_parm == "get"{ //取单个值
85 |
86 | var keyvalue []byte
87 | var err error
88 | keyvalue,err = stub.GetState(b_parm)
89 |
90 | if( err != nil ){
91 |
92 | return shim.Error(" finad error! ")
93 | }
94 |
95 |
96 | return shim.Success( keyvalue )
97 |
98 |
99 |
100 | }else if a_parm == "CreateCompositeKeyandset" { // 设置一个复合键的值
101 |
102 | //parms := []string{ "c_1" , "d_1" , "e_1","f_1","g_1","h_1" }
103 | parms := strings.Split(c_parm,",")
104 | ckey ,_ := stub.CreateCompositeKey(b_parm,parms)
105 |
106 | fmt.Println(" ======== GetStateByPartialCompositeKey ========== ",ckey)
107 |
108 |
109 | err := stub.PutState(ckey , []byte(c_parm) )
110 |
111 | if err !=nil{
112 |
113 | fmt.Println("CreateCompositeKeyandset() : Error inserting Object into State Database %s", err)
114 | }
115 |
116 |
117 | return shim.Success([]byte(ckey))
118 |
119 |
120 |
121 | }else if a_parm == "GetStateByPartialCompositeKey" { // 设置一个复合键的值
122 |
123 |
124 | fmt.Println(" ======== GetStateByPartialCompositeKey ========== ")
125 |
126 | searchparm := strings.Split(c_parm,",")
127 | rs, err := stub.GetStateByPartialCompositeKey(b_parm,searchparm)
128 | if err != nil {
129 | error_str := fmt.Sprintf("GetListOfInitAucs operation failed. Error marshaling JSON: %s", err)
130 | return shim.Error(error_str)
131 | }
132 |
133 | defer rs.Close()
134 |
135 | // Iterate through result set
136 | var i int
137 | var tlist []string // Define a list
138 | for i = 0; rs.HasNext(); i++ {
139 |
140 | // We can process whichever return value is of interest
141 | responseRange, err := rs.Next()
142 |
143 | if err != nil {
144 | error_str := fmt.Sprintf("GetListOfInitAucs() operation failed - Unmarshall Error. %s", err)
145 | fmt.Println(error_str)
146 | return shim.Error(error_str)
147 | }
148 |
149 | objectType, compositeKeyParts, _ := stub.SplitCompositeKey(responseRange.Key)
150 |
151 | /*fmt.Println(" objectType value is "+objectType)
152 | fmt.Println(compositeKeyParts)*/
153 |
154 | returnedColor := compositeKeyParts[0]
155 | returnedMarbleName := compositeKeyParts[1]
156 | fmt.Printf("- found a marble from index:%s color:%s name:%s\n", objectType, returnedColor, returnedMarbleName)
157 |
158 | /*for index, attr := range attributes {
159 |
160 | fmt.Sprintf(" The arrt is : index: => %d , the arrt -> %s " ,index,attr)
161 |
162 | }*/
163 |
164 |
165 | tlist = append(tlist, responseRange.Key)
166 | }
167 |
168 | jsonRows, err := json.Marshal(tlist)
169 | if err != nil {
170 | error_str := fmt.Sprintf("GetListOfInitAucs() operation failed - Unmarshall Error. %s", err)
171 | fmt.Println(error_str)
172 | return shim.Error(error_str)
173 | }
174 |
175 |
176 |
177 | //fmt.Println("List of Auctions Requested : ", jsonRows)
178 | return shim.Success(jsonRows)
179 |
180 | //return shim.Success([]byte("dddd"))
181 |
182 |
183 |
184 | }else if a_parm == "delete" { //删除某个值
185 |
186 |
187 | fmt.Println(" ======== delete ========== %s ",b_parm)
188 |
189 | err := stub.DelState(b_parm)
190 |
191 | if err != nil {
192 | return shim.Error(" 删除出现错误!!!!!")
193 | }
194 |
195 | return shim.Success([]byte(" 删除正确!!!!! "))
196 |
197 |
198 | }else if a_parm == "getStatebyrange" { //查询制定范围内的键值 ,目前没有
199 |
200 |
201 | fmt.Println(" ======== getStatebyrange ========== ")
202 |
203 | startkey := b_parm
204 | endkey := c_parm
205 |
206 | keysIter, err := stub.GetStateByRange( startkey , endkey )
207 |
208 | if err != nil {
209 | return shim.Error(fmt.Sprintf("keys operation failed. Error accessing state: %s", err))
210 | }
211 |
212 | defer keysIter.Close()
213 |
214 | var keys []string
215 |
216 | for keysIter.HasNext(){
217 |
218 | response,iterErr := keysIter.Next()
219 |
220 | if iterErr != nil{
221 | return shim.Error(fmt.Sprintf("find an error %s",iterErr))
222 | }
223 |
224 | keys = append(keys, response.Key)
225 |
226 | }
227 |
228 | for key, value := range keys {
229 | fmt.Printf("key %d contains %s\n", key, value)
230 | }
231 |
232 |
233 | jsonKeys, err := json.Marshal(keys)
234 | if err != nil {
235 | return shim.Error(fmt.Sprintf("keys operation failed. Error marshaling JSON: %s", err))
236 | }
237 |
238 | return shim.Success(jsonKeys)
239 |
240 |
241 |
242 | }else if a_parm == "GetHistoryForKey" { //取单个值的历史记录
243 |
244 | keysIter, err := stub.GetHistoryForKey(b_parm);
245 |
246 |
247 | if err != nil {
248 | return shim.Error(fmt.Sprintf("GetHistoryForKey failed. Error accessing state: %s", err))
249 | }
250 | defer keysIter.Close()
251 |
252 | var keys []string
253 |
254 | for keysIter.HasNext() {
255 |
256 | response, iterErr := keysIter.Next()
257 | if iterErr != nil {
258 | return shim.Error(fmt.Sprintf("GetHistoryForKey operation failed. Error accessing state: %s", err))
259 | }
260 |
261 | //交易编号
262 | txid := response.TxId
263 | //交易的值
264 | txvalue := response.Value
265 | //当前交易的状态
266 | txstatus := response.IsDelete
267 | //交易发生的时间戳
268 | txtimesamp :=response.Timestamp
269 |
270 | tm := time.Unix(txtimesamp.Seconds, 0)
271 | datestr := tm.Format("2006-01-02 03:04:05 PM")
272 |
273 |
274 | fmt.Printf(" Tx info - txid : %s value : %s if delete: %t datetime : %s \n ", txid , string(txvalue) , txstatus , datestr )
275 |
276 | keys = append( keys , txid)
277 |
278 |
279 |
280 |
281 | }
282 |
283 |
284 | jsonKeys, err := json.Marshal(keys)
285 | if err != nil {
286 | return shim.Error(fmt.Sprintf("query operation failed. Error marshaling JSON: %s", err))
287 | }
288 |
289 | return shim.Success(jsonKeys)
290 |
291 |
292 | }else if a_parm == "GetTxID" { //获取当前交易的编号
293 |
294 | txid := stub.GetTxID();
295 | fmt.Println(" ======== GetTxID ========== %s ",txid)
296 | return shim.Success([]byte(txid))
297 |
298 |
299 | }else if a_parm == "GetTxTimestamp" { //获取当前时间
300 |
301 |
302 | txtime,err:= stub.GetTxTimestamp()
303 | if err != nil {
304 | fmt.Printf("Error getting transaction timestamp: %s", err)
305 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err))
306 | }
307 |
308 |
309 | tm := time.Unix(txtime.Seconds, 0)
310 |
311 | fmt.Printf("Transaction Time: %v \n ", tm.Format("2006-01-02 03:04:05 PM"))
312 |
313 | return shim.Success([]byte(fmt.Sprint(" time is : %s ",tm.Format("2006-01-02 15:04:05"))))
314 |
315 |
316 | }else if a_parm == "GetBinding" { //取单个值
317 |
318 |
319 | bindtype , err := stub.GetBinding()
320 |
321 | if err != nil {
322 | fmt.Printf("Error getting transaction timestamp: %s", err)
323 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err))
324 | }
325 |
326 | fmt.Printf("GetBinding : %s \n ", string(bindtype[:]) )
327 |
328 | return shim.Success(bindtype)
329 |
330 | }else if a_parm == "GetSignedProposal" { //取单个值
331 |
332 |
333 | stub.GetSignedProposal()
334 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
335 |
336 |
337 | }else if a_parm == "GetCreator" { //取访问请求者的证书
338 |
339 | createbytes , err := stub.GetCreator()
340 |
341 | if err != nil {
342 | fmt.Printf("Error getting transaction timestamp: %s", err)
343 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err))
344 | }
345 |
346 | return shim.Success(createbytes)
347 |
348 |
349 | }else if a_parm == "GetTransient" { //获取单个值的方式
350 |
351 | transient,err := stub.GetTransient()
352 |
353 | if err != nil {
354 | fmt.Printf("Error getting transaction timestamp: %s", err)
355 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err))
356 | }
357 |
358 | for key := range transient {
359 | fmt.Printf(" the %s and value is %s \n", key, string(transient[key]));
360 | }
361 |
362 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
363 |
364 | }else if a_parm == "setloglevel" { //获取单个值的方式
365 |
366 | logleve , _ := shim.LogLevel("dubug")
367 | shim.SetLoggingLevel(logleve)
368 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
369 |
370 | }else if a_parm == "InvokeChaincode" { //获取单个值的方式
371 |
372 |
373 | //queryArgs := util.ToChaincodeArgs("query", "GetCreator","akeym","11234343")
374 |
375 | //parms1 := []string{ "query", "GetCreator","akeym","11234343" }
376 | parms1 := []string{"query","a"}
377 | queryArgs := make([][]byte, len(parms1))
378 | for i, arg := range parms1 {
379 | queryArgs[i] = []byte(arg)
380 | }
381 |
382 |
383 | response := stub.InvokeChaincode("cc_endfinlshed",queryArgs,"roberttestchannel12")
384 |
385 | if response.Status != shim.OK {
386 | errStr := fmt.Sprintf("Failed to query chaincode. Got error: %s", response.Payload)
387 | fmt.Printf(errStr)
388 | return shim.Error(errStr)
389 | }
390 |
391 | result := string(response.Payload)
392 |
393 |
394 |
395 | fmt.Printf(" invoke chaincode %s " ,result)
396 |
397 | return shim.Success([]byte("success InvokeChaincode and Not opter !!!!!!!! " + result))
398 |
399 | }else{
400 |
401 |
402 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
403 |
404 | }
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 | }
414 |
415 |
416 | func main() {
417 | err := shim.Start(new(simplechaincode))
418 | if err != nil {
419 | fmt.Printf("Error starting Simple chaincode: %s", err)
420 | }
421 | }
422 |
423 |
424 |
--------------------------------------------------------------------------------
/simplegyljr/simplechaincode.go:
--------------------------------------------------------------------------------
1 |
2 | package main
3 |
4 | import (
5 |
6 | "fmt"
7 | "github.com/hyperledger/fabric/core/chaincode/shim"
8 | pb "github.com/hyperledger/fabric/protos/peer"
9 | //"github.com/hyperledger/fabric/common/util"
10 | )
11 |
12 | type gylchaincode struct {
13 |
14 | }
15 |
16 | func (t *gylchaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
17 | return shim.Success([]byte("success init "))
18 | }
19 |
20 |
21 | func (t *gylchaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
22 |
23 |
24 | _,args := stub.GetFunctionAndParameters()
25 |
26 | var a_parm = args[0]
27 | var b_parm = args[1]
28 | var c_parm = args[2]
29 |
30 |
31 |
32 | fmt.Printf(" parm is %s %s %s \n " , a_parm , b_parm , c_parm )
33 |
34 |
35 | // 保存交易数据
36 | if a_parm == "set"{
37 |
38 | stub.PutState(b_parm,[]byte(c_parm))
39 | return shim.Success( []byte( "success invok " + c_parm ) )
40 |
41 | }else if a_parm == "get"{ //查询交易数据
42 |
43 | var keyvalue []byte
44 | var err error
45 | keyvalue,err = stub.GetState(b_parm)
46 |
47 | if( err != nil ){
48 |
49 | return shim.Error(" finad error! ")
50 | }
51 |
52 |
53 | return shim.Success( keyvalue )
54 |
55 |
56 | }else{
57 |
58 |
59 | return shim.Success([]byte("success invok and Not opter !!!!!!!! "))
60 |
61 | }
62 |
63 |
64 | }
65 |
66 |
67 | func main() {
68 | err := shim.Start(new(gylchaincode))
69 | if err != nil {
70 | fmt.Printf("Error starting Simple chaincode: %s", err)
71 | }
72 | }
73 |
74 |
75 |
--------------------------------------------------------------------------------
/study/chaincodetest.go:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | Copyright xuehuiit Corp. 2018 All Rights Reserved.
4 |
5 | http://www.xuehuiit.com
6 |
7 | QQ 411321687
8 |
9 | */
10 |
11 | package main
12 |
13 | import (
14 |
15 |
16 | "fmt"
17 |
18 | "github.com/hyperledger/fabric/core/chaincode/shim"
19 | pb "github.com/hyperledger/fabric/protos/peer"
20 |
21 | "strconv"
22 | )
23 |
24 | //定义一个机构体,作为chaincode的主对象,可以是任何符合go语言规范的命名方式
25 |
26 | type chainCodeStudy1 struct {
27 |
28 | }
29 |
30 |
31 | var A, B string
32 | var Aval, Bval, X int
33 |
34 |
35 |
36 | /**
37 | 系统初始化方法, 在部署chaincode的过程中当执行命令
38 |
39 | peer chaincode instantiate -o orderer.robertfabrictest.com:7050 -C
40 | roberttestchannel -n r_test_cc6 -v 1.0 -c '{"Args":["init","a","100","b","200"]}'
41 | -P "OR ('Org1MSP.member','Org2MSP.member')"
42 |
43 | 的时候会调用该方法
44 |
45 |
46 | */
47 | func (t *chainCodeStudy1) Init(stub shim.ChaincodeStubInterface) pb.Response {
48 |
49 |
50 | var err error
51 |
52 |
53 | //获取传入参数值,在端采用数组的方式传入相关的参数
54 | _, args := stub.GetFunctionAndParameters()
55 |
56 |
57 |
58 | if len(args) != 4 {
59 |
60 | errinfo := fmt.Sprint(" 参数值错误 . Expecting 4 , 传入值为 %d",len(args))
61 | return shim.Error(errinfo)
62 | }
63 |
64 | // 获取第一个和第二个参数,并验证
65 |
66 | A = args[0]
67 | Aval, err = strconv.Atoi(args[1])
68 | if err != nil {
69 | return shim.Error("参数错误,不是数字")
70 | }
71 |
72 | //获取第三个和第四个参数并验证
73 | B = args[2]
74 | Bval, err = strconv.Atoi(args[3])
75 | if err != nil {
76 | return shim.Error("参数错误,不是数字")
77 | }
78 | fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
79 |
80 | /************
81 | // Write the state to the ledger
82 | err = stub.PutState(A, []byte(strconv.Itoa(Aval))
83 | if err != nil {
84 | return nil, err
85 | }
86 |
87 | stub.PutState(B, []byte(strconv.Itoa(Bval))
88 | err = stub.PutState(B, []byte(strconv.Itoa(Bval))
89 | if err != nil {
90 | return nil, err
91 | }
92 | ************/
93 | return shim.Success(nil)
94 | }
95 |
96 | /**
97 |
98 | 主业务逻辑,在执行命令
99 | peer chaincode invoke -o 192.168.23.212:7050 -C roberttestchannel -n r_test_cc6 -c '{"Args":["invoke","a","b","1"]}'
100 |
101 | 的时候系统会调用该方法并传入相关的参数,注意 "invoke" 之后的参数是需要传入的参数
102 |
103 |
104 |
105 | */
106 | func (t *chainCodeStudy1) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
107 |
108 |
109 | function, args := stub.GetFunctionAndParameters()
110 | if function == "invoke" {
111 | return t.invoke(stub, args)
112 | }
113 |
114 | return shim.Error("Invalid invoke function name. Expecting \"invoke\"")
115 |
116 |
117 | }
118 |
119 |
120 | /**
121 |
122 | 业务方法,以为chaincode对外提供的业务接口只有 Invoke方法,如果业务逻辑比较发展,可以将相关的业务分成多个方法,然后在
123 | Invoke 方法中调用这些方法,
124 |
125 | 本方法是其中的一个业务方法,本方法模拟从账号A,转账X 给账户B
126 |
127 | */
128 | func (t *chainCodeStudy1) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
129 |
130 | // Transaction makes payment of X units from A to B
131 | X, err := strconv.Atoi(args[0])
132 | if err != nil {
133 | fmt.Printf("这是服务器的信息 只能显示在服务器端 ", args[0], err)
134 | return shim.Error( fmt.Sprintf(" 参数 %s 转换时发生错误 %s !!!!! " , args[0] , err ) )
135 | }
136 |
137 | Aval = Aval - X
138 | Bval = Bval + X
139 | ts, err2 := stub.GetTxTimestamp()
140 |
141 |
142 | if err2 != nil {
143 | fmt.Printf("Error getting transaction timestamp: %s", err2)
144 | return shim.Error(fmt.Sprintf("Error getting transaction timestamp: %s", err2))
145 | }
146 |
147 | fmt.Printf("Transaction Time: %v,Aval = %d, Bval = %d\n", ts, Aval, Bval)
148 | return shim.Success(nil)
149 | }
150 |
151 | func main() {
152 | err := shim.Start(new(chainCodeStudy1))
153 | if err != nil {
154 | fmt.Printf("Error starting Simple chaincode: %s", err)
155 | }
156 | }
--------------------------------------------------------------------------------