mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 15:35:09 +00:00
Update fabric to v2.5.13 and v3.1.1 for improved compatibility and performance
This commit is contained in:
parent
cc85f96d9e
commit
33401e729d
6 changed files with 741 additions and 0 deletions
194
README-NIVIX.md
Normal file
194
README-NIVIX.md
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
# Nivix Hybrid Blockchain Setup
|
||||
|
||||
This document provides step-by-step instructions for setting up the Nivix hybrid blockchain architecture combining Solana and Hyperledger Fabric.
|
||||
|
||||
## Overview
|
||||
|
||||
The Nivix payment platform uses a hybrid architecture:
|
||||
- **Solana**: Handles fast and low-cost payment transactions
|
||||
- **Hyperledger Fabric**: Stores private KYC/AML data and transaction records
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker v28.1.1+
|
||||
- Docker Compose v2.35.1+
|
||||
- Go v1.20+
|
||||
- Hyperledger Fabric v2.5.12+
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
### 1. Setting up the Hyperledger Fabric Test Network
|
||||
|
||||
```bash
|
||||
# Navigate to the test network directory
|
||||
cd /media/shubham/OS/for\ linux\ work/blockchain\ solana/hyperledger/fabric/fabric-samples/test-network
|
||||
|
||||
# Bring down any existing network
|
||||
./network.sh down
|
||||
|
||||
# Start a fresh Fabric network
|
||||
./network.sh up
|
||||
|
||||
# Create a channel named "mychannel"
|
||||
./network.sh createChannel
|
||||
```
|
||||
|
||||
### 2. Preparing the Nivix KYC Chaincode
|
||||
|
||||
```bash
|
||||
# Navigate to the chaincode directory
|
||||
cd /media/shubham/OS/for\ linux\ work/blockchain\ solana/hyperledger/fabric/fabric-samples/chaincode-nivix-kyc/go/nivix-kyc
|
||||
|
||||
# Add required dependencies
|
||||
go get github.com/hyperledger/fabric-contract-api-go/contractapi
|
||||
go mod tidy
|
||||
|
||||
# Prepare vendor directory
|
||||
go mod vendor
|
||||
```
|
||||
|
||||
### 3. Create Private Data Collections Configuration
|
||||
|
||||
Create a file named `collections_config.json` in the test-network directory:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "kycCollection",
|
||||
"policy": "OR('Org1MSP.member', 'Org2MSP.member')",
|
||||
"requiredPeerCount": 0,
|
||||
"maxPeerCount": 1,
|
||||
"blockToLive": 1000000,
|
||||
"memberOnlyRead": true,
|
||||
"memberOnlyWrite": true,
|
||||
"endorsementPolicy": {
|
||||
"signaturePolicy": "OR('Org1MSP.member', 'Org2MSP.member')"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "transactionCollection",
|
||||
"policy": "OR('Org1MSP.member', 'Org2MSP.member')",
|
||||
"requiredPeerCount": 0,
|
||||
"maxPeerCount": 1,
|
||||
"blockToLive": 1000000,
|
||||
"memberOnlyRead": true,
|
||||
"memberOnlyWrite": true,
|
||||
"endorsementPolicy": {
|
||||
"signaturePolicy": "OR('Org1MSP.member', 'Org2MSP.member')"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### 4. Deploy the Chaincode
|
||||
|
||||
```bash
|
||||
# Return to the test-network directory
|
||||
cd /media/shubham/OS/for\ linux\ work/blockchain\ solana/hyperledger/fabric/fabric-samples/test-network
|
||||
|
||||
# Install jq (required by scripts)
|
||||
sudo apt-get update && sudo apt-get install -y jq
|
||||
|
||||
# Deploy the chaincode
|
||||
./network.sh deployCC -ccn nivix-kyc -ccp ../chaincode-nivix-kyc/go/nivix-kyc -ccl go
|
||||
```
|
||||
|
||||
### 5. Update Chaincode with Private Collections
|
||||
|
||||
```bash
|
||||
# Set up environment variables for Org1
|
||||
export PATH=${PWD}/../bin:$PATH
|
||||
export FABRIC_CFG_PATH=$PWD/../config/
|
||||
export CORE_PEER_TLS_ENABLED=true
|
||||
export CORE_PEER_LOCALMSPID="Org1MSP"
|
||||
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
|
||||
export CORE_PEER_ADDRESS=localhost:7051
|
||||
|
||||
# Approve for Org1
|
||||
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name nivix-kyc --version 1.2 --package-id nivix-kyc_1.1:5ef7a3ff23f8d69ed809eb2863c129d83fa780069026d2615545b4136ae003bd --sequence 3 --collections-config "${PWD}/collections_config.json"
|
||||
|
||||
# Set up environment variables for Org2
|
||||
export CORE_PEER_LOCALMSPID="Org2MSP"
|
||||
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
|
||||
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
|
||||
export CORE_PEER_ADDRESS=localhost:9051
|
||||
|
||||
# Approve for Org2
|
||||
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name nivix-kyc --version 1.2 --package-id nivix-kyc_1.1:5ef7a3ff23f8d69ed809eb2863c129d83fa780069026d2615545b4136ae003bd --sequence 3 --collections-config "${PWD}/collections_config.json"
|
||||
|
||||
# Switch back to Org1 for commit
|
||||
export CORE_PEER_LOCALMSPID="Org1MSP"
|
||||
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
|
||||
export CORE_PEER_ADDRESS=localhost:7051
|
||||
|
||||
# Commit the chaincode definition
|
||||
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name nivix-kyc --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" --version 1.2 --sequence 3 --collections-config "${PWD}/collections_config.json"
|
||||
```
|
||||
|
||||
## Testing the Chaincode
|
||||
|
||||
### 1. Store KYC Data
|
||||
|
||||
```bash
|
||||
# Store KYC data for user1
|
||||
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n nivix-kyc --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"StoreKYCData","Args":["user1", "Sol123456789", "John Doe", "true", "2025-05-17", "10", "a1b2c3d4e5f6"]}'
|
||||
|
||||
# Store KYC data for user2
|
||||
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n nivix-kyc --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"StoreKYCData","Args":["user2", "Sol987654321", "Jane Smith", "true", "2025-05-17", "5", "f6e5d4c3b2a1"]}'
|
||||
```
|
||||
|
||||
### 2. Query KYC Status
|
||||
|
||||
```bash
|
||||
# Query KYC status for user1
|
||||
peer chaincode query -C mychannel -n nivix-kyc -c '{"function":"GetKYCStatus","Args":["Sol123456789"]}'
|
||||
|
||||
# Query KYC status for user2
|
||||
peer chaincode query -C mychannel -n nivix-kyc -c '{"function":"GetKYCStatus","Args":["Sol987654321"]}'
|
||||
```
|
||||
|
||||
### 3. Record Solana Transaction
|
||||
|
||||
```bash
|
||||
# Record a transaction from Solana
|
||||
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n nivix-kyc --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"RecordTransaction","Args":["tx123", "solSig456", "user1", "user2", "100.5", "USDC", "2025-05-17T17:36:00Z"]}'
|
||||
```
|
||||
|
||||
## Understanding the Chaincode
|
||||
|
||||
The Nivix KYC chaincode provides the following functions:
|
||||
|
||||
1. `StoreKYCData`: Stores KYC information in a private data collection while maintaining a public reference of KYC status.
|
||||
|
||||
2. `GetKYCStatus`: Retrieves the public KYC status of a user by their Solana address without exposing personal information.
|
||||
|
||||
3. `RecordTransaction`: Records transaction data from Solana on the Hyperledger Fabric network for compliance and auditing purposes.
|
||||
|
||||
4. `GetTransactionSummary`: Retrieves a public summary of a transaction by its ID.
|
||||
|
||||
## Bringing Down the Network
|
||||
|
||||
When you're finished testing, you can bring down the network:
|
||||
|
||||
```bash
|
||||
./network.sh down
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
1. If you encounter chaincode installation errors, ensure that:
|
||||
- All required dependencies are installed
|
||||
- Go modules are properly set up
|
||||
- The chaincode path is correct
|
||||
|
||||
2. For issues with private collections:
|
||||
- Verify the collections configuration file is properly formatted
|
||||
- Check that `requiredPeerCount` is set to 0 if testing with minimal peers
|
||||
- Ensure the collection policy matches the channel members
|
||||
|
||||
3. If chaincode invocation fails:
|
||||
- Check that all parameters are correctly passed
|
||||
- Verify the function name matches exactly what's in the chaincode
|
||||
- Ensure the chaincode was successfully committed with collections config
|
||||
33
chaincode-nivix-kyc/go/nivix-kyc/go.mod
Normal file
33
chaincode-nivix-kyc/go/nivix-kyc/go.mod
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
module github.com/hyperledger/fabric-samples/chaincode-nivix-kyc/go/nivix-kyc
|
||||
|
||||
go 1.20
|
||||
|
||||
require github.com/hyperledger/fabric-contract-api-go v1.2.2
|
||||
|
||||
require (
|
||||
github.com/go-openapi/jsonpointer v0.20.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/spec v0.20.9 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/gobuffalo/envy v1.10.2 // indirect
|
||||
github.com/gobuffalo/packd v1.0.2 // indirect
|
||||
github.com/gobuffalo/packr v1.30.1 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/hyperledger/fabric-chaincode-go v0.0.0-20230731094759-d626e9ab09b9 // indirect
|
||||
github.com/hyperledger/fabric-protos-go v0.3.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
154
chaincode-nivix-kyc/go/nivix-kyc/go.sum
Normal file
154
chaincode-nivix-kyc/go/nivix-kyc/go.sum
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
|
||||
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
|
||||
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/envy v1.10.2 h1:EIi03p9c3yeuRCFPOKcSfajzkLb3hrRjEpHGI8I2Wo4=
|
||||
github.com/gobuffalo/envy v1.10.2/go.mod h1:qGAGwdvDsaEtPhfBzb3o0SfDea8ByGn9j8bKmVft9z8=
|
||||
github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
|
||||
github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
|
||||
github.com/gobuffalo/packd v1.0.2 h1:Yg523YqnOxGIWCp69W12yYBKsoChwI7mtu6ceM9Bwfw=
|
||||
github.com/gobuffalo/packd v1.0.2/go.mod h1:sUc61tDqGMXON80zpKGp92lDb86Km28jfvX7IAyxFT8=
|
||||
github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg=
|
||||
github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk=
|
||||
github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hyperledger/fabric-chaincode-go v0.0.0-20230731094759-d626e9ab09b9 h1:XV1mxAmExeWraP5AmBSB1v415jMCSFJ087dRUiI6f6o=
|
||||
github.com/hyperledger/fabric-chaincode-go v0.0.0-20230731094759-d626e9ab09b9/go.mod h1:WEd2Rlyj47/8b0VvH/zYPKamLdU3hg7jWqV8XEBTLOk=
|
||||
github.com/hyperledger/fabric-contract-api-go v1.2.2 h1:zun9/BmaIWFSSOkfQXikdepK0XDb7MkJfc/lb5j3ku8=
|
||||
github.com/hyperledger/fabric-contract-api-go v1.2.2/go.mod h1:UnFLlRFn8GvXE7mXxWtU+bESM7fb5YzsKo1DA16vvaE=
|
||||
github.com/hyperledger/fabric-protos-go v0.3.0 h1:MXxy44WTMENOh5TI8+PCK2x6pMj47Go2vFRKDHB2PZs=
|
||||
github.com/hyperledger/fabric-protos-go v0.3.0/go.mod h1:WWnyWP40P2roPmmvxsUXSvVI/CF6vwY1K1UFidnKBys=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
226
chaincode-nivix-kyc/go/nivix-kyc/nivix-kyc.go
Normal file
226
chaincode-nivix-kyc/go/nivix-kyc/nivix-kyc.go
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/hyperledger/fabric-contract-api-go/contractapi"
|
||||
)
|
||||
|
||||
// KYCRecord structure for KYC data
|
||||
type KYCRecord struct {
|
||||
UserID string `json:"userId"`
|
||||
SolanaAddress string `json:"solanaAddress"`
|
||||
FullName string `json:"fullName"`
|
||||
KYCVerified bool `json:"kycVerified"`
|
||||
VerificationDate string `json:"verificationDate"`
|
||||
RiskScore int `json:"riskScore"`
|
||||
DocumentHash string `json:"documentHash"`
|
||||
}
|
||||
|
||||
// TransactionRecord structure to track transactions
|
||||
type TransactionRecord struct {
|
||||
TxID string `json:"txId"`
|
||||
SolanaSignature string `json:"solanaSignature"`
|
||||
FromUser string `json:"fromUser"`
|
||||
ToUser string `json:"toUser"`
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
// NivixKYCContract manages KYC data for Nivix platform
|
||||
type NivixKYCContract struct {
|
||||
contractapi.Contract
|
||||
}
|
||||
|
||||
// StoreKYCData stores KYC information in a private data collection
|
||||
func (s *NivixKYCContract) StoreKYCData(ctx contractapi.TransactionContextInterface,
|
||||
userId string,
|
||||
solanaAddress string,
|
||||
fullName string,
|
||||
kycVerified bool,
|
||||
verificationDate string,
|
||||
riskScore int,
|
||||
documentHash string) error {
|
||||
|
||||
// Create the KYC record
|
||||
kycRecord := KYCRecord{
|
||||
UserID: userId,
|
||||
SolanaAddress: solanaAddress,
|
||||
FullName: fullName,
|
||||
KYCVerified: kycVerified,
|
||||
VerificationDate: verificationDate,
|
||||
RiskScore: riskScore,
|
||||
DocumentHash: documentHash,
|
||||
}
|
||||
|
||||
// Convert to JSON
|
||||
kycJSON, err := json.Marshal(kycRecord)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal KYC data: %v", err)
|
||||
}
|
||||
|
||||
// Store in private data collection
|
||||
// Note: In production, this should go to a private data collection
|
||||
err = ctx.GetStub().PutPrivateData("kycCollection", userId, kycJSON)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to store KYC data: %v", err)
|
||||
}
|
||||
|
||||
// Store a public reference that this user has KYC (without personal details)
|
||||
publicData := struct {
|
||||
SolanaAddress string `json:"solanaAddress"`
|
||||
KYCVerified bool `json:"kycVerified"`
|
||||
RiskScore int `json:"riskScore"`
|
||||
}{
|
||||
SolanaAddress: solanaAddress,
|
||||
KYCVerified: kycVerified,
|
||||
RiskScore: riskScore,
|
||||
}
|
||||
|
||||
publicJSON, err := json.Marshal(publicData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal public KYC data: %v", err)
|
||||
}
|
||||
|
||||
// Store public reference on the main ledger
|
||||
return ctx.GetStub().PutState(solanaAddress, publicJSON)
|
||||
}
|
||||
|
||||
// GetKYCStatus quickly checks if a Solana address has KYC verification
|
||||
func (s *NivixKYCContract) GetKYCStatus(ctx contractapi.TransactionContextInterface,
|
||||
solanaAddress string) (*struct {
|
||||
SolanaAddress string `json:"solanaAddress"`
|
||||
KYCVerified bool `json:"kycVerified"`
|
||||
RiskScore int `json:"riskScore"`
|
||||
}, error) {
|
||||
kycBytes, err := ctx.GetStub().GetState(solanaAddress)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read KYC status: %v", err)
|
||||
}
|
||||
if kycBytes == nil {
|
||||
return nil, fmt.Errorf("the Solana address %s has no KYC record", solanaAddress)
|
||||
}
|
||||
|
||||
var kycStatus struct {
|
||||
SolanaAddress string `json:"solanaAddress"`
|
||||
KYCVerified bool `json:"kycVerified"`
|
||||
RiskScore int `json:"riskScore"`
|
||||
}
|
||||
|
||||
err = json.Unmarshal(kycBytes, &kycStatus)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal KYC data: %v", err)
|
||||
}
|
||||
|
||||
return &kycStatus, nil
|
||||
}
|
||||
|
||||
// RecordTransaction stores a transaction record from Solana
|
||||
func (s *NivixKYCContract) RecordTransaction(ctx contractapi.TransactionContextInterface,
|
||||
txId string,
|
||||
solanaSignature string,
|
||||
fromUser string,
|
||||
toUser string,
|
||||
amount float64,
|
||||
currency string,
|
||||
timestamp string) error {
|
||||
|
||||
// Create transaction record
|
||||
txRecord := TransactionRecord{
|
||||
TxID: txId,
|
||||
SolanaSignature: solanaSignature,
|
||||
FromUser: fromUser,
|
||||
ToUser: toUser,
|
||||
Amount: amount,
|
||||
Currency: currency,
|
||||
Timestamp: timestamp,
|
||||
Status: "completed",
|
||||
}
|
||||
|
||||
// Convert to JSON
|
||||
txJSON, err := json.Marshal(txRecord)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal transaction data: %v", err)
|
||||
}
|
||||
|
||||
// Store in private data collection
|
||||
err = ctx.GetStub().PutPrivateData("transactionCollection", txId, txJSON)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to store transaction data: %v", err)
|
||||
}
|
||||
|
||||
// Store public reference to transaction
|
||||
publicData := struct {
|
||||
TxID string `json:"txId"`
|
||||
SolanaSignature string `json:"solanaSignature"`
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Status string `json:"status"`
|
||||
}{
|
||||
TxID: txId,
|
||||
SolanaSignature: solanaSignature,
|
||||
Amount: amount,
|
||||
Currency: currency,
|
||||
Timestamp: timestamp,
|
||||
Status: "completed",
|
||||
}
|
||||
|
||||
publicJSON, err := json.Marshal(publicData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal public transaction data: %v", err)
|
||||
}
|
||||
|
||||
// Store public reference on the main ledger
|
||||
return ctx.GetStub().PutState("tx_"+txId, publicJSON)
|
||||
}
|
||||
|
||||
// GetTransactionSummary gets the public transaction data
|
||||
func (s *NivixKYCContract) GetTransactionSummary(ctx contractapi.TransactionContextInterface,
|
||||
txId string) (*struct {
|
||||
TxID string `json:"txId"`
|
||||
SolanaSignature string `json:"solanaSignature"`
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Status string `json:"status"`
|
||||
}, error) {
|
||||
txBytes, err := ctx.GetStub().GetState("tx_" + txId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read transaction: %v", err)
|
||||
}
|
||||
if txBytes == nil {
|
||||
return nil, fmt.Errorf("the transaction %s does not exist", txId)
|
||||
}
|
||||
|
||||
var txSummary struct {
|
||||
TxID string `json:"txId"`
|
||||
SolanaSignature string `json:"solanaSignature"`
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
err = json.Unmarshal(txBytes, &txSummary)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal transaction data: %v", err)
|
||||
}
|
||||
|
||||
return &txSummary, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
chaincode, err := contractapi.NewChaincode(&NivixKYCContract{})
|
||||
if err != nil {
|
||||
log.Panicf("Error creating nivix-kyc chaincode: %v", err)
|
||||
}
|
||||
|
||||
if err := chaincode.Start(); err != nil {
|
||||
log.Panicf("Error starting nivix-kyc chaincode: %v", err)
|
||||
}
|
||||
}
|
||||
108
nivix-commands.txt
Normal file
108
nivix-commands.txt
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# NIVIX HYBRID BLOCKCHAIN - IMPORTANT COMMANDS
|
||||
|
||||
## NETWORK MANAGEMENT
|
||||
|
||||
# Bring down any existing network
|
||||
./network.sh down
|
||||
|
||||
# Start a fresh Fabric network
|
||||
./network.sh up
|
||||
|
||||
# Create a channel named "mychannel"
|
||||
./network.sh createChannel
|
||||
|
||||
# Bring down the network when done
|
||||
./network.sh down
|
||||
|
||||
## CHAINCODE PREPARATION
|
||||
|
||||
# Navigate to the chaincode directory
|
||||
cd /media/shubham/OS/for\ linux\ work/blockchain\ solana/hyperledger/fabric/fabric-samples/chaincode-nivix-kyc/go/nivix-kyc
|
||||
|
||||
# Add required dependencies
|
||||
go get github.com/hyperledger/fabric-contract-api-go/contractapi
|
||||
go mod tidy
|
||||
|
||||
# Prepare vendor directory
|
||||
go mod vendor
|
||||
|
||||
## CHAINCODE DEPLOYMENT
|
||||
|
||||
# Return to the test-network directory
|
||||
cd /media/shubham/OS/for\ linux\ work/blockchain\ solana/hyperledger/fabric/fabric-samples/test-network
|
||||
|
||||
# Install jq (required by scripts)
|
||||
sudo apt-get update && sudo apt-get install -y jq
|
||||
|
||||
# First deployment of chaincode
|
||||
./network.sh deployCC -ccn nivix-kyc -ccp ../chaincode-nivix-kyc/go/nivix-kyc -ccl go
|
||||
|
||||
## PRIVATE COLLECTIONS SETUP
|
||||
|
||||
# Set environment variables for Org1
|
||||
export PATH=${PWD}/../bin:$PATH
|
||||
export FABRIC_CFG_PATH=$PWD/../config/
|
||||
export CORE_PEER_TLS_ENABLED=true
|
||||
export CORE_PEER_LOCALMSPID="Org1MSP"
|
||||
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
|
||||
export CORE_PEER_ADDRESS=localhost:7051
|
||||
|
||||
# Approve chaincode with collections for Org1
|
||||
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name nivix-kyc --version 1.2 --package-id nivix-kyc_1.1:5ef7a3ff23f8d69ed809eb2863c129d83fa780069026d2615545b4136ae003bd --sequence 3 --collections-config "${PWD}/collections_config.json"
|
||||
|
||||
# Set environment variables for Org2
|
||||
export CORE_PEER_LOCALMSPID="Org2MSP"
|
||||
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
|
||||
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
|
||||
export CORE_PEER_ADDRESS=localhost:9051
|
||||
|
||||
# Approve chaincode with collections for Org2
|
||||
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name nivix-kyc --version 1.2 --package-id nivix-kyc_1.1:5ef7a3ff23f8d69ed809eb2863c129d83fa780069026d2615545b4136ae003bd --sequence 3 --collections-config "${PWD}/collections_config.json"
|
||||
|
||||
# Reset to Org1 for commit
|
||||
export CORE_PEER_LOCALMSPID="Org1MSP"
|
||||
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
|
||||
export CORE_PEER_ADDRESS=localhost:7051
|
||||
|
||||
# Commit the chaincode definition with collections
|
||||
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --channelID mychannel --name nivix-kyc --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" --version 1.2 --sequence 3 --collections-config "${PWD}/collections_config.json"
|
||||
|
||||
## KYC OPERATIONS
|
||||
|
||||
# Store KYC data for user1
|
||||
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n nivix-kyc --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"StoreKYCData","Args":["user1", "Sol123456789", "John Doe", "true", "2025-05-17", "10", "a1b2c3d4e5f6"]}'
|
||||
|
||||
# Store KYC data for user2
|
||||
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n nivix-kyc --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"StoreKYCData","Args":["user2", "Sol987654321", "Jane Smith", "true", "2025-05-17", "5", "f6e5d4c3b2a1"]}'
|
||||
|
||||
# Query KYC status for user1
|
||||
peer chaincode query -C mychannel -n nivix-kyc -c '{"function":"GetKYCStatus","Args":["Sol123456789"]}'
|
||||
|
||||
# Query KYC status for user2
|
||||
peer chaincode query -C mychannel -n nivix-kyc -c '{"function":"GetKYCStatus","Args":["Sol987654321"]}'
|
||||
|
||||
## TRANSACTION RECORDING
|
||||
|
||||
# Record a transaction from Solana
|
||||
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n nivix-kyc --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"RecordTransaction","Args":["tx123", "solSig456", "user1", "user2", "100.5", "USDC", "2025-05-17T17:36:00Z"]}'
|
||||
|
||||
## CHANNEL EXAMINATION
|
||||
|
||||
# List channels the peer has joined
|
||||
peer channel list
|
||||
|
||||
# Get information about the channel
|
||||
peer channel getinfo -c mychannel
|
||||
|
||||
## CHAINCODE EXAMINATION
|
||||
|
||||
# List installed chaincodes
|
||||
peer lifecycle chaincode queryinstalled
|
||||
|
||||
# Query committed chaincode definitions
|
||||
peer lifecycle chaincode querycommitted --channelID mychannel
|
||||
|
||||
# Check specific chaincode commitment status
|
||||
peer lifecycle chaincode querycommitted --channelID mychannel --name nivix-kyc
|
||||
26
test-network/collections_config.json
Normal file
26
test-network/collections_config.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
[
|
||||
{
|
||||
"name": "kycCollection",
|
||||
"policy": "OR('Org1MSP.member', 'Org2MSP.member')",
|
||||
"requiredPeerCount": 0,
|
||||
"maxPeerCount": 1,
|
||||
"blockToLive": 1000000,
|
||||
"memberOnlyRead": true,
|
||||
"memberOnlyWrite": true,
|
||||
"endorsementPolicy": {
|
||||
"signaturePolicy": "OR('Org1MSP.member', 'Org2MSP.member')"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "transactionCollection",
|
||||
"policy": "OR('Org1MSP.member', 'Org2MSP.member')",
|
||||
"requiredPeerCount": 0,
|
||||
"maxPeerCount": 1,
|
||||
"blockToLive": 1000000,
|
||||
"memberOnlyRead": true,
|
||||
"memberOnlyWrite": true,
|
||||
"endorsementPolicy": {
|
||||
"signaturePolicy": "OR('Org1MSP.member', 'Org2MSP.member')"
|
||||
}
|
||||
}
|
||||
]
|
||||
Loading…
Reference in a new issue