Skip to content

Instantly share code, notes, and snippets.

@JonathanVeg
Created November 4, 2018 17:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JonathanVeg/dda0bb342c5ed00e451a3992bfaeb5da to your computer and use it in GitHub Desktop.
Save JonathanVeg/dda0bb342c5ed00e451a3992bfaeb5da to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"errors"
"regexp"
"strings"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)
// main part
// empty struct based on marbles
type SimpleChaincode struct {
}
// main struct for id.
// other structs will be here, bellow this one
// the parent id is used only for PF and it is the pf id that the pj belongs to
type RegAluno struct {
ObjectType string `json:"docType"`
Id string `json:"id"`
Name string `json:"name"`
Doc string `json:"doc"`
Course string `json:"course"`
}
// init does nothing.
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {
return shim.Success(nil)
}
// this function is used to repass the calls to specific functions
// I do not recommend to do the functions inside the "if"
// It is possible, but will make the code hard to read
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
fn, args := stub.GetFunctionAndParameters()
print("starting invoke, for - " + fn)
if fn == "add_aluno" {
return add_aluno(stub, args)
}
if fn == "get_aluno" {
return get_aluno(stub, args)
}
return shim.Error("Incorrect function. Expecting 'add_aluno' or 'get_aluno' and got '" + fn + "'")
}
// verify if the docnumber (cpf or cnpj) is already registered
// the GetStateByRange seems dumb (and it is) but is the way that marbles do
// and I did not find a better way for this
func verify_if_doc_exists(stub shim.ChaincodeStubInterface, doc string) (bool, error) {
resultsIterator, err := stub.GetStateByRange("id0", "id999999999999999999999999999999")
if err != nil {
return false, errors.New("Error while verifying data")
}
// the defer is called after the function around it be finished
// in this case it is for make sure that the iterator will be closed
defer resultsIterator.Close()
for resultsIterator.HasNext() {
aKeyValue, err := resultsIterator.Next()
if err != nil {
return false, errors.New(err.Error())
}
queryValAsBytes := aKeyValue.Value
var regid RegAluno
err = json.Unmarshal(queryValAsBytes, &regid)
if err != nil {
return false, errors.New(err.Error())
}
if regid.Doc == doc {
return true, nil
}
}
return false, nil
}
// verify if a given id already is registered
// it is different from the above function because the id can be
// searched using the "GetState" directly
func verify_if_id_exists(stub shim.ChaincodeStubInterface, id string) bool {
regidAsBytes1, err1 := stub.GetState(id)
if err1 != nil {
return false
}
return len(strings.TrimSpace(string(regidAsBytes1))) > 0
}
/*
args must be 3:
0 -> id
1 -> name
2 -> doc
3 -> course
*/
// function for adding a new id in the blockchain using the above functions
// for validations
func add_aluno(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 4 {
return shim.Error("Incorrect arguments. Expecting 4 params.")
}
// prepare the variables from args - trimmed
objectType := "RegAluno"
id := strings.TrimSpace(args[0])
name := strings.TrimSpace(args[1])
doc := strings.TrimSpace(args[2])
course := strings.TrimSpace(args[3])
if strings.Index(id, "id") == -1 {
id = "id" + id
}
// remove a mascara dos numeros, caso tenha
pattern := regexp.MustCompile(`(\d+)`)
docStringPattern := pattern.FindAllStringSubmatch(doc, -1)
docString := ""
for _, numberString := range docStringPattern {
docString += numberString[1]
}
doc = docString
// exec the addition
data := &RegAluno{
ObjectType: objectType,
Id: id,
Name: name,
Doc: doc,
Course: course,
}
var jsonStudent, _ = json.Marshal(data)
err := stub.PutState(id, []byte(jsonStudent))
if err != nil {
return shim.Error("ERROR WHILE ADDING RegAluno: " + id)
}
return shim.Success([]byte("id added successfully"))
}
/*
args must be 1:
0 -> id : (generated id)
*/
// function for reading an id in blockchain using a given id
func get_aluno(stub shim.ChaincodeStubInterface, args []string) peer.Response {
if len(args) != 1 {
// return shim.Error("Incorrect arguments. Expecting just the 'id' to be read")
return shim.Error("Incorrect arguments. Expecting just the 'id' to be read")
}
id := args[0]
if strings.Index(id, "id") == -1 {
id = "id" + id
}
value, err := stub.GetState(id)
if err != nil {
return shim.Error("Failed to get id: " + err.Error())
}
if value == nil {
return shim.Error("Id not found")
}
return shim.Success(value)
}
// the main function is mandatory
// this function is called once the project is started and it is used
// just to start the network
func main() {
if err := shim.Start(new(SimpleChaincode)); err != nil {
print("Error starting RegAluno chaincode: %s", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment