How chaincode is install from local filesystem - hyperledger-fabric

I have written the chaincode its in local system, now i need to install chaincode in hyperledger fabric peers.How it is done from local system to install the chaincode to my peer node. below code is taken from hyperledger fabric chaincode example.please suggest me
package main
import (
"fmt"
"strconv"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface)
pb.Response {
fmt.Println("ex02 Init")
_, args := stub.GetFunctionAndParameters()
var A, B string // Entities
var Aval, Bval int // Asset holdings
var err error
if len(args) != 4 {
return shim.Error("Incorrect number of arguments. Expecting 4")
}
// Initialize the chaincode
A = args[0]
Aval, err = strconv.Atoi(args[1])
if err != nil {
return shim.Error("Expecting integer value for asset holding")
}
B = args[2]
Bval, err = strconv.Atoi(args[3])
if err != nil {
return shim.Error("Expecting integer value for asset holding")
}
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
// Write the state to the ledger
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
if err != nil {
return shim.Error(err.Error())
}
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}

You can install the chaincode in several ways
NodeSDK
JavaSDK
CLI
I would suggest you try with CLI first, fabric-samples has one example.
Behind the seen fabric compile and only binary file will be deployed to the peer

Related

Hyperledger fabric: Querying implicit data collection

I am seeing this when querying data from implicit private data collection.
Please see code snippet below.
When I query individual key (using QueryBidPrivate/GetPrivateData), I get corresponding data.
But if I query the complete collection (using GetPrivateDataByRange(collection, "", "")), I get nothing from the Iterator.
peer chaincode query -C mychannel -n govtcontract -c '{"function":"QueryBidPrivate","Args":["100", "1035"]}'
{"bidamt":100,"biddate":"2022-05-04","contractid":"1035","salt":"4567ab4567","vendorid":"100"}
peer chaincode query -C mychannel -n govtcontract -c '{"function":"ListAllBids","Args":[]}'
No output
Is there anything I am missing here ?
// ListAllBids returns all Bids details from private state
func (s *SmartContract) ListAllBids(ctx contractapi.TransactionContextInterface) ([]VendorBid, error) {
// Get client org id and verify it matches peer org id.
// In this scenario, client is only authorized to read/write private data from its own peer.
clientOrgID, err := getClientOrgID(ctx, true)
if err != nil {
return nil, fmt.Errorf("failed to get verified OrgID: %s", err.Error())
}
collection := "_implicit_org_" + clientOrgID
BidIterator, err := ctx.GetStub().GetPrivateDataByRange(collection, "", "")
if err != nil {
logger.Infof("ListAllBids error: %s", err.Error())
return nil, fmt.Errorf("failed to read bid list : %s", err.Error())
}
if BidIterator == nil {
logger.Infof("ListAllBids : null iterator ")
return nil, fmt.Errorf("bid private details does not exist ")
}
defer BidIterator.Close()
logger.Infof("ListAllBids in govtcontract: no error")
var allbids []VendorBid
myMSPID, err := ctx.GetClientIdentity().GetMSPID()
logger.Infof("myMSPID: %s", myMSPID)
for BidIterator.HasNext() {
logger.Infof("Iterator has element: ")
entrybid, err := BidIterator.Next()
if err != nil {
return nil, err
}
var bidvar VendorBid
err = json.Unmarshal(entrybid.Value, &bidvar)
if err != nil {
return nil, err
}
allbids = append(allbids, bidvar)
logger.Infof("Iterator element: %s", entrybid.Value)
}
return allbids, nil
}
=========================================
// QueryBidPrivate returns the Bid details from owner's private data collection
func (s *SmartContract) QueryBidPrivate(ctx contractapi.TransactionContextInterface, vendorId string, contractId string) (string, error) {
// Get client org id and verify it matches peer org id.
// In this scenario, client is only authorized to read/write private data from its own peer.
clientOrgID, err := getClientOrgID(ctx, true)
if err != nil {
return "", fmt.Errorf("failed to get verified OrgID: %s", err.Error())
}
collection := "_implicit_org_" + clientOrgID
bidconkey, err := ctx.GetStub().CreateCompositeKey(vendorId, []string{contractId})
bidDetails, err := ctx.GetStub().GetPrivateData(collection, bidconkey)
if err != nil {
return "", fmt.Errorf("failed to read bid private properties from client org's collection: %s", err.Error())
}
if bidDetails == nil {
return "", fmt.Errorf("bid private details does not exist in client org's collection: %s", contractId)
}
return string(bidDetails), nil
}
GetPrivateDataByPartialCompositeKey() is the function for querying a range of private data that was stored using a composite key. GetPrivateDataByRange() won't retrieve the data stored with a composite key. I think in the above code snippet you have to replace the function call GetPrivateDataByRange(collection, "", "") with GetPrivateDataByPartialCompositeKey(collection, vendorId, []string{})
Sample usage can be found here.
I faced the same error in the smart contract. The issue here is because of storing data on the composite key.
Instead of below code :
for BidIterator.HasNext() {
logger.Infof("Iterator has element: ")
entrybid, err := BidIterator.Next()
if err != nil {
return nil, err
}
var bidvar VendorBid
err = json.Unmarshal(entrybid.Value, &bidvar)
if err != nil {
return nil, err
}
allbids = append(allbids, bidvar)
logger.Infof("Iterator element: %s", entrybid.Value)
}
Use the below function
func constructQueryResponseFromIterator(resultsIterator shim.StateQueryIteratorInterface)
(*bytes.Buffer, error)
{
// 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 nil, err
}
// Add a comma before array members, suppress it for the first array member
if bArrayMemberAlreadyWritten == true {
buffer.WriteString(",")
}
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("]")
return &buffer, nil
}

