Depurar contrato inteligente no modo de desenvolvedor de desenvolvimento

Um, use nodejs para escrever contratos inteligentes

Etapa 1: Crie uma nova pasta fishcc no diretório chaincode e inicie o nome você mesmo;
Etapa 2: Entre na pasta fishcc e execute o npm initcomando;
Etapa 3: Instale o fabric-shim;

npm install --save fabric-shim

Etapa 4: Crie um novo arquivo app.js e especifique você mesmo o nome do arquivo.
Etapa 5: redija o contrato de acordo com o modelo a seguir.

const shim = require('fabric-shim');
const util = require('util');

let Chaincode = class {
    
    
	
  async Init(stub) {
    
    
    console.info('execute Init method...');
    return shim.success('');
  }
  
  async Invoke(stub) {
    
    
    let ret = stub.getFunctionAndParameters();
    let method = this[ret.fcn];
    if (!method) {
    
    
      let errMsg = ret.fcn + ' method does not exist';
      throw new Error(errMsg);
    }
    try {
    
    
      let payload = await method(stub, ret.params);
      return shim.success(payload);
    } catch (err) {
    
    
      console.log(err);
      return shim.error(err);
    }
  }
  
  async xxx(stub, args) {
    
    
    console.info('调用智能合约方法,xxx方法名根据实际自己指定');
  }
  
}
  
shim.start(new Chaincode());

O código completo do contrato é o seguinte:

const shim = require('fabric-shim');
const util = require('util');

let Chaincode = class {
    
    
	
  async Init(stub) {
    
    
    return shim.success('');
  }
  
  async Invoke(stub) {
    
    
    let ret = stub.getFunctionAndParameters();
    let method = this[ret.fcn];
    if (!method) {
    
    
      throw new Error(ret.fcn + ' method does not exist.');
    }
    try {
    
    
      let payload = await method(stub, ret.params);
      return shim.success(payload);
    } catch (err) {
    
    
      console.log(err);
      return shim.error(err);
    }
  }
  
  async initLedger(stub, args) {
    
    
    let fishes = [];
    fishes.push({
    
    
       vessel: "Fish001", 
       location: "67.0006, -70.5476", 
       timestamp: "1504054225",
       holder: "zhang"
    });
    fishes.push({
    
    
       vessel: "Fish002", 
       location: "57.9006, -78.3478", 
       timestamp: "1504054666",
       holder: "li"
    });
    fishes.push({
    
    
       vessel: "Fish003", 
       location: "77.9034, -75.3455", 
       timestamp: "1504054888",
       holder: "wang"
    });
    
    for (let i = 0; i < fishes.length; i++) {
    
    
      await stub.putState('FISH' + i, Buffer.from(JSON.stringify(fishes[i])));
      console.info('Added <--> ',fishes[i]);
    }
  }
  
  async queryFish(stub, args) {
    
    
    if (args.length != 1) {
    
    
      throw new Error('args length is not equals 1.');
    }
    let fishNumber = args[0];
    let fishAsBytes = await stub.getState(fishNumber);
    if (!fishAsBytes || fishAsBytes.toString().length <= 0) {
    
    
      throw new Error('no data found.');
    }
    console.log(fishAsBytes.toString());
    return fishAsBytes;
  }
  
  async recordFish(stub, args) {
    
    
    if (args.length != 5) {
    
    
	  throw new Error('Args length is not equals 5.');
    }

    var fish = {
    
    
      vessel: args[1],
      location: args[2],
      timestamp: args[3],
      holder: args[4]
    };

    await stub.putState(args[0], Buffer.from(JSON.stringify(fish)));
  }
  
  async queryAllFish(stub, args) {
    
    
    let startKey = 'FISH0';
    let endKey = 'FISH999';

    let iterator = await stub.getStateByRange(startKey, endKey);

    let allResults = [];
    while (true) {
    
    
      let res = await iterator.next();

      if (res.value && res.value.value.toString()) {
    
    
        let jsonRes = {
    
    };
        console.log(res.value.value.toString('utf8'));

        jsonRes.Key = res.value.key;
        try {
    
    
          jsonRes.Record = JSON.parse(res.value.value.toString('utf8'));
        } catch (err) {
    
    
          console.log(err);
          jsonRes.Record = res.value.value.toString('utf8');
        }
        allResults.push(jsonRes);
      }
      if (res.done) {
    
    
        console.log('end of data');
        await iterator.close();
        console.info(allResults);
        return Buffer.from(JSON.stringify(allResults));
      }
    }
  }
  
  async changeFishHolder(stub, args) {
    
    
    if (args.length != 2) {
    
    
      throw new Error('Args length is not equals 2.');
    }
    let fishAsBytes = await stub.getState(args[0]);
    let fish = JSON.parse(fishAsBytes);
    fish.holder = args[1];
    await stub.putState(args[0], Buffer.from(JSON.stringify(fish)));
  }
}
  
shim.start(new Chaincode());

Etapa 6: Modifique o arquivo package.json e adicione o comando start nos scripts;

"scripts": {
    
    
  "start": "node app.js"
},

Até agora, o contrato inteligente está escrito.

2. Depurar contratos inteligentes no modo de desenvolvedor de desenvolvimento

Os contratos inteligentes do Hyperledge Fabric são iniciados e mantidos por cada nó. No entanto, após usar o modo de desenvolvedor, a compilação e a inicialização do contrato inteligente são deixadas para o usuário. Na fase de desenvolvimento de contratos inteligentes, é muito útil usar o modo de desenvolvedor para escrever, compilar e executar contratos inteligentes.

Iniciar o modo de desenvolvedor é muito simples, desligamos a função tls de todos os nós.

- CORE_PEER_TLS_ENABLED=false

