Kubernetes Üzerinde Hyperledger Fabric Ağının Kurulumu ve Yönetimi
Tags: hyperledger, fabric, kubernetes, blockchain
Published: 2024-01-02 11:26:17

:bangbang: Ön Koşullar:

- Bir önceki serideki adımların yapılmış olması gerekmektedir.

#Adım 1: Gerekli Değişkenlerin Tanımlanması

Bu adımda, Fabric ağ bileşenleri için Docker imajları ve sürümleri belirleniyor. Bu, kurulum sürecinde kullanılacak temel yapılandırma bilgileridir.

```
export PEER_IMAGE=hyperledger/fabric-peer
export PEER_VERSION=2.5.0
export ORDERER_IMAGE=hyperledger/fabric-orderer
export ORDERER_VERSION=2.5.0
export CA_IMAGE=hyperledger/fabric-ca
export CA_VERSION=1.5.6
```

#Adım 2: Cluster IP'nin Alınması ve CoreDNS Konfigürasyonu

Kubernetes cluster IP adresi alınıyor ve CoreDNS için özel bir yapılandırma yapılıyor. Bu, ağ trafiğinin yönlendirilmesi ve yönetilmesi için önemlidir.

```
sudo apt install jq

CLUSTER_IP=$(kubectl -n istio-system get svc istio-ingressgateway -o json | jq -r .spec.clusterIP)
kubectl apply -f - <<EOF
kind: ConfigMap
apiVersion: v1
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        rewrite name regex (.*)\.localho\.st host.ingress.internal
        hosts {
          ${CLUSTER_IP} host.ingress.internal
          fallthrough
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
EOF
```

#Adım 3: CA Kurulumu ve Peer Kayıtları

 Sertifika otoritesi (CA) kurulumu ve peer kayıtları yapılıyor. Bu adım, ağın güvenlik ve kimlik doğrulama mekanizmalarının temelini oluşturur.

**Org1:**

```
# CA Kurulumu org1 için
kubectl hlf ca create --image=$CA_IMAGE --version=$CA_VERSION --storage-class=standard --capacity=1Gi --name=org1-ca \
    --enroll-id=enroll --enroll-pw=enrollpw --hosts=org1-ca.localho.st --istio-port=443

kubectl wait --timeout=180s --for=condition=Running fabriccas.hlf.kungfusoftware.es --all

curl -k https://org1-ca.localho.st:443/cainfo

# Peerler için org1'de kullanıcı kaydı
kubectl hlf ca register --name=org1-ca --user=peer --secret=peerpw --type=peer \
 --enroll-id enroll --enroll-secret=enrollpw --mspid Org1MSP

# Peer Kurulumu org1 için
kubectl hlf peer create --statedb=couchdb --image=$PEER_IMAGE --version=$PEER_VERSION --storage-class=standard --enroll-id=peer --mspid=Org1MSP \
        --enroll-pw=peerpw --capacity=5Gi --name=org1-peer0 --ca-name=org1-ca.default \
        --hosts=peer0-org1.localho.st --istio-port=443


kubectl wait --timeout=180s --for=condition=Running fabricpeers.hlf.kungfusoftware.es --all
```

**Org2:**
```
# CA Kurulumu org2 için
kubectl hlf ca create --image=$CA_IMAGE --version=$CA_VERSION --storage-class=standard --capacity=1Gi --name=org2-ca \
    --enroll-id=enroll --enroll-pw=enrollpw --hosts=org2-ca.localho.st --istio-port=443

kubectl wait --timeout=180s --for=condition=Running fabriccas.hlf.kungfusoftware.es --all

curl -k https://org2-ca.localho.st:443/cainfo

# Peerler için org2'de kullanıcı kaydı
kubectl hlf ca register --name=org2-ca --user=peer --secret=peerpw --type=peer \
 --enroll-id enroll --enroll-secret=enrollpw --mspid Org2MSP

# Peer Kurulumu org2 için
kubectl hlf peer create --statedb=couchdb --image=$PEER_IMAGE --version=$PEER_VERSION --storage-class=standard --enroll-id=peer --mspid=Org2MSP \
        --enroll-pw=peerpw --capacity=5Gi --name=org2-peer0 --ca-name=org2-ca.default \
        --hosts=peer0-org2.localho.st --istio-port=443


kubectl wait --timeout=180s --for=condition=Running fabricpeers.hlf.kungfusoftware.es --all
```

