Para entender un smart contract, primero hemos de recordar qué significa un contrato. Un contrato no es más que un acuerdo entre dos o más partes, un entorno donde se define lo que se puede hacer, cómo se puede hacer, qué pasa si algo no se hace. Es decir, unas reglas de juego que permiten a todas las partes que lo aceptan entender en qué va a consistir la interacción que van a realizar.
Un contrato inteligente es capaz de ejecutarse y hacerse cumplir por sí mismo, de manera autónoma y automática, sin intermediarios ni mediadores. Los smart contracts se tratan de “scripts” (códigos informáticos) escritos con lenguajes de programación. Esto quiere decir que los términos del contrato son puras sentencias y comandos en el código que lo forma.
Dentro del ecosistema Hyperledger los contratos inteligentes se denominan chaincode.
Para efectos de la demostración, se requiere tener una red blockchain desplegada, por lo que nos basaremos en lo explicado en el post Hyperledger Fabric y docker swarm en multiples hosts y el chaincode del siguiente repositorio desarrollado en Go.
Ingresamos al contenedor cli, y ejecutamos los siguientes comandos.
docker exec -ti cli_cli.1.$(docker service ps -f 'name=cli_cli.1' cli_cli -q --no-trunc | head -n1) /bin/bash
Creamos el canal, al cual pertenecerán nuestras organizaciones
export CHANNEL_NAME=marketplace
peer channel create -o orderer.midominio.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/midominio.com/orderers/orderer.midominio.com/msp/tlscacerts/tlsca.midominio.com-cert.pem
Unimos nuestros nodos al canal que se acaba de crear.
peer channel join -b marketplace.block
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.midominio.com/users/Admin@org1.midominio.com/msp CORE_PEER_ADDRESS=peer1.org1.midominio.com:7051 CORE_PEER_LOCALMSPID="Org1MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.midominio.com/peers/peer1.org1.midominio.com/tls/ca.crt peer channel join -b marketplace.block
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/users/Admin@org2.midominio.com/msp CORE_PEER_ADDRESS=peer0.org2.midominio.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/peers/peer0.org2.midominio.com/tls/ca.crt peer channel join -b marketplace.block
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/users/Admin@org2.midominio.com/msp CORE_PEER_ADDRESS=peer1.org2.midominio.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/peers/peer1.org2.midominio.com/tls/ca.crt peer channel join -b marketplace.block
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/users/Admin@org3.midominio.com/msp CORE_PEER_ADDRESS=peer0.org3.midominio.com:7051 CORE_PEER_LOCALMSPID="Org3MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/peers/peer0.org3.midominio.com/tls/ca.crt peer channel join -b marketplace.block
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/users/Admin@org3.midominio.com/msp CORE_PEER_ADDRESS=peer1.org3.midominio.com:7051 CORE_PEER_LOCALMSPID="Org3MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/peers/peer1.org3.midominio.com/tls/ca.crt peer channel join -b marketplace.block
Actualizamos los anchor peer.
peer channel update -o orderer.midominio.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/midominio.com/orderers/orderer.midominio.com/msp/tlscacerts/tlsca.midominio.com-cert.pem
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/users/Admin@org2.midominio.com/msp CORE_PEER_ADDRESS=peer0.org2.midominio.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/peers/peer0.org2.midominio.com/tls/ca.crt peer channel update -o orderer.midominio.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/midominio.com/orderers/orderer.midominio.com/msp/tlscacerts/tlsca.midominio.com-cert.pem
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/users/Admin@org3.midominio.com/msp CORE_PEER_ADDRESS=peer0.org3.midominio.com:7051 CORE_PEER_LOCALMSPID="Org3MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/peers/peer0.org3.midominio.com/tls/ca.crt peer channel update -o orderer.midominio.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org3MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/midominio.com/orderers/orderer.midominio.com/msp/tlscacerts/tlsca.midominio.com-cert.pem
Instalación e Instanciamiento de chaincode
Seteamos las siguientes variables.
export CHANNEL_NAME=marketplace
export CHAINCODE_NAME=marbles02
export CHAINCODE_SRC=github.com/chaincode/marbles02
export CHAINCODE_VERSION=0
export COMPOSE_PROJECT_NAME=marble02project
export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/midominio.com/orderers/orderer.midominio.com/msp/tlscacerts/tlsca.midominio.com-cert.pem
Instalamos el chaincode sobre los nodos de la red blockchain
peer chaincode install -n $CHAINCODE_NAME -p $CHAINCODE_SRC -v $CHAINCODE_VERSION
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.midominio.com/users/Admin@org1.midominio.com/msp CORE_PEER_ADDRESS=peer1.org1.midominio.com:7051 CORE_PEER_LOCALMSPID="Org1MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.midominio.com/peers/peer1.org1.midominio.com/tls/ca.crt peer chaincode install -n $CHAINCODE_NAME -p $CHAINCODE_SRC -v $CHAINCODE_VERSION
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/users/Admin@org2.midominio.com/msp CORE_PEER_ADDRESS=peer0.org2.midominio.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/peers/peer0.org2.midominio.com/tls/ca.crt peer chaincode install -n $CHAINCODE_NAME -p $CHAINCODE_SRC -v $CHAINCODE_VERSION
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/users/Admin@org2.midominio.com/msp CORE_PEER_ADDRESS=peer1.org2.midominio.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.midominio.com/peers/peer1.org2.midominio.com/tls/ca.crt peer chaincode install -n $CHAINCODE_NAME -p $CHAINCODE_SRC -v $CHAINCODE_VERSION
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/users/Admin@org3.midominio.com/msp CORE_PEER_ADDRESS=peer0.org3.midominio.com:7051 CORE_PEER_LOCALMSPID="Org3MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/peers/peer0.org3.midominio.com/tls/ca.crt peer chaincode install -n $CHAINCODE_NAME -p $CHAINCODE_SRC -v $CHAINCODE_VERSION
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/users/Admin@org3.midominio.com/msp CORE_PEER_ADDRESS=peer1.org3.midominio.com:7051 CORE_PEER_LOCALMSPID="Org3MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.midominio.com/peers/peer1.org3.midominio.com/tls/ca.crt peer chaincode install -n $CHAINCODE_NAME -p $CHAINCODE_SRC -v $CHAINCODE_VERSION
Instanciamos el chaincode
peer chaincode instantiate -o orderer.midominio.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n $CHAINCODE_NAME -v $CHAINCODE_VERSION -c '{"Args":["a","10"]}' -P "OR ('Org1MSP.member','Org2MSP.member','Org3MSP.member')"
Podemos hacer uso de CouchDB para ver el estado actual de las transacciones sobre la red blockchain.
Una ves instanciado el smart contract, procedemos a validar sus funcionalidades de acuerdo a los metodos desarrollados.
Teniendo el chaincode desplegados, se podría hacer uso de Fabric SDK para implementar un cliente API REST para el consumo de tereceros.
peer chaincode invoke -o orderer.midominio.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n $CHAINCODE_NAME -c '{"Args":["initMarble","marble1","azul","20","Jorge"]}'
peer chaincode invoke -o orderer.midominio.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n $CHAINCODE_NAME -c '{"Args":["transferMarble","marble1","Luis"]}'
peer chaincode invoke -o orderer.midominio.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n $CHAINCODE_NAME -c '{"Args":["transferMarble","marble1","Daniel"]}'
peer chaincode invoke -o orderer.midominio.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n $CHAINCODE_NAME -c '{"Args":["delete","marble1"]}'
peer chaincode query -o orderer.midominio.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n $CHAINCODE_NAME -c '{"Args":["getHistoryForMarble","marble1"]}'
Vista histórica de transacciones de un activo.
Referencia: https://github.com/hyperledger/fabric
Muy buena información