fabric-samples/chaincode-nivix-kyc/go/nivix-kyc/nivix-kyc.go

226 lines
No EOL
6.7 KiB
Go

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)
}
}