**Org3:**
```
# CA Kurulumu org3 için
kubectl hlf ca create --image=$CA_IMAGE --version=$CA_VERSION --storage-class=standard --capacity=1Gi --name=org3-ca \
    --enroll-id=enroll --enroll-pw=enrollpw --hosts=org3-ca.localho.st --istio-port=443

kubectl wait --timeout=180s --for=condition=Running fabriccas.hlf.kungfusoftware.es --all

curl -k https://org3-ca.localho.st:443/cainfo

# Peerler için org3'de kullanıcı kaydı
kubectl hlf ca register --name=org3-ca --user=peer --secret=peerpw --type=peer \
 --enroll-id enroll --enroll-secret=enrollpw --mspid Org3MSP

# Peer Kurulumu org3 için
kubectl hlf peer create --statedb=couchdb --image=$PEER_IMAGE --version=$PEER_VERSION --storage-class=standard --enroll-id=peer --mspid=Org3MSP \
        --enroll-pw=peerpw --capacity=5Gi --name=org3-peer0 --ca-name=org3-ca.default \
        --hosts=peer0-org3.localho.st --istio-port=443


kubectl wait --timeout=180s --for=condition=Running fabricpeers.hlf.kungfusoftware.es --all
```

**Org4:**
```
# CA Kurulumu org4 için
kubectl hlf ca create --image=$CA_IMAGE --version=$CA_VERSION --storage-class=standard --capacity=1Gi --name=org4-ca \
    --enroll-id=enroll --enroll-pw=enrollpw --hosts=org4-ca.localho.st --istio-port=443

kubectl wait --timeout=180s --for=condition=Running fabriccas.hlf.kungfusoftware.es --all

curl -k https://org4-ca.localho.st:443/cainfo

# Peerler için org4'de kullanıcı kaydı
kubectl hlf ca register --name=org4-ca --user=peer --secret=peerpw --type=peer \
 --enroll-id enroll --enroll-secret=enrollpw --mspid Org4MSP

# Peer Kurulumu org4 için
kubectl hlf peer create --statedb=couchdb --image=$PEER_IMAGE --version=$PEER_VERSION --storage-class=standard --enroll-id=peer --mspid=Org4MSP \
        --enroll-pw=peerpw --capacity=5Gi --name=org4-peer0 --ca-name=org4-ca.default \
        --hosts=peer0-org4.localho.st --istio-port=443


kubectl wait --timeout=180s --for=condition=Running fabricpeers.hlf.kungfusoftware.es --all
```


#Adım 4: Orderer Kurulumu

İşlem sıralayıcı (orderer) bileşeninin kurulumu ve yapılandırılması gerçekleştiriliyor. Orderer, ağ üzerindeki işlemlerin düzenini ve tutarlılığını sağlar.

```
kubectl hlf ca create  --image=$CA_IMAGE --version=$CA_VERSION --storage-class=standard --capacity=1Gi --name=ord-ca \
    --enroll-id=enroll --enroll-pw=enrollpw --hosts=ord-ca.localho.st --istio-port=443

kubectl wait --timeout=180s --for=condition=Running fabriccas.hlf.kungfusoftware.es --all


curl -vik https://ord-ca.localho.st:443/cainfo

kubectl hlf ca register --name=ord-ca --user=orderer --secret=ordererpw \
    --type=orderer --enroll-id enroll --enroll-secret=enrollpw --mspid=OrdererMSP --ca-url="https://ord-ca.localho.st:443"

kubectl hlf ordnode create --image=$ORDERER_IMAGE --version=$ORDERER_VERSION \
    --storage-class=standard --enroll-id=orderer --mspid=OrdererMSP \
    --enroll-pw=ordererpw --capacity=2Gi --name=ord-node1 --ca-name=ord-ca.default \
    --hosts=orderer0-ord.localho.st --istio-port=443

kubectl wait --timeout=180s --for=condition=Running fabricorderernodes.hlf.kungfusoftware.es --all

kubectl get pods

openssl s_client -connect orderer0-ord.localho.st:443
```

