- 第 1 章 区块链
- 第 2 章 以太坊
- 第 3 章 以太坊私链入门
- 第 4 章 以太坊网络
- 第 5 章 geth v1.8.16 命令详解
- 第 6 章 Wallet
- 第 7 章 Token
- 第 8 章 智能合约语言 Solidity v0.5.0
- 第 9 章 Truffle v4.1.8 开发框架
- 第 10 章 web3.js - 1.0.0
- 第 11 章 web3j v3.4.0 - Jave Client
- 11.2. 启动以太坊
- 11.3. Maven pom.xml 文件
- 11.4. Java 与 Solidity 数据类型映射关系
- 11.5. 常量
- 11.6. 连接到服务器获取版本号
- 11.7. 获得以太坊状态信息
- 11.8. 单位转换
- 11.9. 账号管理
- 11.10. Credentials
- 11.11. 交易
- 11.12. 钱包
- 11.13. 智能合约
- 11.14. ERC20合约
- 11.15. Infura
- 11.16. 助记词
- 11.17. 过滤器 (Filter)
- 11.18. Subscription
- 11.19. 解锁账号
- 11.20. IBAN (International Bank Account Number)
- 11.21. Springboot with Ethereum (web3j)
- 第 12 章 web3.py - A python interface for interacting with the Ethereum blockchain and ecosystem.
- 第 14 章 Ethereum Developer APIs
- 第 15 章 infura
- 第 16 章 以太坊案例
- 第 17 章 FAQ
- 17.3. Error: authentication needed: password or unlock
- 17.4. 新增节点后不生效
- 17.5. Unhandled rejection Error: Returned error: The method personal_unlockAccount does not exist/is not available
- 17.6. Error: exceeds block gas limit
- 17.7. Migrations.sol:11:3: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(…) { … }" instead.
- 17.8. Exception in thread "main" rx.exceptions.OnErrorNotImplementedException: Invalid response received: okhttp3.internal.http.RealResponseBody@6c25e6c4
- 17.9. 旧版本 Remix(browser-solidity) 本地安装
- 第 18 章 Hyperledger Fabric v2.0.0
- 第 19 章 Hyperledger Fabric 运维
- 第 20 章 Chaincode 链码(智能合约)
- 第 21 章 Hyperledger Fabric Client SDK for Node.js
- 第 22 章 fabric-sdk-java
- 第 24 章 已知 Hyperledger 落地案例
- 第 25 章 Fabric Command
- 第 26 章 Fabric FAQ
- 第 27 章 IPFS(InterPlanetary File System,星际文件系统)
- 第 28 章 IPFS 命令
- 第 29 章 IPFS WebUI
- 第 30 章 IPFS 集群配置
- 第 31 章 IPFS API
- 第 32 章 IPFS Faq
- 第 33 章 EOS
- 第 34 章 EOS 安装
- 第 35 章 CLEOS
- 第 36 章 智能合约开发
- 第 37 章 EOS Dapp 开发
- 第 38 章 FAQ
- 第 39 章 BaaS (Blockchain as a Service) 平台
- 第 40 章 BitCoin
- 第 41 章 其他区块链相关
- 附录 1. 附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
19.8. 验收与测试
19.8. 验收与测试
19.8.1. 准备合约文件
[root@localhost netkiller]# cat chaincode/fabcar/fabcar.go /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * The sample smart contract for documentation topic: * Writing Your First Blockchain Application */ package main /* Imports * 4 utility libraries for formatting, handling bytes, reading and writing JSON, and string manipulation * 2 specific Hyperledger Fabric specific libraries for Smart Contracts */ import ( "bytes" "encoding/json" "fmt" "strconv" "github.com/hyperledger/fabric/core/chaincode/shim" sc "github.com/hyperledger/fabric/protos/peer" ) // Define the Smart Contract structure type SmartContract struct { } // Define the car structure, with 4 properties. Structure tags are used by encoding/json library type Car struct { Make string `json:"make"` Model string `json:"model"` Colour string `json:"colour"` Owner string `json:"owner"` } /* * The Init method is called when the Smart Contract "fabcar" is instantiated by the blockchain network * Best practice is to have any Ledger initialization in separate function -- see initLedger() */ func (s *SmartContract) Init(APIstub shim.ChaincodeStubInterface) sc.Response { return shim.Success(nil) } /* * The Invoke method is called as a result of an application request to run the Smart Contract "fabcar" * The calling application program has also specified the particular smart contract function to be called, with arguments */ func (s *SmartContract) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response { // Retrieve the requested Smart Contract function and arguments function, args := APIstub.GetFunctionAndParameters() // Route to the appropriate handler function to interact with the ledger appropriately if function == "queryCar" { return s.queryCar(APIstub, args) } else if function == "initLedger" { return s.initLedger(APIstub) } else if function == "createCar" { return s.createCar(APIstub, args) } else if function == "queryAllCars" { return s.queryAllCars(APIstub) } else if function == "changeCarOwner" { return s.changeCarOwner(APIstub, args) } return shim.Error("Invalid Smart Contract function name.") } func (s *SmartContract) queryCar(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { if len(args) != 1 { return shim.Error("Incorrect number of arguments. Expecting 1") } carAsBytes, _ := APIstub.GetState(args[0]) return shim.Success(carAsBytes) } func (s *SmartContract) initLedger(APIstub shim.ChaincodeStubInterface) sc.Response { cars := []Car{ Car{Make: "Toyota", Model: "Prius", Colour: "blue", Owner: "Tomoko"}, Car{Make: "Ford", Model: "Mustang", Colour: "red", Owner: "Brad"}, Car{Make: "Hyundai", Model: "Tucson", Colour: "green", Owner: "Jin Soo"}, Car{Make: "Volkswagen", Model: "Passat", Colour: "yellow", Owner: "Max"}, Car{Make: "Tesla", Model: "S", Colour: "black", Owner: "Adriana"}, Car{Make: "Peugeot", Model: "205", Colour: "purple", Owner: "Michel"}, Car{Make: "Chery", Model: "S22L", Colour: "white", Owner: "Aarav"}, Car{Make: "Fiat", Model: "Punto", Colour: "violet", Owner: "Pari"}, Car{Make: "Tata", Model: "Nano", Colour: "indigo", Owner: "Valeria"}, Car{Make: "Holden", Model: "Barina", Colour: "brown", Owner: "Shotaro"}, } i := 0 for i < len(cars) { fmt.Println("i is ", i) carAsBytes, _ := json.Marshal(cars[i]) APIstub.PutState("CAR"+strconv.Itoa(i), carAsBytes) fmt.Println("Added", cars[i]) i = i + 1 } return shim.Success(nil) } func (s *SmartContract) createCar(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { if len(args) != 5 { return shim.Error("Incorrect number of arguments. Expecting 5") } var car = Car{Make: args[1], Model: args[2], Colour: args[3], Owner: args[4]} carAsBytes, _ := json.Marshal(car) APIstub.PutState(args[0], carAsBytes) return shim.Success(nil) } func (s *SmartContract) queryAllCars(APIstub shim.ChaincodeStubInterface) sc.Response { startKey := "CAR0" endKey := "CAR999" resultsIterator, err := APIstub.GetStateByRange(startKey, endKey) if err != nil { return shim.Error(err.Error()) } defer resultsIterator.Close() // buffer is a JSON array containing QueryResults var buffer bytes.Buffer buffer.WriteString("[") bArrayMemberAlreadyWritten := false for resultsIterator.HasNext() { queryResponse, err := resultsIterator.Next() if err != nil { return shim.Error(err.Error()) } // Add a comma before array members, suppress it for the first array member if bArrayMemberAlreadyWritten == true { buffer.WriteString(",") } buffer.WriteString("{\"Key\":") buffer.WriteString("\"") buffer.WriteString(queryResponse.Key) buffer.WriteString("\"") buffer.WriteString(", \"Record\":") // Record is a JSON object, so we write as-is buffer.WriteString(string(queryResponse.Value)) buffer.WriteString("}") bArrayMemberAlreadyWritten = true } buffer.WriteString("]") fmt.Printf("- queryAllCars:\n%s\n", buffer.String()) return shim.Success(buffer.Bytes()) } func (s *SmartContract) changeCarOwner(APIstub shim.ChaincodeStubInterface, args []string) sc.Response { if len(args) != 2 { return shim.Error("Incorrect number of arguments. Expecting 2") } carAsBytes, _ := APIstub.GetState(args[0]) car := Car{} json.Unmarshal(carAsBytes, &car) car.Owner = args[1] carAsBytes, _ = json.Marshal(car) APIstub.PutState(args[0], carAsBytes) return shim.Success(nil) } // The main function is only relevant in unit test mode. Only included here for completeness. func main() { // Create a new Smart Contract err := shim.Start(new(SmartContract)) if err != nil { fmt.Printf("Error creating new Smart Contract: %s", err) } }
19.8.2. 安装 chaincode
安装合约在 tools 节点上进行。
docker-compose -f docker-compose-cli.yaml exec cli bash CORE_PEER_ADDRESS=172.16.0.17:7051 CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer chaincode install -n fabcar -v 1.0 -p github.com/fabcar peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n fabcar -v 1.0 -c '{"Args":[""]}' -P "OR ('Org1MSP.member','Org2MSP.member')" peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"initLedger","Args":[""]}'
root@a90d0d869dd3:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode install -n fabcar -v 1.0 -p github.com/fabcar 2018-02-09 11:26:28.025 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP 2018-02-09 11:26:28.025 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity 2018-02-09 11:26:28.025 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc 2018-02-09 11:26:28.025 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc 2018-02-09 11:26:28.139 UTC [golang-platform] getCodeFromFS -> DEBU 005 getCodeFromFS github.com/fabcar 2018-02-09 11:26:29.394 UTC [golang-platform] func1 -> DEBU 006 Discarding GOROOT package bytes 2018-02-09 11:26:29.395 UTC [golang-platform] func1 -> DEBU 007 Discarding GOROOT package encoding/json 2018-02-09 11:26:29.395 UTC [golang-platform] func1 -> DEBU 008 Discarding GOROOT package fmt 2018-02-09 11:26:29.395 UTC [golang-platform] func1 -> DEBU 009 Discarding provided package github.com/hyperledger/fabric/core/chaincode/shim 2018-02-09 11:26:29.395 UTC [golang-platform] func1 -> DEBU 00a Discarding provided package github.com/hyperledger/fabric/protos/peer 2018-02-09 11:26:29.395 UTC [golang-platform] func1 -> DEBU 00b Discarding GOROOT package strconv 2018-02-09 11:26:29.396 UTC [golang-platform] GetDeploymentPayload -> DEBU 00c done 2018-02-09 11:26:29.406 UTC [msp/identity] Sign -> DEBU 00d Sign: plaintext: 0A8A070A5C08031A0C08E58AF6D30510...939FFF060000FFFF9C08DC0700200000 2018-02-09 11:26:29.406 UTC [msp/identity] Sign -> DEBU 00e Sign: digest: A504EE8048EEE8C77F9E1C39827124474638110FD3980017BCA6D644E3E7EC98 2018-02-09 11:26:29.426 UTC [chaincodeCmd] install -> DEBU 00f Installed remotely response:<status:200 payload:"OK" > 2018-02-09 11:26:29.427 UTC [main] main -> INFO 010 Exiting.....
peer chaincode instantiate -o 172.16.0.17:7050 -C mychannel -n fabcar -v 1.0 -c '{"Args":[""]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论