Value is not updated when ChainCode is executed

I am following a tutorial for hyperledger-fabric, below is the link.
http://hyperledger-fabric.readthedocs.io/en/latest/build_network.html.
When I executed byfn.sh as per instructed by the link, it fails when trying to query the value after the invoke to transfer 10 value from a to b is executed. The query result is still 100 and not 90 despite the Success Response : 200 and no error returned from the ChainCode.
I've also proven this by going to CLI container and executed the command step-by-step.
I wonder if any of you faced this issue and moreover if there's any guidance how to debug this (e.g. how to see the chain in the blockchain, what log to check if the value fails to be updated but the response is success, etc.).
Thanks in advance
[Edit]: From the instruction (http://hyperledger-fabric.readthedocs.io/en/latest/build_network.html), it is mentioned that we need to run (also part of byfn.sh)
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'
to transfer the value from 'a' to 'b', and afterwards when we invoke a query to peers, the value of a should change to 90 from originally 100.
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
The chaincode installed to each peer can be found here: https://github.com/hyperledger/fabric-samples/blob/release/chaincode/chaincode_example02/chaincode_example02.go
Copy-paste the code that invokes to update the value
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var A, B string // Entities
var Aval, Bval int // Asset holdings
var X int // Transaction value
var err error
if len(args) != 3 {
return shim.Error("Incorrect number of arguments. Expecting 3")
}
A = args[0]
B = args[1]
// Get the state from the ledger
// TODO: will be nice to have a GetAllState call to ledger
Avalbytes, err := stub.GetState(A)
if err != nil {
return shim.Error("Failed to get state")
}
if Avalbytes == nil {
return shim.Error("Entity not found")
}
Aval, _ = strconv.Atoi(string(Avalbytes))
Bvalbytes, err := stub.GetState(B)
if err != nil {
return shim.Error("Failed to get state")
}
if Bvalbytes == nil {
return shim.Error("Entity not found")
}
Bval, _ = strconv.Atoi(string(Bvalbytes))
// Perform the execution
X, err = strconv.Atoi(args[2])
if err != nil {
return shim.Error("Invalid transaction amount, expecting a integer value")
}
Aval = Aval - X
Bval = Bval + X
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
// Write the state back to the ledger
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
if err != nil {
return shim.Error(err.Error())
}
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
I am pretty confused how it can fail to update the value and if someone can give me a hint how to debug the blockchain or fabric, that will be great.

How to rightly decode data in block-listener.go example?

I'm using block-listener to listen transactions in one channel to send notification in another. But i haven't clue how to decode data that print block-listener.go example.
Not 100% sure what do you mean by decoding the data is the following block of the [block-lister.go][1] takes care to print transactions for you:
for {
select {
case b := <-a.notfy:
fmt.Println("")
fmt.Println("")
fmt.Println("Received block")
fmt.Println("--------------")
txsFltr := util.TxValidationFlags(b.Block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
for i, r := range b.Block.Data.Data {
tx, _ := getTxPayload(r)
if tx != nil {
chdr, err := utils.UnmarshalChannelHeader(tx.Header.ChannelHeader)
if err != nil {
fmt.Print("Error extracting channel header\n")
return
}
if txsFltr.IsInvalid(i) {
fmt.Println("")
fmt.Println("")
fmt.Printf("Received invalid transaction from channel '%s'\n", chdr.ChannelId)
fmt.Println("--------------")
fmt.Printf("Transaction invalid: TxID: %s\n", chdr.TxId)
} else {
fmt.Printf("Received transaction from channel '%s': \n\t[%v]\n", chdr.ChannelId, tx)
if event, err := getChainCodeEvents(r); err == nil {
if len(chaincodeID) != 0 && event.ChaincodeId == chaincodeID {
fmt.Println("")
fmt.Println("")
fmt.Printf("Received chaincode event from channel '%s'\n", chdr.ChannelId)
fmt.Println("------------------------")
fmt.Printf("Chaincode Event:%+v\n", event)
}
}
}
}
}
}
}
if you would like you can also use following function to get block printed in JSON format:
protolator.DeepMarshalJSON(os.Stdout, t.Block)

Hyperledger Build error: Error creating new Smart Contract: Error chaincode id not provided

I am learning how to use Hyperledger Fabric DLT framework.
I am building an application that allows a seller of Tuna to transact with a buyer at a discount without compromising the marker price at which the seller sells to other buyers.
Problem: However each time a execute the code this message is thrown
2018-01-14 18:45:11.292 EST [shim] SetupChaincodeLogging -> INFO 001 Chaincode log level not provided; defaulting to: INFO
2018-01-14 18:45:11.292 EST [shim] SetupChaincodeLogging -> INFO 002 Chaincode (build level: ) starting up ...
This is the error that I constantly get each time I run the code:
Error creating new Smart Contract: Error chaincode id not providedeloiim:fabric_
This is the code I created
package main
import ( "github.com/hyperledger/fabric/core/chaincode/shim"; sc"github.com/hyperledger/fabric/protos/peer"; "bytes"; "encoding/json"; "strconv"; "fmt"; )
type SmartContract struct {
}
type Tuna struct {
TxID int `json:"txid"`
Container string `json:"container"`
Timestamp string `json:"timestamp"`
Location string `json:"location"`
Owner string `json:"owner"`
}
changeTunaHolder - As the tuna fish is passed to different parties in the supply chain, the data in the world state can be updated with who has possession. The changeTunaHolder method takes in 2 arguments, tuna id and new holder name.
I suspect the error is with the changeTunaHolder method given that it takes the id and Owner fields
func (S_ *SmartContract) changeTunaHolder(APIstub shim.ChaincodeStubInterface, parameters []string) sc.Response {
if len(parameters) != 2 {
return shim.Error("Incorrect number of arguments. Expecting 2")
}
tunaAsBytes, _ := APIstub.GetState(parameters[0])
if tunaAsBytes == nil {
return shim.Error("Could not locate tuna")
}
TUNA := Tuna{}
json.Unmarshal(tunaAsBytes, &TUNA)
// Normally check that the specified argument is a valid holder of tuna
// we are skipping this check for this example
TUNA.Owner = parameters[1]
tunaAsBytes, _ = json.Marshal(TUNA)
_error := APIstub.PutState(parameters[0], tunaAsBytes)
if _error != nil {
return shim.Error(fmt.Sprintf("Failed to change tuna holder: %s", parameters[0]))
}
return shim.Success(nil)
}
Init METHOD - In this the code attempts to retrieve the requested Smart Contract function and arguments
func (S_ *SmartContract) Init(APIstub shim.ChaincodeStubInterface) sc.Response {
return shim.Success(nil)
}
func (S_ *SmartContract ) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response {
function, parameters := APIstub.GetFunctionAndParameters()
if function == "queryTuna" {
return S_.queryTuna(APIstub, parameters)
} else if function == "initLedger"{
return S_.initLedger(APIstub)
} else if function == "recordTuna" {
return S_.recordTuna(APIstub, parameters)
} else if function == "changeTunaHolder" {
return S_.changeTunaHolder(APIstub, parameters)
}
return shim.Error("Invalid Smart Contract function name.")
}
queryTuna - The queryTuna method would be used by a fisherman, regulator, or restaurateur to view the record of one particular tuna. It takes one argument - the key for the tuna in question.
func (S_ *SmartContract) queryTuna(APIstub shim.ChaincodeStubInterface, parameters []string) sc.Response {
if len(parameters) != 1{
return shim.Error("Incorrect number of arguments. Expecting 1")
}
tunaAsBytes, _ := APIstub.GetState(parameters[0])
if tunaAsBytes == nil {
return shim.Error("Could not locate tuna")
}
return shim.Success(tunaAsBytes)
}
initLedger - The initLedger method will add test data to our network.
func (S_ *SmartContract) initLedger(APIstub shim.ChaincodeStubInterface) sc.Response{
TUNA := []Tuna {
Tuna{TxID: 1,Container: "923F", Location: "67.0006, -70.5476", Timestamp: "1504054225", Owner: "Miriam"},
Tuna{TxID: 2,Container: "M83T", Location: "91.2395, -49.4594", Timestamp: "1504057825", Owner: "Dave"},
Tuna{TxID: 3,Container: "T012", Location: "58.0148, 59.01391", Timestamp: "1493517025", Owner: "Igor"},
Tuna{TxID: 4,Container: "P490", Location: "-45.0945, 0.7949", Timestamp: "1496105425", Owner: "Amalea"},
Tuna{TxID: 5,Container: "S439", Location: "-107.6043, 19.5003", Timestamp: "1493512301", Owner: "Rafa"},
Tuna{TxID: 6,Container: "J205", Location: "-155.2304, -15.8723", Timestamp: "1494117101", Owner: "Shen"},
Tuna{TxID: 7,Container: "S22L", Location: "103.8842, 22.1277", Timestamp: "1496104301", Owner: "Leila"},
Tuna{TxID: 8,Container: "EI89", Location: "-132.3207, -34.0983", Timestamp: "1485066691", Owner: "Yuan"},
Tuna{TxID: 9,Container: "129R", Location: "153.0054, 12.6429", Timestamp: "1485153091", Owner: "Carlo"},
Tuna{TxID: 10,Container: "49W4", Location: "51.9435, 8.2735", Timestamp: "1487745091", Owner: "Fatima"},
}
iter := 0
for iter < len(TUNA) {
println("iter is", iter)
tunaAsBytes, _ := json.Marshal(TUNA[iter])
APIstub.PutState(strconv.Itoa(iter+1), tunaAsBytes)
fmt.Println("ADDED", TUNA[iter])
iter += 1
}
return shim.Success(nil)
}
recordTuna - The recordTuna method is the method a fisherman like Sarah would use to record each of her tuna catches. This method takes in five arguments (attributes to be saved in the ledger).
func (S_ *SmartContract) recordTuna(APIstub shim.ChaincodeStubInterface, parameters[]string) sc.Response {
if len(parameters) != 5 {
return shim.Error("Incorrect number of arguments. Expecting 5")
}
TUNA := Tuna{Container:parameters[1], Location:parameters[2], Timestamp:parameters[3], Owner:parameters[4]}
tunaAsBytes, _:=json.Marshal(TUNA)
_error := APIstub.PutState(parameters[0], tunaAsBytes)
if _error != nil {
return shim.Error(fmt.Sprintf("Failed to record tuna catch: %s", parameters[0]))
}
return shim.Success(nil)
}
queryAllTuna - The queryAllTuna method allows for assessing all the records; in this case, all the Tuna records added to the ledger. This method does not take any arguments. It will return a JSON string containing the results.
func (S_ *SmartContract) queryAllTuna(APIstub shim.ChaincodeStubInterface) sc.Response {
init_key := "0"
end_key := "999"
results_iterator, _error := APIstub.GetStateByRange(init_key, end_key)
if _error != nil {
return shim.Error(_error.Error())
}
defer results_iterator.Close()
var buffer bytes.Buffer
buffer.WriteString("[")
b_array_member_already_written := false
for results_iterator.HasNext() {
query_response, _error := results_iterator.Next()
if _error != nil {
return shim.Error(_error.Error())
}
if b_array_member_already_written == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"Key\":")
buffer.WriteString("\"")
buffer.WriteString(query_response.Key)
buffer.WriteString("\"")
buffer.WriteString(", \"Record\":")
buffer.WriteString(string(query_response.Value))
buffer.WriteString("}")
b_array_member_already_written = true
}
buffer.WriteString("]")
fmt.Printf("- queryAllTuna:\n%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
MAIN FUNCTION
func main() {
_error := shim.Start(new(SmartContract))
if _error != nil {
fmt.Printf("Error creating new Smart Contract: %s", _error)
}
}
have you tried to go with the terminal in chaincode-docker-devmode?
cd fabric-samples/chaincode-docker-devmode
as in Chaincode for Developers
Me I got the same error when I forgot to jump in the repository
And make sure to put the version in CORE_CHAINCODE_ID_NAME (e.g: CORE_CHAINCODE_ID_NAME=mycc:0)

Query latest world state using Hyperledger 1.0 Nodejs SDK

Based on hyperledger SDK doc, we can use nodeJS SDK to query for the block and the transaction info. Is it possible to use this SDK to query the latest world state, e.g, query the value for a given key?
To being able to query for latest world state your chaincode has to provide this capability, namely you have to implement this logic and incorporate it into your chaincode. Then it will simply require to execute the chaincode to get the value for the key you are interested it.
For example you can do something similar to this:
package main
import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)
// Person
type Asset struct {
ID string `json:"id"`
Name string `json:"name"`
Price string `json:"price"`
}
// assetManagement the chaincode interface implementation to manage
// the ledger of person records
type assetManagement struct {
}
func (p *assetManagement) Init(stub shim.ChaincodeStubInterface) peer.Response {
return shim.Success(nil)
}
func (p *assetManagement) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
actionName, params := stub.GetFunctionAndParameters()
if actionName == "addAsset" {
return p.addAsset(stub)
} else if actionName == "getAsset" {
return p.getAsset(stub)
}
return shim.Error("Unknown function name")
}
func (p *assetManagement) getAsset(stub shim.ChaincodeStubInterface) peer.Response {
_, params := stub.GetFunctionAndParameters()
assetID := params[0]
state, err := stub.GetState(assetID)
if err != nil {
return shim.Error(fmt.Sprintf("%s", err))
}
return shim.Success(state)
}
func (p *assetManagement) addAsset(stub shim.ChaincodeStubInterface) peer.Response {
// TODO add loggic adding new asset
}
func main() {
err := shim.Start(new(assetManagement))
if err != nil {
fmt.Printf("Error starting Simple chaincode: %s", err)
}
}
Next all you need is to invoke chaincode passing function name getAsset with asset ID and will get latest state for that asset. Here is the code based on Go SDK:
// Skipped initialization.
txRequest := apitxn.ChaincodeInvokeRequest{
Targets: []apitxn.ProposalProcessor{p},
Fcn: "getAsset",
Args: []string{"42"},
TransientMap: map[string][]byte{},
ChaincodeID: "assetChaincode",
}
proposalResponse, _, err := ch.SendTransactionProposal(txRequest)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%v\n", proposalResponse[0].ProposalResponse)
tx, err := ch.CreateTransaction(proposalResponse)
if err != nil {
fmt.Println(err)
return
}
txResponse, err := ch.SendTransaction(tx)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(txResponse[0])

Resources