#Adım 5: Kullanıcı Kaydı 

Bu adımda, orderer ve diğer organizasyonlar için kullanıcı kayıtları yapılarak ağ üzerindeki roller ve yetkiler tanımlanıyor.

**Orderer:**

```
# register
kubectl hlf ca register --name=ord-ca --user=admin --secret=adminpw \
    --type=admin --enroll-id enroll --enroll-secret=enrollpw --mspid=OrdererMSP

# enroll

kubectl hlf ca enroll --name=ord-ca --namespace=default \
    --user=admin --secret=adminpw --mspid OrdererMSP \
    --ca-name tlsca  --output orderermsp.yaml
```

**Org1:**

```
# Kullanıcı Kaydı (Register)
kubectl hlf ca register --name=org1-ca --namespace=default --user=admin --secret=adminpw \
    --type=admin --enroll-id enroll --enroll-secret=enrollpw --mspid=Org1MSP

# Kayıt (Enroll)
kubectl hlf ca enroll --name=org1-ca --namespace=default \
    --user=admin --secret=adminpw --mspid Org1MSP \
    --ca-name ca --output org1msp.yaml
```

**Org2:**
```
# Kullanıcı Kaydı (Register)
kubectl hlf ca register --name=org2-ca --namespace=default --user=admin --secret=adminpw \
    --type=admin --enroll-id enroll --enroll-secret=enrollpw --mspid=Org2MSP

# Kayıt (Enroll)
kubectl hlf ca enroll --name=org2-ca --namespace=default \
    --user=admin --secret=adminpw --mspid Org2MSP \
    --ca-name ca --output org2msp.yaml
```

**Org3:**

```
# Kullanıcı Kaydı (Register)
kubectl hlf ca register --name=org3-ca --namespace=default --user=admin --secret=adminpw \
    --type=admin --enroll-id enroll --enroll-secret=enrollpw --mspid=Org3MSP

# Kayıt (Enroll)
kubectl hlf ca enroll --name=org3-ca --namespace=default \
    --user=admin --secret=adminpw --mspid Org3MSP \
    --ca-name ca --output org3msp.yaml
```

**Org4:**

```
# Kullanıcı Kaydı (Register)
kubectl hlf ca register --name=org4-ca --namespace=default --user=admin --secret=adminpw \
    --type=admin --enroll-id enroll --enroll-secret=enrollpw --mspid=Org4MSP

# Kayıt (Enroll)
kubectl hlf ca enroll --name=org4-ca --namespace=default \
    --user=admin --secret=adminpw --mspid Org4MSP \
    --ca-name ca --output org4msp.yaml
```

#Adım 6: Cüzdan Oluşturma

Bu adımda, MSP (Membership Service Provider) bilgilerini içeren bir cüzdan (wallet) oluşturuluyor. Bu cüzdan, ağdaki çeşitli bileşenlerin kimlik bilgilerini güvenli bir şekilde saklar.

```
# Secret Oluşturma
kubectl create secret generic wallet --namespace=default \
        --from-file=org1msp.yaml=$PWD/org1msp.yaml \
        --from-file=org2msp.yaml=$PWD/org2msp.yaml \
        --from-file=org3msp.yaml=$PWD/org3msp.yaml \
        --from-file=org4msp.yaml=$PWD/org4msp.yaml \
        --from-file=orderermsp.yaml=$PWD/orderermsp.yaml
```

#Adım 7: Ana Kanalın Oluşturulması (demo kanalı)

