- Print
- PDF
Smart contracts
- Print
- PDF
Available in VPC
Manage channel
Channel serves as a sub-network for processing transactions of a certain group (MSP group) within a consortium.
Managing orderer's consortium means selecting all MSPs managed by the orderer, and managing channel members means selecting MSPs participating in a specific channel among the multiple MSPs in a consortium.
Create channel
The following describes how to create a channel.
Before creating a channel, you need to set up a consortium for the members (MSP). For more information, see Setting up orderer consortium.
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
- On the Network names drop-down menu, click the network in which to create a channel.
- Click the [Channels] tab and then click [Create channel].
- Enter channel information, and click [Create].
- Channel is created.
- Channel members can select their role as operator or participant, and only one operator (required) can be specified. When you designate an Operator, all MSPs selected afterward are assigned the role of a Participant.
- Orderer manages the channel and one orderer can manage multiple channels.
When an Orderer is deleted, the connected channels are removed from the channel list but remain undeleted. Be sure not to name a new channel the same as any of the channels removed from the list.
View channel details
To view the details of a channel, do the following:
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
- On the Network names drop-down menu, click the network having the channel whose details you wish to view.
- Click the [Channels] tab.
- Click the channel to check.
- Channel details are displayed.
The following are the descriptions for each item of the channel list page.
Field | Description |
---|---|
① Create channel | Create a new channel |
② Set up channel | Make channel settings, such as those for channel member (MSP) and peer management and block creation policy |
③ Channel items | Checks the channel's basic information |
④ Details | View channel details |
⑤ View blocks | View blocks and transactions of the channel |
⑥ Channel members | View the information of channel members (MSP) |
⑦ Peer information | View the information of peers participating in the channel |
View blocks and transactions
You can view the blocks or transactions belonging to the created channel.
To view blocks or transactions, do the following:
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
- On the Network names drop-down menu, click the applicable network.
- Click the [Channels] tab.
- On the channel list, select the channel and click View blocks.
- Enter block number or transaction ID and click .
- To view the transaction details, click TransactionID.
- When the pop-up loads, the latest block's details are displayed.
Manage channel members (MSP)
You can add new members to a channel or delete existing members.
To manage channel members (MSP), do the following:
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
- On the Network names drop-down menu, click the applicable network.
- Click the [Channels] tab.
- On the channel list, select the channel whose members (MSP) you wish to manage, and click [Set up channel].
- Click Manage channel members (MSP).
- On the Manage channel members (MSP) pop-up window, add or delete members and then click [Okay].
- If an operator is already specified, you can't delete the operator or add a new operator.
Manage peers in channel
You can add new peers participating in the actual communication to the created channel or apply the anchor peer to the peers.
The following describes how to manage peers in the channel.
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
- On the Network names drop-down menu, click the applicable network.
- Click the [Channels] tab.
- On the channel list, select the channel whose members (MSP) you wish to manage, and click [Set up channel].
- Click Manage peer.
- Add peers and set up Anchor Peer and click [Close].
- Joined peers can't be canceled.
- All peers should use the same database.
Anchor Peer serves the role of exchanging information with peers from other organizations. For more information, see the following:
Set up block creation policy
To set up a block creation policy in a channel, do the following:
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
- On the Network names drop-down menu, click the applicable network.
- Click the [Channels] tab.
- On the channel list, select the channel whose members (MSP) you wish to manage, and click [Set up channel].
- Click Set up block creation policy.
- Set up the block creation policy and click [Okay].
- For standard block size and maximum block size, you can only enter integers or decimal numbers with only one digit after the decimal point.
- Changing the default value might affect the transaction processing performance.
For more information on channel configuration, see the following:
Manage chaincode
Install chaincode
You can install a chaincode in the peer created within the network.
To install a chaincode, you need to create a CDS package first. To see how to create a CDS package and download examples, go to Chaincode (CDS) packaging.
For more information on chaincode and CDS package, see the following:
- Chaincode: Go to Hyperledger Fabric Guide
- CDS package: Go to Hyperledger Fabric Guide
- If the network type of Kubernetes Cluster is Private Subnet, to use an external library from chaincode or invite networks between VPCs you need to use NATGW.
The following describes how to install a chaincode.
In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
On the Network names drop-down menu, click the network in which to install a chaincode.
Click the [Chaincodes] tab and then click [Install chaincode].
On the Install chaincode pop-up window, drag and drop the CDS package file onto the area where it says Drag and drop the file or click here or click on the area and select the file. Then, click [Next].
CautionIf the package you are uploading has the same chaincode metadata (name, version) as a previous uploaded CDS package, the previously uploaded package is used instead. Be careful with the version.
Select the peer on which to install the uploaded chaincode (CDS package) and click [Install].
- Peers with chaincode already installed show Installed.
- Since Ver. 2.2 chaincode is deployed with Ver. 1.4 node level, chaincode lifecycle is currently unavailable. Other new features of the 2.2 version are applied normally.
- To enable transaction processing with the installed chaincode, you need to instantiate the chaincode. For more information, see Instantiating chaincode.
The installed chaincode can't be deleted. Once you have instantiated the chaincode, click [View log] to view the chaincode container log.
View chaincode details
The following describes how to check the details of chaincodes installed in the network.
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
- On the Network names drop-down menu, click the network having the chaincode whose details you wish to view.
- Click the [Chaincodes] tab.
- Click the chaincode to check.
- The chaincode details are displayed.
The following are the descriptions for each item of the chaincode list page.
Field | Description |
---|---|
① Install chaincode | Install a new chaincode |
② Instantiate | Instantiates the chaincode |
③ Change version | Change the version of the instantiated chaincode |
④ Search window | Set the search conditions and click to run search |
⑤ Chaincode details | Checks the information of installed chaincodes and instantiated chaincodes |
⑥ Run chaincode | Run the instantiated chaincode |
Instantiate chaincode
You can process transactions after installing and instantiating the chaincode.
The following describes how to instantiate a chaincode.
In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
On the Network names drop-down menu, click the network having the chaincode whose details you wish to view.
Click the [Chaincodes] tab and then click [Instantiate].
Set the Instantiate chaincode field and click [Okay].
- Transaction guarantee member: To add an MSP as a transaction guarantee member, you need to set up the orderer consortium. See Setting up orderer consortium.
- Transaction guarantee policy: If there are multiple transaction guarantee members, you can set the transaction guarantee policy as 1/2, 2/3 and so on. If the transaction guarantee policy is 2/3, then this means that 2 or more out of 3 guarantee members must guarantee the transaction.
- Run initialization function: If the chaincode has an initialization function assigned, you can run the function during instantiation.
- Instantiation can take up to a few minutes. You can see the result by clicking [Alert] at the top right of the console screen.
- If instantiation succeeds, you can view the result on the list of instantiated chaincodes.
- An instantiated chaincode can't be deleted.
Change chaincode version (upgrade)
Once a chaincode is instantiated, installing a new version simply changes the version without additional instantiation.
If a higher version is installed for an instantiated chaincode, an Upgrade available badge is displayed for the chaincode on the instantiated chaincode list.
To change the version of an instantiated chaincode, do the following:
In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
On the Network names drop-down menu, click the network having the chaincode you wish to upgrade.
Click the [Chaincodes] tab and then click [Change version].
Set the Upgrade chaincode field and click [Okay].
- Transaction guarantee member: To add an MSP as a transaction guarantee member, you need to set up the orderer consortium. See Setting up orderer consortium.
- Transaction guarantee policy: e.g. If the transaction guarantee policy is 2/3, it means that at least two out of the three guarantee members must provide guarantee.
- Run initialization function: If the chaincode has an initialization function assigned, you can run the function during instantiation.
- Version change is possible only if the chaincode names match.
- Version change can take up to a few minutes. You can see the result by clicking [Alert] at the top right of the console screen.
- If version change succeeds, you can view the result on the list of instantiated chaincodes.
Run chaincode
You can use [Run chaincode] to run an instantiated chaincode.
To run a chaincode, do the following:
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Smart Contracts.
- On the Network names drop-down menu, click the network having the chaincode you wish to run.
- Click the [Chaincodes] tab, and on [List of instantiated chaincodes] select the chaincode to call. Then, click [Run chaincode].
- Enter the desired command (Invoke/Query), contract name, function name and parameters and click [Run].
- Enter contract name if the chaincode has Multi Contract enabled.
- When you call a chaincode, you can view the values of mspId, Identity and chaincode response.
- Add parameters in the same order as those for the function to call.
- If a parameter to send is an object, add it in the JSON format as follows:
{"carNumber":"CAR1001","color":"red"}
Change chaincode deployment structure
For future operations, Ncloud Kubernetes Service will have the docker.sock file removed in the worker node and thus use the new method of deploying chaincode container into the container where the docker.sock file is installed, as shown below.
AS-IS
TO-BE
If node was configured and chaincode deployed before December 21, 2023, you need to change the node configuration and restart the node through the following procedure:
- In Kubernetes Cluster, save deployment.yaml of the peer node as the input.yaml file.
$ kubectl -n [namespace] get deploy [peer deployment yaml] - o yaml > input.yaml
To check namespace, do the following:
- In the VPC environment of the NAVER Cloud Platform console, click Services > Blockchain > Blockchain Service > Networks.
- On the [Network list] tab, click the network having the namespace to check.
- namespace comprises the strings starting with bc except those after ingress in Load balancer name (Instance No) in Details.
Use the following conversion tool to change the content of input.yaml created in step 1.
Conversion tool file (Unzip it and use the right file for your OS.)$ ./blockchain-migrtation_darwin_amd64 -r blockchain.kr.private-ncr-ntruss.com -i input.yaml -o output.yaml
Apply the changed output.yaml file.
$ kubectl apply -f output.yaml -n [namespace]
- The above task changes and re-runs previously deployed nodes, which may cause a downtime of about 1 minute.
- If the above task is not performed, any change made through upgrading the version of Kubernetes Cluster, adding worker node, etc. may affect the operation.
Develop application
Developing an application on Hyperledger Fabric consists of the following steps:
- Develop chaincode
- Package chaincode
- Install, instantiate and upgrade chaincode
- Develop, build and run application
1. Develop chaincode
Hyperledger Fabric provides Chaincode Shim API, which is a library that supports chaincode development in 3 languages, namely Go, Java and Javascript. The library differs depending on the version of Hyperledger Fabric. Thus, it is necessary to use the correct library for the version when you are using Blockchain Service. For how to select the correct library and configure the build environment in each language, see Chaincode sample among the following reference links.
The interface used to store or read blockchain data is the ChaincodeStubInterface
. ChaincodeStubInterface
provides methods such as putState(key, value)
and getState(key)
to support storing blockchain data in a key/value format. For more information, see Chaincode development guide among the following reference links.
For more information on chaincode development, see the following:
After Hyperledger Fabric 1.4 was released, the library path for Chaincode Shim API of the Go language was partially changed. Thus, for chaincode samples for version 1.4, change the import statement to the one under After change.
Before change
import ( "github.com/hyperledger/fabric/core/chaincode/shim" sc "github.com/hyperledger/fabric/protos/peer" )
After change
import ( "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-chaincode-go/shimtest" sc "github.com/hyperledger/fabric-protos-go/peer" )
Hyperledger Fabric 2.x provides Contract API in addition to Chaincode Shim API to support chaincode development. Contract API comes with the library for Hyperledger Fabric 1.4 and thus can be used in Blockchain Service on NAVER Cloud. However, note that chaincode samples using Contract API are written for Hyperledger Fabric 2.x.
2. Package chaincode (CDS)
Once chaincode development is completed, you need to package the chaincode in the CDS format. CDS is a method of defining such attributes as code, name and version on Hyperledger Fabric. Through CDS, you can install chaincode.
You can create a CDS package through Fabric SDK or CLI.
For more information on CDS packaging, see the following:
This guide uses an example to explain how to create a CDS using the fabric-tools container.
Make preparations (required)
Install the following application in the local environment to execute this example. Please refer to the link about downloading the application and detailed instructions.
- Docker 19.03 or higher (https://www.docker.com/products/docker-desktop)
- Git (https://git-scm.com/)
- Go (https://go.dev/)
Download example code
Execute the following command in the local environment and download the example code.
$ mkdir -p $GOPATH/src/github.com/hyperledger
$ cd $GOPATH/src/github.com/hyperledger
$ git clone -b v1.4.12 https://github.com/hyperledger/fabric.git
Run fabric-tools container and package CDS file
Run the following command to run the fabric-tools container containing the CLI file.
$ docker run -ti --rm -v $GOPATH/src:/opt/gopath/src hyperledger/fabric-tools:1.4.12 /bin/bash
Run the following command to check if
$GOPATH
is/opt/gopath
in the fabric-tools container and check if$GOPATH
in the local storage has been mounted on the correct path.root@073c6694cadb echo $GOPATH /opt/gopath
Move to the
$GOPATH/src
folder and run the following command to package the example code in a CDS file.root@073c6694cadb: cd $GOPATH/src root@073c6694cadb:/opt/gopath/src# peer chaincode package -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd -v 1.0 mycc.cds 2021-04-27 12:53:18.821 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc 2021-04-27 12:53:18.821 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
The following is an example of creating Ver. 1.0 CDS file for each language using the peer chaincode package
command.
peer chaincode package [package name] -n [chaincode name] -v [version] -p [chaincode absolute path] -l [chaincode language]
For
java
chaincodepeer chaincode package fabcar.v1.cds -n fabcar -v 1.0 -p chaincode/fabcar/java -l java
For
javascript
chaincodepeer chaincode package fabcar.v1.cds -n fabcar -v 1.0 -p chaincode/fabcar/javascript -l node
For
go
chaincodeFor the go chaincode, use the relative path of $GOPATH/src for -p. cp -r chaincode/fabcar/go/* $GOPATH/src/fabcar peer chaincode package fabcar.v1.cds -n fabcar -v 1.0 -p fabcar
- After completing CDS packaging, check if the
mycc.cds
file has been created in$GOPATH/src
in the local storage.
3. Install, instantiate and upgrade chaincode
When the CDS package file is created, use the Blockchain Service console to install the chaincode in the peer node and instantiate it. For more information, see the following:
Once a chaincode is instantiated, installing a new version simply performs upgrade without additional instantiation. For more information, see the following:
4. Develop, build and run application
After the chaincode is instantiated, you can develop and run an application that accesses a blockchain using the chaincode.
For more information on application development, see the following:
The following example is based on version 1.4.
As with chaincode, Hyperledger Fabric provides a library for application development, namely Fabric SDK, in go, java and javascript versions. Fabric SDK has 1.4 and 2.x versions. You can use version 1.4. If there is no compatibility issue, you can use the latest version SDK.
In addition to the chaincode calling function, Fabric SDK provides various other functions including bringing network details by accessing peer node (service discovery), creating ID or issue certificate by accessing CA node and creating channels and registering chaincodes.
This guide describes the application components with the Node.js example.
Preparations
Peer node access address and CA (Certificate) to access peer nodes are required to run the application. You can download the information on the Blockchain Service console.
- connection profile: Save in
download/connection_profile.json
the file downloaded in Organizations on Blockchain Service. (See Download MSP access information.) - Certificate: Save in
download/user.json
the file exported in Nodes. (See Manage CA user ID.)
You can enroll the certificate directly from the CA server and create a wallet as in the application sample without downloading the certificate on the console.
Application (javascript) example
- Refer to the example to write an application (
query.js
) which creates a wallet with the certificate downloaded on the console and uses it to call the chaincodefabcar
and output the result.
/*
* Copyright IBM Corp. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
'use strict';
const { Gateway, Wallets } = require('fabric-network');
const path = require('path');
const fs = require('fs');
async function main() {
try {
// load the network configuration
const ccpPath = path.resolve(__dirname, 'download/connection_profile.json');
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
const mspId = ccp.client.organization;
// load the exported user
const userPath = path.resolve(__dirname, 'download/user.json');
const user = JSON.parse(fs.readFileSync(userPath, 'utf8'));
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = await Wallets.newFileSystemWallet(walletPath);
var identity = await wallet.get(user.name);
if (!identity) {
const x509Identity = {
credentials: {
certificate: Buffer.from(user.cert, 'base64').toString('utf8'),
privateKey: Buffer.from(user.key, 'base64').toString('utf8'),
},
mspId: mspId,
type: 'X.509',
};
await wallet.put(user.name, x509Identity);
identity = await wallet.get(user.name);
}
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccp, {wallet: wallet, identity: user.name, discovery: { enabled: true, asLocalhost: false } });
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('defaultchannel');
// Get the contract from the network.
const contract = network.getContract('fabcar');
// Evaluate the specified transaction.
// queryCar transaction - requires 1 argument, ex: ('queryCar', 'CAR4')
// queryAllCars transaction - requires no arguments, ex: ('queryAllCars')
const result = await contract.evaluateTransaction('queryAllCars');
console.log(`Transaction has been evaluated, result is: ${result.toString()}`);
// Disconnect from the gateway.
await gateway.disconnect();
} catch (error) {
console.error(`Failed to evaluate transaction: ${error}`);
process.exit(1);
}
}
main();
- Create a
package.json
file as follows.
{
"name": "fabcar",
"version": "1.0.0",
"description": "FabCar application implemented in JavaScript",
"engines": {
"node": ">=8",
"npm": ">=5"
},
"scripts": {
"lint": "eslint ."
},
"engineStrict": true,
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
"fabric-network": "^2.1.0"
}
}
- Build and run as follows.
- Print the information stored in the blockchain.
$ npm install
$ node query.js
Transaction has been evaluated, result is: [{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
Application (java) example
- Write an application (
ClientApp.java
) which creates a wallet with the certificate downloaded on the console and uses it to call the chaincodefabcar
and output the result.
/*
SPDX-License-Identifier: Apache-2.0
*/
package org.example;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.Gateway;
import org.hyperledger.fabric.gateway.Network;
import org.hyperledger.fabric.gateway.Wallet;
import org.hyperledger.fabric.sdk.NetworkConfig;
import org.hyperledger.fabric.sdk.security.CryptoPrimitives;
import javax.json.Json;
import javax.json.JsonObject;
public class ClientApp {
static {
System.setProperty("org.hyperledger.fabric.sdk.service_discovery.as_localhost", "false");
}
public static void main(String[] args) throws Exception {
// Load a file system based wallet for managing identities.
Path walletPath = Paths.get("wallet");
Wallet wallet = Wallet.createFileSystemWallet(walletPath);
// load a CCP
Path networkConfigPath = Paths.get("download", "connection_profile.json");
InputStream is = new FileInputStream(networkConfigPath.toFile());
NetworkConfig ccp = NetworkConfig.fromJsonStream(is);
String mspId = ccp.getClientOrganization().getMspId();
// load the exported user
Path userPath = Paths.get("download", "user.json");
is = new FileInputStream(userPath.toFile());
JsonObject userObject = (JsonObject) Json.createReader(is).read();
String userId = userObject.getString("name");
boolean userExists = wallet.exists(userId);
if (!userExists) {
CryptoPrimitives crypto = new CryptoPrimitives();
Wallet.Identity user = Wallet.Identity.createIdentity(mspId,
new String(Base64.getDecoder().decode(userObject.getString("cert"))),
crypto.bytesToPrivateKey(Base64.getDecoder().decode(userObject.getString("key"))));
wallet.put(userId, user);
}
Gateway.Builder builder = Gateway.createBuilder();
builder.identity(wallet, userId).networkConfig(networkConfigPath).discovery(true);
// create a gateway connection
try (Gateway gateway = builder.connect()) {
// get the network and contract
Network network = gateway.getNetwork("defaultchannel");
Contract contract = network.getContract("fabcar");
byte[] result;
result = contract.evaluateTransaction("queryAllCars");
System.out.println(new String(result));
System.exit(0);
}
}
}
- Create a
pom.xml
file as follows.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fabcar-java</groupId>
<artifactId>fabcar-java</artifactId>
<version>1.4.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>oss-sonatype</id>
<name>OSS Sonatype</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.hyperledger.fabric</groupId>
<artifactId>fabric-gateway-java</artifactId>
<version>1.4.1</version>
</dependency>
</dependencies>
</project>
- Build and run as follows.
- The information stored in the blockchain is printed.
$ mvn compile
$ mvn exec:java -Dexec.mainClass=org.example.ClientApp
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]