Modifique o comando command do nó peer e inclua o parâmetro -peer-chaincodedev = true após o comando peer node start.

command: peer node start --peer-chaincodedev=true	

Configure a porta 7052 para todos os nós de mesmo nível. Comunicação GRPC entre nós de usuário na porta 7052.
Insira a descrição da imagem aqui
Por fim, seguimos as etapas abaixo para testar.

A primeira etapa: iniciar todos os nós;

docker-compose up -d

Etapa 2: Depois que a inicialização for concluída, vá para o diretório de scripts do contêiner de nó de mesmo nível e execute o script start.sh.

#!/bin/bash
rm -f ../channel-artifacts/mychannel.block
printf "start create channel...\n"
peer channel create -o orderer.example.com:7050 -c mychannel -f ../channel-artifacts/channel.tx
printf "end create channel...\n"
mv mychannel.block ../channel-artifacts
printf "peer0.org1.example.com start join channel...\n"
peer channel join -b ../channel-artifacts/mychannel.block
printf "peer0.org1.example.com end join channel...\n"
printf "peer0.org1.example.com start install chaincode...\n"
peer chaincode install -n fishcc -v 1.0 -l node -p /opt/gopath/src/github.com/chaincode/fishcc
printf "peer0.org1.example.com end install chaincode...\n"
printf "start packaging chaincode...\n"
peer chaincode package -n fishcc -p /opt/gopath/src/github.com/chaincode/fishcc -v 1.0 fishcc.1.0.out -l node
printf "end packaging chaincode"
mv fishcc.1.0.out ../channel-artifacts
export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.key
printf "peer1.org1.example.com start join channel...\n"
peer channel join -b ../channel-artifacts/mychannel.block
printf "peer1.org1.example.com end join channel...\n"
printf "peer1.org1.example.com start install chaincode...\n"
peer chaincode install ../channel-artifacts/fishcc.1.0.out
printf "peer1.org1.example.com end install chaincode...\n"
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key
printf "peer0.org2.example.com start join channel...\n"
peer channel join -b ../channel-artifacts/mychannel.block
printf "peer0.org2.example.com end join channel...\n"
printf "peer0.org2.example.com start install chaincode...\n"
peer chaincode install ../channel-artifacts/fishcc.1.0.out
printf "peer0.org2.example.com end install chaincode...\n"
export CORE_PEER_ADDRESS=peer1.org2.example.com:7051
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/server.key
printf "peer1.org2.example.com start join channel...\n"
peer channel join -b ../channel-artifacts/mychannel.block
printf "peer1.org2.example.com end join channel...\n"
printf "peer1.org2.example.com start install chaincode...\n"
peer chaincode install ../channel-artifacts/fishcc.1.0.out
printf "peer1.org2.example.com end install chaincode...\n"

O script de shell acima executa tarefas como criar canais, adicionar canais e criar códigos em cadeia.

Etapa 3: Abra outra janela de shell, entre no diretório chaincode / fishcc e execute a execução.A npm start --peer.address grpc://localhost:7052 --chaincode-id-name fishcc:1.0interface após a execução bem-sucedida é a seguinte:
Insira a descrição da imagem aqui
Etapa 4: Instancie o contrato.

peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n fishcc -l node -v 1.0 -c '{"Args":[""]}' -P "AND('Org1MSP.member')"

Depois de executar a instanciação, você pode ver a janela do contrato em execução da seguinte forma:
Insira a descrição da imagem aqui
Podemos ver as informações do resultado do contrato instanciado na janela do contrato.

Etapa 5: teste.

# 初始化
peer chaincode invoke -C mychannel -n fishcc -c '{"Args":["initLedger"]}' -o orderer.example.com:7050

# 查询
peer chaincode invoke -C mychannel -n fishcc -c '{"Args":["queryFish","FISH0"]}'

Três, configure o couchDB

O Hyperledge Fabric oferece suporte a dois modos de banco de dados de estado:

  • levelDB: armazenamento de arquivos, não é fácil de visualizar e gerenciar
  • couchDB: banco de dados de contêiner independente, fornecendo funções de consulta ricas

3.1 Configurar o couchDB

A primeira etapa: baixar a imagem hyperledger / fabric-couchdb, a
Insira a descrição da imagem aqui
segunda etapa: configurar o serviço couchDB no arquivo de configuração docker-compose;

couchdb:
    container_name: couchdb
    image: hyperledger/fabric-couchdb
    environment:
      - COUCHDB_USER=admin
      - COUCHDB_PASSWORD=123456
    ports:
      - 5984:5984
    networks:
      - byfn

O COUCHDB_USER e COUCHDB_PASSWORD acima especificam respectivamente o nome de login e a senha de login da plataforma de gerenciamento do couchDB.

Etapa 3: Adicionar as informações de configuração do couchDB na configuração do ambiente do nó do par;

- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=123456

Etapa 4: Especifique a sequência de inicialização dos nós de mesmo nível;

depends_on:
  - orderer.example.com
  - couchdb

3.2 Simples e prático de couchDB

A primeira etapa: iniciar o contêiner do docker; a
Insira a descrição da imagem aqui
segunda etapa: http://localhost:5984/_utilsentrar no console no navegador ; a
Insira a descrição da imagem aqui
terceira etapa: inserir o nome de usuário e a senha. Depois que o login for bem-sucedido, se o contrato inteligente tiver sido inicializado, você pode ver o contrato implementado no lado direito da coluna Bancos de dados.
Insira a descrição da imagem aqui
O mychannel_fishcc acima é o contrato que implantamos. Depois de clicar em, você pode ver que existem três dados, a saber, FISH0, FISH1 e FISH2.
Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/zhongliwen1981/article/details/104994059
Recomendado
Clasificación