Ağın ana iletişim kanalı, demo kanalı oluşturuluyor. Bu kanal, ağdaki tüm peerler ve ordererlar arasında iletişimi sağlar. Kanalın yapılandırması, ağın temel operasyonel parametrelerini belirler.
```
export PEER_ORG_SIGN_CERT=$(kubectl get fabriccas org1-ca -o=jsonpath='{.status.ca_cert}')
export PEER_ORG_TLS_CERT=$(kubectl get fabriccas org1-ca -o=jsonpath='{.status.tlsca_cert}')
export IDENT_8=$(printf "%8s" "")
export PEER_ORG_SIGN_CERT=$(kubectl get fabriccas org2-ca -o=jsonpath='{.status.ca_cert}')
export PEER_ORG_TLS_CERT=$(kubectl get fabriccas org2-ca -o=jsonpath='{.status.tlsca_cert}')
export IDENT_8=$(printf "%8s" "")
export PEER_ORG_SIGN_CERT=$(kubectl get fabriccas org3-ca -o=jsonpath='{.status.ca_cert}')
export PEER_ORG_TLS_CERT=$(kubectl get fabriccas org3-ca -o=jsonpath='{.status.tlsca_cert}')
export IDENT_8=$(printf "%8s" "")
export PEER_ORG_SIGN_CERT=$(kubectl get fabriccas org4-ca -o=jsonpath='{.status.ca_cert}')
export PEER_ORG_TLS_CERT=$(kubectl get fabriccas org4-ca -o=jsonpath='{.status.tlsca_cert}')
export IDENT_8=$(printf "%8s" "")
export ORDERER_TLS_CERT=$(kubectl get fabriccas ord-ca -o=jsonpath='{.status.tlsca_cert}' | sed -e "s/^/${IDENT_8}/" )
export ORDERER0_TLS_CERT=$(kubectl get fabricorderernodes ord-node1 -o=jsonpath='{.status.tlsCert}' | sed -e "s/^/        /" )

kubectl apply -f - <<EOF
apiVersion: hlf.kungfusoftware.es/v1alpha1
kind: FabricMainChannel
metadata:
  name: demo
spec:
  name: demo
  adminOrdererOrganizations:
    - mspID: OrdererMSP
  adminPeerOrganizations:
    - mspID: Org1MSP
    - mspID: Org2MSP
    - mspID: Org3MSP
    - mspID: Org4MSP
  channelConfig:
    application:
      acls: null
      capabilities:
        - V2_0
      policies: null
    capabilities:
      - V2_0
    orderer:
      batchSize:
        absoluteMaxBytes: 1048576
        maxMessageCount: 10
        preferredMaxBytes: 524288
      batchTimeout: 2s
      capabilities:
        - V2_0
      etcdRaft:
        options:
          electionTick: 10
          heartbeatTick: 1
          maxInflightBlocks: 5
          snapshotIntervalSize: 16777216
          tickInterval: 500ms
      ordererType: etcdraft
      policies: null
      state: STATE_NORMAL
    policies: null
  externalOrdererOrganizations: []
  peerOrganizations:
    - mspID: Org1MSP
      caName: "org1-ca"
      caNamespace: "default"
    - mspID: Org2MSP
      caName: "org2-ca"
      caNamespace: "default"
    - mspID: Org3MSP
      caName: "org3-ca"
      caNamespace: "default"
    - mspID: Org4MSP
      caName: "org4-ca"
      caNamespace: "default"
  identities:
    OrdererMSP:
      secretKey: orderermsp.yaml
      secretName: wallet
      secretNamespace: default
    Org1MSP:
      secretKey: org1msp.yaml
      secretName: wallet
      secretNamespace: default
    Org2MSP:
      secretKey: org2msp.yaml
      secretName: wallet
      secretNamespace: default
    Org3MSP:
      secretKey: org3msp.yaml
      secretName: wallet
      secretNamespace: default
    Org4MSP:
      secretKey: org4msp.yaml
      secretName: wallet
      secretNamespace: default
  externalPeerOrganizations: []
  ordererOrganizations:
    - caName: "ord-ca"
      caNamespace: "default"
      externalOrderersToJoin:
        - host: ord-node1
          port: 7053
      mspID: OrdererMSP
      ordererEndpoints:
        - ord-node1:7050
      orderersToJoin: []
  orderers:
    - host: ord-node1
      port: 7050
      tlsCert: |-
${ORDERER0_TLS_CERT}
EOF
```

