Complex data models with Chaincode and Go
The basic examples with Hyperledger are excellent but I wanted to model a data structure with optional and repeating elements. Using Chaincode I then wanted to create and read a record.
The use case for this type of problem is a common one. In your list of contacts a typical contact would have multiple email telephone numbers and it is not possible to know in advance how many phone numbers any particular contact may have. They may have no phone number, one phone or many phone numbers.
The notation to use in Chaincode is []*
[] — means this repeats
* — means this is optional, so may or may not appear
type Contact stuct {
ContactID int `json:”contactid”`
Fullname string `json:”fullname”`
Telephone []*Tele `json:”tele”`
}
type Tele struct {
Teletype string `json:”type”`
Telephonenumber string `json:”telenum”`
}
To write to the Hyperledger Fabric blockchain using Go Chaincode the following code looks like this.
func (s *ComplexContract) NewContact(ctx contractapi.TransactionContextInterface, contactid string, fullname string, , tele []*Tele) error {
//create a new contact
ca := new(Contact)
ca.ContactID = contactid
ca.Fullname = fullname
ca.Telephone = tele
//transform into a JSON document
caBytes, _ := json.Marshal(ca)
//Create contact
err := ctx.GetStub().PutState(contactid, []byte(caBytes))
return nil
}
The arguments to call to the contract are as follows
Example 1
‘{“Args”:[“NewContact”,”CONTACT_001”,”Jane Doe”,“[{“Mobile”,”555–555–555”},{“Work”, “555–666–777”}]”]}’
This will create a contact called Jane Doe with two telephone numbers
Example 2
‘{“Args”:[“NewContact”,”CONTACT_002”,”Jim Doe”,“[]”]}’
This will create a contact called Jim Doe without telephone numbers (No one likes Jim :-))
Example 3
‘{“Args”:[“NewContact”,”CONTACT_003”,”Joe Doe”,“[{“Work”, “444–666–777”}]”]}’
This will create a contact called Joe Doe with one telephone number