Kanalın oluşturulduğu kontrol edilir:

```
kubectl get fabricmainchannels.hlf.kungfusoftware.es
```

#Adım 8: Takipçi Kanalların Oluşturulması 

Her organizasyon için takipçi kanallar oluşturuluyor. Bu kanallar, ana demo kanalına bağlı olarak çalışır ve organizasyonların kendi peerlerine özel işlemleri yönetmesine olanak tanır.

**Org1:**

```
# org1 için
export IDENT_8=$(printf "%8s" "")
export ORDERER0_TLS_CERT=$(kubectl get fabricorderernodes ord-node1 -o=jsonpath='{.status.tlsCert}' | sed -e "s/^/${IDENT_8}/" )

kubectl apply -f - <<EOF
apiVersion: hlf.kungfusoftware.es/v1alpha1
kind: FabricFollowerChannel
metadata:
  name: demo-org1msp
spec:
  anchorPeers:
    - host: org1-peer0.default
      port: 7051
  hlfIdentity:
    secretKey: org1msp.yaml
    secretName: wallet
    secretNamespace: default
  mspId: Org1MSP
  name: demo
  externalPeersToJoin: []
  orderers:
    - certificate: |
${ORDERER0_TLS_CERT}
      url: grpcs://ord-node1.default:7050
  peersToJoin:
    - name: org1-peer0
      namespace: default
EOF
```

**Org2:**

```
# org2 için
export IDENT_8=$(printf "%8s" "")
export ORDERER0_TLS_CERT=$(kubectl get fabricorderernodes ord-node1 -o=jsonpath='{.status.tlsCert}' | sed -e "s/^/${IDENT_8}/" )

kubectl apply -f - <<EOF
apiVersion: hlf.kungfusoftware.es/v1alpha1
kind: FabricFollowerChannel
metadata:
  name: demo-org2msp
spec:
  anchorPeers:
    - host: org2-peer0.default
      port: 7051
  hlfIdentity:
    secretKey: org2msp.yaml
    secretName: wallet
    secretNamespace: default
  mspId: Org2MSP
  name: demo
  externalPeersToJoin: []
  orderers:
    - certificate: |
${ORDERER0_TLS_CERT}
      url: grpcs://ord-node1.default:7050
  peersToJoin:
    - name: org2-peer0
      namespace: default
EOF
```
**Org3:**

```
# org3 için
export IDENT_8=$(printf "%8s" "")
export ORDERER0_TLS_CERT=$(kubectl get fabricorderernodes ord-node1 -o=jsonpath='{.status.tlsCert}' | sed -e "s/^/${IDENT_8}/" )

kubectl apply -f - <<EOF
apiVersion: hlf.kungfusoftware.es/v1alpha1
kind: FabricFollowerChannel
metadata:
  name: demo-org3msp
spec:
  anchorPeers:
    - host: org3-peer0.default
      port: 7051
  hlfIdentity:
    secretKey: org3msp.yaml
    secretName: wallet
    secretNamespace: default
  mspId: Org3MSP
  name: demo
  externalPeersToJoin: []
  orderers:
    - certificate: |
${ORDERER0_TLS_CERT}
      url: grpcs://ord-node1.default:7050
  peersToJoin:
    - name: org3-peer0
      namespace: default
EOF
```

**Org4:**

```
# org4 için
export IDENT_8=$(printf "%8s" "")
export ORDERER0_TLS_CERT=$(kubectl get fabricorderernodes ord-node1 -o=jsonpath='{.status.tlsCert}' | sed -e "s/^/${IDENT_8}/" )

kubectl apply -f - <<EOF
apiVersion: hlf.kungfusoftware.es/v1alpha1
kind: FabricFollowerChannel
metadata:
  name: demo-org4msp
spec:
  anchorPeers:
    - host: org4-peer0.default
      port: 7051
  hlfIdentity:
    secretKey: org4msp.yaml
    secretName: wallet
    secretNamespace: default
  mspId: Org4MSP
  name: demo
  externalPeersToJoin: []
  orderers:
    - certificate: |
${ORDERER0_TLS_CERT}
      url: grpcs://ord-node1.default:7050
  peersToJoin:
    - name: org4-peer0
      namespace: default
EOF
```

Peer'ların kanala dahil olduğu kontrol edilir:

```
kubectl get fabricfollowerchannels.hlf.kungfusoftware.es
```

#Adım 9: Ağ Yapılandırmasının İncelenmesi

Burada, oluşturulan ağın genel yapılandırması inceleniyor ve network.yaml dosyası oluşturuluyor. Bu dosya, ağın yapılandırma detaylarını içerir.

```
kubectl hlf inspect --output network.yaml -o Org1MSP -o Org2MSP -o Org3MSP -o Org4MSP -o OrdererMSP
```

#Adım 10: CA Kayıt İşlemleri

Bu adımda, her organizasyon için CA'ya (Certificate Authority) admin kullanıcıları kaydediliyor. Bu işlem, ağın güvenliğinin temelini oluşturur.

```
kubectl hlf ca register --name=org1-ca --user=admin --secret=adminpw --type=admin \
 --enroll-id enroll --enroll-secret=enrollpw --mspid Org1MSP \
 --attributes="isAdmin=true:ecert,role=isAdmin:ecert"

kubectl hlf ca register --name=org2-ca --user=admin --secret=adminpw --type=admin \
 --enroll-id enroll --enroll-secret=enrollpw --mspid Org2MSP \
 --attributes="isAdmin=true:ecert,role=isAdmin:ecert"

kubectl hlf ca register --name=org3-ca --user=admin --secret=adminpw --type=admin \
 --enroll-id enroll --enroll-secret=enrollpw --mspid Org3MSP \
 --attributes="isAdmin=true:ecert,role=isAdmin:ecert"

kubectl hlf ca register --name=org4-ca --user=admin --secret=adminpw --type=admin \
 --enroll-id enroll --enroll-secret=enrollpw --mspid Org4MSP \
 --attributes="isAdmin=true:ecert,role=isAdmin:ecert"
```

#Adım 11: Kullanıcıların Kaydedilmesi

Her organizasyon için admin kullanıcıları, CA üzerinden kaydediliyor. Bu kullanıcılar, ağ üzerinde yönetici rollerini üstlenir.

```
kubectl hlf ca enroll --name=org1-ca --user=admin --secret=adminpw --mspid Org1MSP \
        --ca-name ca  --output peer-org1.yaml

kubectl hlf ca enroll --name=org2-ca --user=admin --secret=adminpw --mspid Org2MSP \
        --ca-name ca  --output peer-org2.yaml

kubectl hlf ca enroll --name=org3-ca --user=admin --secret=adminpw --mspid Org3MSP \
        --ca-name ca  --output peer-org3.yaml

kubectl hlf ca enroll --name=org4-ca --user=admin --secret=adminpw --mspid Org4MSP \
        --ca-name ca  --output peer-org4.yaml
```

#Adım 12: Kullanıcıların Ağa Eklenmesi

Kaydedilen kullanıcılar, ağa ekleniyor. Bu işlem, kullanıcıların ağ üzerindeki rollerini ve yetkilerini etkinleştirir.

```
kubectl hlf utils adduser --userPath=peer-org1.yaml --config=network.yaml --username=admin --mspid=Org1MSP

kubectl hlf utils adduser --userPath=peer-org2.yaml --config=network.yaml --username=admin --mspid=Org2MSP

kubectl hlf utils adduser --userPath=peer-org3.yaml --config=network.yaml --username=admin --mspid=Org3MSP

kubectl hlf utils adduser --userPath=peer-org4.yaml --config=network.yaml --username=admin --mspid=Org4MSP
```

#Adım 13: Chaincode Paketleme ve Yükleme

Bu adımda, ağ üzerinde çalıştırılacak olan chaincode (akıllı kontrat) paketleniyor ve peerlere yükleniyor.

```
rm code.tar.gz chaincode.tgz


export CHAINCODE_NAME=test
export CHAINCODE_LABEL=test

cat << METADATA-EOF > "metadata.json"
{
    "type": "ccaas",
    "label": "${CHAINCODE_LABEL}"
}
METADATA-EOF


cat > "connection.json" <<CONN_EOF
{
  "address": "${CHAINCODE_NAME}:7052",
  "dial_timeout": "10s",
  "tls_required": false
}
CONN_EOF



tar cfz code.tar.gz connection.json
tar cfz chaincode.tgz metadata.json code.tar.gz
export PACKAGE_ID=$(kubectl hlf chaincode calculatepackageid --path=chaincode.tgz --language=node --label=$CHAINCODE_LABEL)
echo "PACKAGE_ID=$PACKAGE_ID"
```

```
kubectl hlf chaincode install --path=./chaincode.tgz \
    --config=network.yaml --language=golang --label=$CHAINCODE_LABEL --user=admin --peer=org1-peer0.default





kubectl hlf chaincode install --path=./chaincode.tgz \
    --config=network.yaml --language=golang --label=$CHAINCODE_LABEL --user=admin --peer=org2-peer0.default




kubectl hlf chaincode install --path=./chaincode.tgz \
    --config=network.yaml --language=golang --label=$CHAINCODE_LABEL --user=admin --peer=org3-peer0.default




kubectl hlf chaincode install --path=./chaincode.tgz \
    --config=network.yaml --language=golang --label=$CHAINCODE_LABEL --user=admin --peer=org4-peer0.default


```

```
kubectl hlf externalchaincode sync --image=docker-hesap-adi/image:latest \
    --name=$CHAINCODE_NAME \
    --namespace=default \
    --package-id=$PACKAGE_ID \
    --tls-required=false \
    --replicas=1



kubectl hlf chaincode queryinstalled --config=network.yaml --user=admin --peer=org1-peer0.default

kubectl hlf chaincode queryinstalled --config=network.yaml --user=admin --peer=org2-peer0.default

kubectl hlf chaincode queryinstalled --config=network.yaml --user=admin --peer=org3-peer0.default

kubectl hlf chaincode queryinstalled --config=network.yaml --user=admin --peer=org4-peer0.default
```

#Adım 13: Chaincode Onayı

Her organizasyon için chaincode'u onaylayın:

```
export SEQUENCE=1
export VERSION="1.0"
kubectl hlf chaincode approveformyorg --config=network.yaml --user=admin --peer=org1-peer0.default \
    --package-id=$PACKAGE_ID \
    --version "$VERSION" --sequence "$SEQUENCE" --name=test \
    --policy="OR('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member', 'Org4MSP.member')" --channel=demo

kubectl hlf chaincode approveformyorg --config=network.yaml --user=admin --peer=org2-peer0.default \
    --package-id=$PACKAGE_ID \
    --version "$VERSION" --sequence "$SEQUENCE" --name=test \
    --policy="OR('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member', 'Org4MSP.member')" --channel=demo

kubectl hlf chaincode approveformyorg --config=network.yaml --user=admin --peer=org3-peer0.default \
    --package-id=$PACKAGE_ID \
    --version "$VERSION" --sequence "$SEQUENCE" --name=test \
    --policy="OR('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member', 'Org4MSP.member')" --channel=demo

kubectl hlf chaincode approveformyorg --config=network.yaml --user=admin --peer=org4-peer0.default \
    --package-id=$PACKAGE_ID \
    --version "$VERSION" --sequence "$SEQUENCE" --name=test \
    --policy="OR('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member', 'Org4MSP.member')" --channel=demo
```

#Adım 14: Chaincode Commit İşlemi

Chaincode, ağdaki her organizasyon tarafından onaylanıyor ve ardından ana kanala commit ediliyor. Bu, chaincode'un ağ üzerinde aktif hale gelmesini sağlar.

```
kubectl hlf chaincode commit --config=network.yaml --user=admin --mspid=Org1MSP \
    --version "$VERSION" --sequence "$SEQUENCE" --name=test \
    --policy="OR('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member', 'Org4MSP.member')" --channel=demo
```