Tutorial Hyperledger Fabric SDK Go: How to build your first app?
This tutorial will introduce you to the Hyperledger Fabric Go SDK and allows you to build a simple application using the blockchain principle.
This tutorial uses Hyperledger Fabric version 1.0.5, on github Heroes-Service use the branch 1.0.5!
Edit: The new version of this tutorial is finished and available here: chainhero.io/2018/06/tutorial-build-blockchain-app-v1-1-0
This is the first part of this tutorial. The basics SDK features will be shown, but the second part is scheduled to demonstrate a more complex application.
1. Prerequisites
This tutorial won’t explain in detail how Hyperledger Fabric works. I will just give some tips to understand the general behavior of the framework. If you want to get a full explanation of the tool, go to the official documentation there is a lot of work there that explains what kind of blockchain Hyperledger Fabric is.
This tutorial has been made on Ubuntu 16.04 but the Hyperledger Fabric framework is compatible with Mac OS X, Windows and other Linux distributions.
We will use the Go language to design our first application because the Hyperledger Fabric has been also built in Go and the Fabric SDK Go is really simple to use. In addition, the chaincode (smart contract) can be written in Go too. So the full-stack will be only in Go! Awesome right ? However, if you are go phobic, there are other SDK like for NodeJS, Java or Python but we won’t discuss about them here.
Hyperledger Fabric uses Docker to easily deploy a blockchain network. In addition, some components (peers) also deploys docker containers to separate data (channel). So make sure that your platform supports this kind of virtualization.
2. Introduction to Hyperledger Fabric
Hyperledger Fabric is a platform for distributed ledger solutions underpinned by a modular architecture delivering high degrees of confidentiality, resiliency, flexibility and scalability. It is designed to support pluggable implementations of different components and accommodate the complexity and intricacies that exist across the economic ecosystem.
See the full explaination from the official documentation, in the introduction part: Hyperledger Fabric Blockchain
3. Installation guide
This tutorial was made on Ubuntu 16.04, but there is help for Windows, Mac OS X and other Linux distributions users.
a. Docker
Docker version 17.03.0-ce or greater is required.
Linux (Ubuntu)
First of all, in order to install docker correctly we need to install its dependencies:
sudo apt install apt-transport-https ca-certificates curl software-properties-common
Once the dependencies are installed, we can install docker:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
sudo apt update && \
sudo apt install -y docker-ce
Now we need to manage the current user to avoid using administration rights (root
) access when we will use the docker command. To do so, we need to add the current user to the docker
group:
sudo groupadd docker ; \
sudo gpasswd -a ${USER} docker && \
sudo service docker restart
Do not mind if groupadd: group 'docker' already exists
error pop up.
To apply the changes made, you need to logout/login. You can then check your version with:
docker -v
Mac OS X
Download and install the latest Docker.dmg
package for Mac OS X available on the Docker website. This will install docker-compose
as well, so you can skip the next step.
Linux (not Ubuntu)
See links below:
Windows
See instructions from the Docker website: docker.com/docker-for-windows
b. Docker Compose
Docker-compose version 1.8 or greater is required.
We are currently unable to manage easily multiple containers at once. To solve this issue, we need docker-compose.
Linux
The installation is pretty fast:
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose
Apply these changes by logout/login and then check its version with:
docker-compose version
Windows / Others
See instructions from the Docker-compose website: docs.docker.com/compose/install
c. Go
Go version 1.9.x or greater is required.
Linux
You can either follow instructions from golang.org or use these generics commands that will install Golang 1.9.2 and prepare your environment (generate your GOPATH
) for Ubuntu:
wget https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz && \
sudo tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz && \
rm go1.9.2.linux-amd64.tar.gz && \
echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee -a /etc/profile && \
echo 'export GOPATH=$HOME/go' | tee -a $HOME/.bashrc && \
echo 'export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' | tee -a $HOME/.bashrc && \
mkdir -p $HOME/go/{src,pkg,bin}
To make sure that the installation works, you can logout/login (again) and run:
go version
Windows / Mac OS X / Others
See instructions from the Golang website: golang.org/install
c. Fabric SDK Go
Last but not least, the Hyperledger Fabric SDK Go will allow us to easily communicate with the Fabric’s components. You don’t need to install the Fabric or Fabric CA framework because the SDK automatically handles it locally. To avoid version issues, we are going to checkout to a specific commit which works with the following tutorial.
go get -u github.com/hyperledger/fabric-sdk-go && \
cd $GOPATH/src/github.com/hyperledger/fabric-sdk-go && \
git checkout 614551a752802488988921a730b172dada7def1d
Let’s make sure that you have the requested dependencies:
cd $GOPATH/src/github.com/hyperledger/fabric-sdk-go && \
make depend-install
Finally, we can launch the various tests of the SDK to check its proper functioning before going further:
cd $GOPATH/src/github.com/hyperledger/fabric-sdk-go ; \
make
If you get the following error:
../fabric-sdk-go/vendor/github.com/miekg/pkcs11/pkcs11.go:29:18: fatal error: ltdl.h: No such file or directory
You need to install the package libltdl-dev
and re-execute previous command (make
):
sudo apt install libltdl-dev
The process take a while (depending on your network connection). During this process, a virtual network has been built and some tests have been made in order to check if your system is ready. Now we can work with our first application.
Note: there is more output but it’s irrelevant to put it here. The only things you need to care about is the line
fabsdkgo_integration-tests_1 exited with code 0
. If you havefabsdkgo_integration-tests_1 exited with code 1
then you have a problem. Scroll up in the messages above to find the error.
4. Make your first blockchain network
a. Prepare environment
In order to make a blockchain network, we will use docker
to build virtual computers that will handle different roles. In this tutorial we will stay as simple as possible. Hyperledger Fabric needs a lot of certificates to ensure encryption during the whole end to end process (TSL, authentications, signing blocks…). The creation of these files requires a little time and in order to go straight to the heart of the matter, we have already prepared all this for you in the folder fixtures
in this repository.
Make a new directory in the src
folder of your GOPATH
, following our repository naming:
mkdir -p $GOPATH/src/github.com/chainHero/heroes-service && \
cd $GOPATH/src/github.com/chainHero/heroes-service
To get the fixtures
folder, you can either follow this command line, which will install and use subversion to get the folder from this repository. Or download the zip file from Github and extract only the fixtures
folder.
sudo apt install -y subversion && \
cd $GOPATH/src/github.com/chainHero/heroes-service && \
svn checkout https://github.com/chainHero/heroes-service/branches/v1.0.5/fixtures &&
rm -rf fixtures/.svn
Alternatively, if you want to know how to build this fixture folder and learn how to create the blockchain network, follow this quick tutorial on how to build your first network.
b. Test
In order to check if the network works, we will use docker-compose
to start or stop all containers at the same time. Go inside the fixtures
folder, and run:
cd $GOPATH/src/github.com/chainHero/heroes-service/fixtures && \
docker-compose up
You will see a lot of logs with different colors (for your information, red isn’t equal to errors).
Open a new terminal and run:
docker ps
You will see : two peers, the orderer and one CA containers. You have successfully made a new network ready to use with the SDK. To stop the network go back to the previous terminal, press Ctrl+C
and wait that all containers are stopped. If you want to explore more deeper, follow our tutorial dedicated to the network part here or check out the official documentation about this: Building Your First Network
Tips: when the network is stopped, all containers used remain accessible. This is very useful to check logs for example. You can see them with
docker ps -a
. In order to clean up these containers, you need to delete them withdocker rm $(docker ps -aq)
or if you have used adocker-compose
file, go where this file is and rundocker-compose down
.
Tips: you can run the
docker-compose
command in background to keep the prompt. To do so, use the parameter-d
, like this:docker-compose up -d
. To stop containers, run in the same folder where thedocker-compose.yaml
is, the command:docker-compose stop
(ordocker-compose down
to clean up after all containers are stopped).
5. Use the Fabric SDK Go
a. Configuration
Our application needs a lot of parameters, especially the addresses of the Fabric’s components to communicate. We will put everything in a new configuration file, the Fabric SDK Go configuration and our custom parameters. For the moment, we will only try to make the Fabric SDK Go works with the default chaincode:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi config.yaml
name: "chainHero-network"
# Describe what the target network is/does.
description: "The network which will host my first blockchain"
# Schema version of the content. Used by the SDK to apply the corresponding parsing rules.
version: 1.0.0
# The client section used by GO SDK.
client:
# Which organization does this application instance belong to? The value must be the name of an org
organization: Org1
logging:
level: info
# Global configuration for peer, event service and orderer timeouts
peer:
timeout:
connection: 3s
queryResponse: 45s
executeTxResponse: 30s
eventService:
timeout:
connection: 3s
registrationResponse: 3s
orderer:
timeout:
connection: 3s
response: 5s
# Root of the MSP directories with keys and certs. The Membership Service Providers is component that aims to offer an abstraction of a membership operation architecture.
cryptoconfig:
path: "${GOPATH}/src/github.com/chainHero/heroes-service/fixtures/crypto-config"
# Some SDKs support pluggable KV stores, the properties under "credentialStore" are implementation specific
credentialStore:
path: "/tmp/heroes-service-kvs"
# [Optional]. Specific to the CryptoSuite implementation used by GO SDK. Software-based implementations requiring a key store. PKCS#11 based implementations does not.
cryptoStore:
path: "/tmp/heroes-service-msp"
# BCCSP config for the client. Used by GO SDK. It's the Blockchain Cryptographic Service Provider.
# It offers the implementation of cryptographic standards and algorithms.
BCCSP:
security:
enabled: true
default:
provider: "SW"
hashAlgorithm: "SHA2"
softVerify: true
ephemeral: false
level: 256
tlsCerts:
systemCertPool: false
# [Optional]. But most apps would have this section so that channel objects can be constructed based on the content below.
# If one of your application is creating channels, you might not use this
channels:
chainhero:
orderers:
- orderer.hf.chainhero.io
# Network entity which maintains a ledger and runs chaincode containers in order to perform operations to the ledger. Peers are owned and maintained by members.
peers:
peer0.org1.hf.chainhero.io:
# [Optional]. will this peer be sent transaction proposals for endorsement? The peer must
# have the chaincode installed. The app can also use this property to decide which peers
# to send the chaincode install request. Default: true
endorsingPeer: true
# [Optional]. will this peer be sent query proposals? The peer must have the chaincode
# installed. The app can also use this property to decide which peers to send the
# chaincode install request. Default: true
chaincodeQuery: true
# [Optional]. will this peer be sent query proposals that do not require chaincodes, like
# queryBlock(), queryTransaction(), etc. Default: true
ledgerQuery: true
# [Optional]. will this peer be the target of the SDK's listener registration? All peers can
# produce events but the app typically only needs to connect to one to listen to events.
# Default: true
eventSource: true
peer1.org1.hf.chainhero.io:
# List of participating organizations in this network
organizations:
Org1:
mspid: org1.hf.chainhero.io
cryptoPath: "peerOrganizations/org1.hf.chainhero.io/users/{userName}@org1.hf.chainhero.io/msp"
peers:
- peer0.org1.hf.chainhero.io
- peer1.org1.hf.chainhero.io
certificateAuthorities:
- ca.org1.hf.chainhero.io
# List of orderers to send transaction and channel create/update requests to.
# The orderers consent on the order of transactions in a block to be committed to the ledger. For the time being only one orderer is needed.
orderers:
orderer.hf.chainhero.io:
url: grpcs://localhost:7050
grpcOptions:
ssl-target-name-override: orderer.hf.chainhero.io
grpc-max-send-message-length: 15
tlsCACerts:
path: "${GOPATH}/src/github.com/chainHero/heroes-service/fixtures/crypto-config/ordererOrganizations/hf.chainhero.io/tlsca/tlsca.hf.chainhero.io-cert.pem"
# List of peers to send various requests to, including endorsement, query and event listener registration.
peers:
peer0.org1.hf.chainhero.io:
# this URL is used to send endorsement and query requests
url: grpcs://localhost:7051
# this URL is used to connect the EventHub and registering event listeners
eventUrl: grpcs://localhost:7053
# These parameters should be set in coordination with the keepalive policy on the server
grpcOptions:
ssl-target-name-override: peer0.org1.hf.chainhero.io
grpc.http2.keepalive_time: 15
tlsCACerts:
path: "${GOPATH}/src/github.com/chainHero/heroes-service/fixtures/crypto-config/peerOrganizations/org1.hf.chainhero.io/tlsca/tlsca.org1.hf.chainhero.io-cert.pem"
peer1.org1.hf.chainhero.io:
url: grpcs://localhost:8051
eventUrl: grpcs://localhost:8053
grpcOptions:
ssl-target-name-override: peer1.org1.hf.chainhero.io
grpc.http2.keepalive_time: 15
tlsCACerts:
# Certificate location absolute path
path: "${GOPATH}/src/github.com/chainHero/heroes-service/fixtures/crypto-config/peerOrganizations/org1.hf.chainhero.io/tlsca/tlsca.org1.hf.chainhero.io-cert.pem"
# Fabric-CA is a special kind of Certificate Authority provided by Hyperledger Fabric which allows certificate management to be done via REST APIs.
certificateAuthorities:
ca.org1.hf.chainhero.io:
url: https://localhost:7054
# the properties specified under this object are passed to the 'http' client verbatim when making the request to the Fabric-CA server
httpOptions:
verify: false
registrar:
enrollId: admin
enrollSecret: adminpw
caName: ca.org1.hf.chainhero.io
The configuration file is also available here: config.yaml
b. Initialise
We add a new folder named blockchain
that will contain the whole interface that communicate with the network. We will see the Fabric SDK Go only in this folder.
mkdir $GOPATH/src/github.com/chainHero/heroes-service/blockchain
Now, we add a new go file named setup.go
:
vi $GOPATH/src/github.com/chainHero/heroes-service/blockchain/setup.go
package blockchain
import (
"fmt"
chmgmt "github.com/hyperledger/fabric-sdk-go/api/apitxn/chmgmtclient"
resmgmt "github.com/hyperledger/fabric-sdk-go/api/apitxn/resmgmtclient"
"github.com/hyperledger/fabric-sdk-go/pkg/config"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
"time"
)
// FabricSetup implementation
type FabricSetup struct {
ConfigFile string
ChannelID string
initialized bool
ChannelConfig string
OrgAdmin string
OrgName string
admin resmgmt.ResourceMgmtClient
sdk *fabsdk.FabricSDK
}
// Initialize reads the configuration file and sets up the client, chain and event hub
func (setup *FabricSetup) Initialize() error {
// Add parameters for the initialization
if setup.initialized {
return fmt.Errorf("sdk already initialized")
}
// Initialize the SDK with the configuration file
sdk, err := fabsdk.New(config.FromFile(setup.ConfigFile))
if err != nil {
return fmt.Errorf("failed to create sdk: %v", err)
}
setup.sdk = sdk
// Channel management client is responsible for managing channels (create/update channel)
// Supply user that has privileges to create channel (in this case orderer admin)
chMgmtClient, err := setup.sdk.NewClient(fabsdk.WithUser(setup.OrgAdmin), fabsdk.WithOrg(setup.OrgName)).ChannelMgmt()
if err != nil {
return fmt.Errorf("failed to add Admin user to sdk: %v", err)
}
// Org admin user is signing user for creating channel.
// The session method is the only way for now to get the user identity.
session, err := setup.sdk.NewClient(fabsdk.WithUser(setup.OrgAdmin), fabsdk.WithOrg(setup.OrgName)).Session()
if err != nil {
return fmt.Errorf("failed to get session for %s, %s: %s", setup.OrgName, setup.OrgAdmin, err)
}
orgAdminUser := session
// Creation of the channel chainhero. A channel can be understood as a private network inside the main network between two or more specific network Organizations
// The channel is defined by its : Organizations, anchor peer (A peer node that all other peers can discover and communicate with. Every Organizations have one), the shared ledger, chaincode application(s) and the ordering service node(s)
// Each transaction on the network is executed on a channel.
req := chmgmt.SaveChannelRequest{ChannelID: setup.ChannelID, ChannelConfig: setup.ChannelConfig, SigningIdentity: orgAdminUser}
if err = chMgmtClient.SaveChannel(req); err != nil {
return fmt.Errorf("failed to create channel: %v", err)
}
// Allow orderer to process channel creation
time.Sleep(time.Second * 5)
// The resource management client is a client API for managing system resources
// It will allow us to directly interact with the blockchain. It can be associated with the admin status
setup.admin, err = setup.sdk.NewClient(fabsdk.WithUser(setup.OrgAdmin)).ResourceMgmt()
if err != nil {
return fmt.Errorf("failed to create new resource management client: %v", err)
}
// Org peers join channel
if err = setup.admin.JoinChannel(setup.ChannelID); err != nil {
return fmt.Errorf("org peers failed to join the channel: %v", err)
}
fmt.Println("Initialization Successful")
setup.initialized = true
return nil
}
The file is available here: blockchain/setup.go
At this stage, we only initialized a client that will communicate to a peer, a CA and an orderer. We also made a new channel and connected this peer to this channel. See the comments in the code for more information.
c. Test
To make sure that the client managed to initialize all his components, we will make a simple test with the network launched. In order to do this, we need to build the go code. Since we we haven’t any main file we have to add one:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi main.go
package main
import (
"fmt"
"github.com/chainHero/heroes-service/blockchain"
"os"
)
func main() {
// Definition of the Fabric SDK properties
fSetup := blockchain.FabricSetup{
OrgAdmin: "Admin",
OrgName: "Org1",
ConfigFile: "config.yaml",
// Channel parameters
ChannelID: "chainhero",
ChannelConfig: os.Getenv("GOPATH") + "/src/github.com/chainHero/heroes-service/fixtures/artifacts/chainhero.channel.tx",
}
// Initialization of the Fabric SDK from the previously set properties
err := fSetup.Initialize()
if err != nil {
fmt.Printf("Unable to initialize the Fabric SDK: %v\n", err)
}
}
The file is available here: main.go
As you can see, we fixed the GOPATH of the environment if it’s not set. We will need this feature in order to compile the chaincode (we will see this in the next step).
The last thing to do, before starting the compilation, is to use a vendor directory that will contain all our dependencies. In our GOPATH we have Fabric SDK Go and maybe other projects. When we will try to compile our app, Golang search dependencies in our GOPATH, but first it checks if there is a vendor folder in the project. If the dependency is satisfied, then Golang doesn’t go looking in GOPATH or GOROOT. This is very useful when using several different versions of a dependency (some conflicts can happen, like multiple definitions of BCCSP in our case. We will handle this by using a tool like dep
to flatten these dependencies in the vendor
directory.
When you installed the SDK dependencies, DEP was automatically installed. If this is not the case, you can install it by reading the instructions available here: dep installation
Create a file called Gopkg.toml
and copy this inside:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi Gopkg.toml
[[constraint]]
# v1.0.5
name = "github.com/hyperledger/fabric"
revision = "014d6befcf67f3787bb3d67ff34e1a98dc6aec5f"
[[constraint]]
name = "github.com/hyperledger/fabric-sdk-go"
revision = "614551a752802488988921a730b172dada7def1d"
This is a constraint for dep
in order to specify that in our vendor we want the SDK Go to a specific version.
Save the file and then execute this command to synchronize the vendor directory with our project’s dependencies (this may take a while to proceed):
cd $GOPATH/src/github.com/chainHero/heroes-service && \
dep ensure
Now we can compile our application:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
go build
After some time, a new binary named heroes-service
will appear at the root of the project. Try to start the binary like this:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
./heroes-service
At this point, it won’t work because there is no network deployed that the SDK can talk with. We will first start the network and then launch the app again:
cd $GOPATH/src/github.com/chainHero/heroes-service/fixtures && \
docker-compose up -d && \
cd .. && \
./heroes-service
Note: you need to see “Initialization Successful”. If it’s not the case then something went wrong.
Alright! So we just initialised the SDK with our local network. In the next step, we will interact with a chaincode.
d. Clean up and Makefile
The Fabric SDK generates some files, like certificates, binaries and temporally files. Shutting down the network won’t fully clean up your environment and when you will need to start it again, these files will be reused to avoid building process. For development you can keep them to test quickly but for a real test, you need to clean up all and start from the beginning.
How clean up my environment ?
- Shut down your network:
cd $GOPATH/src/github.com/chainHero/heroes-service/fixtures && docker-compose down
- Remove credential stores (defined in the config file, in the
client.credentialStore
section):rm -rf /tmp/heroes-service-*
- Remove some docker containers and docker images not generated by the
docker-compose
command:docker rm -f -v `docker ps -a --no-trunc | grep "heroes-service" | cut -d ' ' -f 1` 2>/dev/null
anddocker rmi `docker images --no-trunc | grep "heroes-service" | cut -d ' ' -f 1` 2>/dev/null
How to be more efficient ?
We can automatize all these tasks in one single step. Also the build and start process can be automated. To do so, we will create a Makefile. First, ensure that you have the tool:
make --version
If make
is not installed do (Ubuntu):
sudo apt install make
Then create a file named Makefile
at the root of the project with this content:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi Makefile
.PHONY: all dev clean build env-up env-down run
all: clean build env-up run
dev: build run
##### BUILD
build:
@echo "Build ..."
@dep ensure
@go build
@echo "Build done"
##### ENV
env-up:
@echo "Start environment ..."
@cd fixtures && docker-compose up --force-recreate -d
@echo "Sleep 15 seconds in order to let the environment setup correctly"
@sleep 15
@echo "Environment up"
env-down:
@echo "Stop environment ..."
@cd fixtures && docker-compose down
@echo "Environment down"
##### RUN
run:
@echo "Start app ..."
@./heroes-service
##### CLEAN
clean: env-down
@echo "Clean up ..."
@rm -rf /tmp/heroes-service-* heroes-service
@docker rm -f -v `docker ps -a --no-trunc | grep "heroes-service" | cut -d ' ' -f 1` 2>/dev/null || true
@docker rmi `docker images --no-trunc | grep "heroes-service" | cut -d ' ' -f 1` 2>/dev/null || true
@echo "Clean up done"
The file is available here: Makefile
Now with the task all
:
- the whole environment will be cleaned up,
- then our go program will be compiled,
- after which the network will be deployed and
- finally the app will be up and running.
To use it, go in the root of the project and use the make
command:
- Task
all
:make
ormake all
- Task
clean
: clean up everything and put down the network (make clean
) - Task
build
: just build the application (make build
) - Task
env-up
: just make the network up (make env-up
) - …
e. Install & instantiate the chaincode
We are almost there to use the blockchain system. But for now we haven’t set up any chaincode (smart contract) yet that will handle queries from our application. First, let’s create a new directory named chaincode
and add a new file named main.go
(this is the main entry point of our smart-contract)::
cd $GOPATH/src/github.com/chainHero/heroes-service && \
mkdir chaincode && \
vi chaincode/main.go
package main
import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
// HeroesServiceChaincode implementation of Chaincode
type HeroesServiceChaincode struct {
}
// Init of the chaincode
// This function is called only one when the chaincode is instantiated.
// So the goal is to prepare the ledger to handle future requests.
func (t *HeroesServiceChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
fmt.Println("########### HeroesServiceChaincode Init ###########")
// Get the function and arguments from the request
function, _ := stub.GetFunctionAndParameters()
// Check if the request is the init function
if function != "init" {
return shim.Error("Unknown function call")
}
// Put in the ledger the key/value hello/world
err := stub.PutState("hello", []byte("world"))
if err != nil {
return shim.Error(err.Error())
}
// Return a successful message
return shim.Success(nil)
}
// Invoke
// All future requests named invoke will arrive here.
func (t *HeroesServiceChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
fmt.Println("########### HeroesServiceChaincode Invoke ###########")
// Get the function and arguments from the request
function, args := stub.GetFunctionAndParameters()
// Check whether it is an invoke request
if function != "invoke" {
return shim.Error("Unknown function call")
}
// Check whether the number of arguments is sufficient
if len(args) < 1 {
return shim.Error("The number of arguments is insufficient.")
}
// In order to manage multiple type of request, we will check the first argument.
// Here we have one possible argument: query (every query request will read in the ledger without modification)
if args[0] == "query" {
return t.query(stub, args)
}
return shim.Error("Unknown action, check the first argument")
}
// query
// Every readonly functions in the ledger will be here
func (t *HeroesServiceChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
fmt.Println("########### HeroesServiceChaincode query ###########")
// Check whether the number of arguments is sufficient
if len(args) < 2 {
return shim.Error("The number of arguments is insufficient.")
}
// Like the Invoke function, we manage multiple type of query requests with the second argument.
// We also have only one possible argument: hello
if args[1] == "hello" {
// Get the state of the value matching the key hello in the ledger
state, err := stub.GetState("hello")
if err != nil {
return shim.Error("Failed to get state of hello")
}
// Return this value in response
return shim.Success(state)
}
// If the arguments given don’t match any function, we return an error
return shim.Error("Unknown query action, check the second argument.")
}
func main() {
// Start the chaincode and make it ready for futures requests
err := shim.Start(new(HeroesServiceChaincode))
if err != nil {
fmt.Printf("Error starting Heroes Service chaincode: %s", err)
}
}
The file is available here: chaincode/main.go
Note: the chaincode isn’t really related to the application, we can have one repository for the app and another for the chaincode. For your information, today the chaincode can also be written in other languages like Java.
For now, the chaincode does nothing extraordinary, just put the key/value hello
/world
in the ledger at initialisation. In addition, there is one function that we can call by an invoke: query hello
. This function gets the state of the ledger, i.e. hello
and give it in response. We will test this in the next step, after successfully install and instantiate the chaincode.
In order to install and instantiate the chaincode, we need to add some code in the application. Edit the blockchain/setup.go
with those following lines:
package blockchain
import (
"fmt"
"github.com/hyperledger/fabric-sdk-go/api/apitxn/chclient"
chmgmt "github.com/hyperledger/fabric-sdk-go/api/apitxn/chmgmtclient"
resmgmt "github.com/hyperledger/fabric-sdk-go/api/apitxn/resmgmtclient"
"github.com/hyperledger/fabric-sdk-go/pkg/config"
packager "github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/ccpackager/gopackager"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl"
"time"
)
// FabricSetup implementation
type FabricSetup struct {
ConfigFile string
OrgID string
ChannelID string
ChainCodeID string
initialized bool
ChannelConfig string
ChaincodeGoPath string
ChaincodePath string
OrgAdmin string
OrgName string
UserName string
client chclient.ChannelClient
admin resmgmt.ResourceMgmtClient
sdk *fabsdk.FabricSDK
}
// Initialize reads the configuration file and sets up the client, chain and event hub
func (setup *FabricSetup) Initialize() error {
[...]
}
func (setup *FabricSetup) InstallAndInstantiateCC() error {
// Create a new go lang chaincode package and initializing it with our chaincode
ccPkg, err := packager.NewCCPackage(setup.ChaincodePath, setup.ChaincodeGoPath)
if err != nil {
return fmt.Errorf("failed to create chaincode package: %v", err)
}
// Install our chaincode on org peers
// The resource management client send the chaincode to all peers in its channel in order for them to store it and interact with it later
installCCReq := resmgmt.InstallCCRequest{Name: setup.ChainCodeID, Path: setup.ChaincodePath, Version: "1.0", Package: ccPkg}
_, err = setup.admin.InstallCC(installCCReq)
if err != nil {
return fmt.Errorf("failed to install cc to org peers %v", err)
}
// Set up chaincode policy
// The chaincode policy is required if your transactions must follow some specific rules
// If you don't provide any policy every transaction will be endorsed, and it's probably not what you want
// In this case, we set the rule to : Endorse the transaction if the transaction have been signed by a member from the org "org1.hf.chainhero.io"
ccPolicy := cauthdsl.SignedByAnyMember([]string{"org1.hf.chainhero.io"})
// Instantiate our chaincode on org peers
// The resource management client tells to all peers in its channel to instantiate the chaincode previously installed
err = setup.admin.InstantiateCC(setup.ChannelID, resmgmt.InstantiateCCRequest{Name: setup.ChainCodeID, Path: setup.ChaincodePath, Version: "1.0", Args: [][]byte{[]byte("init")}, Policy: ccPolicy})
if err != nil {
return fmt.Errorf("failed to instantiate the chaincode: %v", err)
}
// Channel client is used to query and execute transactions
setup.client, err = setup.sdk.NewClient(fabsdk.WithUser(setup.UserName)).Channel(setup.ChannelID)
if err != nil {
return fmt.Errorf("failed to create new channel client: %v", err)
}
fmt.Println("Chaincode Installation & Instantiation Successful")
return nil
}
The file is available here: blockchain/setup.go
Tips: take care of the chaincode version, if you want to update your chaincode, increment the version number set at the line 105 of this
setup.go
file. Otherwise the network will keep the same chaincode.
We need now to modify our main.go file in order to call our new function
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi main.go
[...]
fSetup := blockchain.FabricSetup{
// Channel parameters
ChannelID: "chainhero",
ChannelConfig: os.Getenv("GOPATH") + "/src/github.com/chainHero/heroes-service/fixtures/artifacts/chainhero.channel.tx",
// Chaincode parameters
ChainCodeID: "heroes-service",
ChaincodeGoPath: os.Getenv("GOPATH"),
ChaincodePath: "github.com/chainHero/heroes-service/chaincode/",
OrgAdmin: "Admin",
OrgName: "Org1",
ConfigFile: "config.yaml",
// User parameters
UserName: "User1",
}
[...]
// Install and instantiate the chaincode
err = fSetup.InstallAndInstantiateCC()
if err != nil {
fmt.Printf("Unable to install and instantiate the chaincode: %v\n", err)
}
}
The file is available here: main.go
We can test this, just with the make
command setup in the previous step:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
make
Tips: the installation and the instantiation don’t need to be run at every start of the application. Only when we update the chaincode (and the chaincode version). A solution is to provide an argument when we run the application to tell to do this additional procedure before move on. Since in this tutorial we will clean up the environment every time we don’t really care about that.
f. Query the chaincode
Like a database, the chaincode is plugged and ready to answer. Let’s try the hello
query.
We will put all query functions in a new file named query.go
in the blockchain
folder:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi blockchain/query.go
package blockchain
import (
"fmt"
"github.com/hyperledger/fabric-sdk-go/api/apitxn/chclient"
)
// QueryHello query the chaincode to get the state of hello
func (setup *FabricSetup) QueryHello() (string, error) {
// Prepare arguments
var args []string
args = append(args, "invoke")
args = append(args, "query")
args = append(args, "hello")
response, err := setup.client.Query(chclient.Request{ChaincodeID: setup.ChainCodeID, Fcn: args[0], Args: [][]byte{[]byte(args[1]), []byte(args[2])}})
if err != nil {
return "", fmt.Errorf("failed to query: %v", err)
}
return string(response.Payload), nil
}
The file is available here: blockchain/query.go
You can add the call to this new function in the main.go
:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi main.go
func main() {
[...]
// Query the chaincode
response, err := fSetup.QueryHello()
if err != nil {
fmt.Printf("Unable to query hello on the chaincode: %v\n", err)
} else {
fmt.Printf("Response from the query hello: %s\n", response)
}
}
The file is available here: main.go
Let’s try:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
make
g. Change the ledger state
The next thing to do in order to make a basic tour of the Fabric SDK Go, is to make a request to the chaincode in order to change the ledger state.
First, we will add this ability in the chaincode. Edit the chaincode/main.go
file:
[...]
// Invoke
// All future requests named invoke will arrive here.
func (t *HeroesServiceChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
fmt.Println("########### HeroesServiceChaincode Invoke ###########")
// Get the function and arguments from the request
function, args := stub.GetFunctionAndParameters()
// Check whether it is an invoke request
if function != "invoke" {
return shim.Error("Unknown function call")
}
// Check whether the number of arguments is sufficient
if len(args) < 1 {
return shim.Error("The number of arguments is insufficient.")
}
// In order to manage multiple type of request, we will check the first argument.
// Here we have one possible argument: query (every query request will read in the ledger without modification)
if args[0] == "query" {
return t.query(stub, args)
}
// The update argument will manage all update in the ledger
if args[0] == "invoke" {
return t.invoke(stub, args)
}
// If the arguments given don’t match any function, we return an error
return shim.Error("Unknown action, check the first argument")
}
[...]
// invoke
// Every functions that read and write in the ledger will be here
func (t *HeroesServiceChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
fmt.Println("########### HeroesServiceChaincode invoke ###########")
if len(args) < 2 {
return shim.Error("The number of arguments is insufficient.")
}
// Check if the ledger key is "hello" and process if it is the case. Otherwise it returns an error.
if args[1] == "hello" && len(args) == 3 {
// Write the new value in the ledger
err := stub.PutState("hello", []byte(args[2]))
if err != nil {
return shim.Error("Failed to update state of hello")
}
// Notify listeners that an event "eventInvoke" have been executed (check line 19 in the file invoke.go)
err = stub.SetEvent("eventInvoke", []byte{})
if err != nil {
return shim.Error(err.Error())
}
// Return this value in response
return shim.Success(nil)
}
// If the arguments given don’t match any function, we return an error
return shim.Error("Unknown invoke action, check the second argument.")
}
[...]
The file is available here: chaincode/main.go
From the application side, we add a new function to make the invocation of the chaincode. Add a file named invoke.go
in the blockchain
folder:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi blockchain/invoke.go
package blockchain
import (
"fmt"
"github.com/hyperledger/fabric-sdk-go/api/apitxn/chclient"
"time"
)
// InvokeHello
func (setup *FabricSetup) InvokeHello(value string) (string, error) {
// Prepare arguments
var args []string
args = append(args, "invoke")
args = append(args, "invoke")
args = append(args, "hello")
args = append(args, value)
eventID := "eventInvoke"
// Add data that will be visible in the proposal, like a description of the invoke request
transientDataMap := make(map[string][]byte)
transientDataMap["result"] = []byte("Transient data in hello invoke")
// Register a notification handler on the client
notifier := make(chan *chclient.CCEvent)
rce, err := setup.client.RegisterChaincodeEvent(notifier, setup.ChainCodeID, eventID)
if err != nil {
return "", fmt.Errorf("failed to register chaincode evet: %v", err)
}
// Create a request (proposal) and send it
response, err := setup.client.Execute(chclient.Request{ChaincodeID: setup.ChainCodeID, Fcn: args[0], Args: [][]byte{[]byte(args[1]), []byte(args[2]), []byte(args[3])}, TransientMap: transientDataMap})
if err != nil {
return "", fmt.Errorf("failed to move funds: %v", err)
}
// Wait for the result of the submission
select {
case ccEvent := <-notifier:
fmt.Printf("Received CC event: %s\n", ccEvent)
case <-time.After(time.Second * 20):
return "", fmt.Errorf("did NOT receive CC event for eventId(%s)", eventID)
}
// Unregister the notification handler previously created on the client
err = setup.client.UnregisterChaincodeEvent(rce)
return response.TransactionID.ID, nil
}
The file is available here: blockchain/invoke.go
You can then add the call to this function in the main.go
:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
vi main.go
func main() {
[...]
// Query the chaincode
response, err := fSetup.QueryHello()
if err != nil {
fmt.Printf("Unable to query hello on the chaincode: %v\n", err)
} else {
fmt.Printf("Response from the query hello: %s\n", response)
}
// Invoke the chaincode
txId, err := fSetup.InvokeHello("chainHero")
if err != nil {
fmt.Printf("Unable to invoke hello on the chaincode: %v\n", err)
} else {
fmt.Printf("Successfully invoke hello, transaction ID: %s\n", txId)
}
// Query again the chaincode
response, err = fSetup.QueryHello()
if err != nil {
fmt.Printf("Unable to query hello on the chaincode: %v\n", err)
} else {
fmt.Printf("Response from the query hello: %s\n", response)
}
}
The file is available here: main.go
Let’s try:
cd $GOPATH/src/github.com/chainHero/heroes-service && \
make
Note: this error message may appear:
endorsement validation failed: Endorser Client Status Code: (3) ENDORSEMENT_MISMATCH. Description: ProposalResponsePayloads do not match
. Since we have two peers, the SDK sends its request to the two directly and if it receives a different answer (which is quite possible because it’s an asynchronous system) then it returns this error. The best thing to do in these cases and start over again.
6. Make this in a web application
We also can make this usable for any user. The best choice is a web application and we are lucky because the Go language natively provides a web server handling HTTP requests and also templating for HTML.
For now, we have only two different actions: the query and the invocation of the hello value. Let’s make two HTML pages for each action. We add a web
directory with three other directories:
web/templates
: contains all HTML pages (templates)web/assets
: contains all CSS, Javascript, Fonts, Images…web/controllers
: contains all functions that will render templates
We use the MVC (Model-View-Controller) to make it more readable. The Model will be the blockchain part, the View are templates and Controller are provided by functions in the controllers
directory.
Populate each with the appropriate code (we also added Bootstrap to make the result a little prettier:
web/templates/layout.html
web/templates/home.html
web/templates/request.html
web/controllers/controller.go
web/controllers/home.go
web/controllers/request.go
web/app.go
web/assets
And finally, we change the main.go
, in order to use the web interface instead of directly query the blockchain.
Run the app and go to localhost:3000/home.html:
cd $GOPATH/src/github.com/chainHero/heroes-service ; \
make
The home
page make a query in the blockchain to get the value of the hello
key and display it.
The request
page has a form to change the hello
value.
After a successful submission the transaction ID is given.
We can see the change by going back to the home
page.
It’s the end for the first part. A more complex application is coming.
7. References
- Hyperledger website
- Hyperledger Fabric online documentation
- Hyperledger Fabric on github
- Hyperledger Fabric Certificate Authority on github
- Hyperledger Fabric SDK Go on github
- Fabric SDK Go tests
- CLI: An example CLI for Fabric built with the Go SDK.
First of all, thanks for a detailed tutorial. Its very useful.
Can you please help me in resolving an error that I am facing when trying to run command `dep ensure` :
Solving failure: No versions of golang.org/x/crypto met constraints:
master: unable to update checked out version: fatal: reference is not a tree: 21652f85b
: command failed: [git checkout 21652f85b0fdddb6c2b6b77a5beca5c5a908174a]: exit status 128
I have re-verified all the settings but can figure out what might be causing this.
Thanks
Hi and thanks for the feedback!
Can you try to remove the
Gopkg.lock
file and put the same content in theGopkg.toml
as: https://github.com/chainHero/heroes-service/blob/master/Gopkg.tomlAnd then run:
dep ensure
What system are you on?
Hi,
thank you for great tutorial.
I’m hitting the same problem. I created Gophg.toml as it is in https://github.com/chainHero/heroes-service/blob/master/Gopkg.toml, but I gen an error when execute ‘dep ensure’:
Solving failure: No versions of github.com/mitchellh/mapstructure met constraints:
master: unable to update checked out version: fatal: reference is not a tree: bb74f1db0675b241733089d5a1faa5dd8b0ef57b
: command failed: [git checkout bb74f1db0675b241733089d5a1faa5dd8b0ef57b]: exit status 128
Hello Nina,
Can you try to execute the command
dep ensure
again ? Sometimes dep is loosing the connection or having some connectivity trouble.If it’s still not working, please write the full log here, thanks 🙂
I tried to run make depend-install but its not working for me. I’m on Mac High Sierra, Go v1.10
TJLs-MBP:fabric-sdk-go tim$ make depend-install
Installing dependencies ...
Installing dep@v0.4.1 to /Users/tim/go/bin ...
HEAD is now at 37d9ea0 dep: Sharpen `dep prune` warning message
gocov is not installed (go get -u github.com/axw/gocov/...)
gocov-xml is not installed (go get -u github.com/AlekSi/gocov-xml)
misspell is not installed (go get -u github.com/client9/misspell/cmd/misspell)
golint is not installed (go get -u github.com/golang/lint/golint)
goimports is not installed (go get -u golang.org/x/tools/cmd/goimports)
mockgen is not installed (go get -u github.com/golang/mock/mockgen)
dep is not installed (go get -u github.com/golang/dep/cmd/dep)
Missing dependency. Aborting. You can fix by installing the tool listed above or running make depend-install.
make: *** [depend-install] Error 1
So I ran each of those by hand:
TJLs-MBP:fabric-sdk-go tim$ go get -u github.com/golang/lint/golint
TJLs-MBP:fabric-sdk-go tim$ go get -u github.com/axw/gocov/...
TJLs-MBP:fabric-sdk-go tim$ go get -u github.com/AlekSi/gocov-xml
TJLs-MBP:fabric-sdk-go tim$ go get -u github.com/client9/misspell/cmd/misspell
TJLs-MBP:fabric-sdk-go tim$ go get -u golang.org/x/tools/cmd/goimports
TJLs-MBP:fabric-sdk-go tim$ go get -u github.com/golang/mock/mockgen
TJLs-MBP:fabric-sdk-go tim$ go get -u github.com/golang/dep/cmd/dep
Then ran the make again, but still same error:
TJLs-MBP:fabric-sdk-go tim$ make depend-install
Installing dependencies ...
Installing dep@v0.4.1 to /Users/tim/go/bin ...
HEAD is now at 37d9ea0 dep: Sharpen `dep prune` warning message
gocov is not installed (go get -u github.com/axw/gocov/...)
gocov-xml is not installed (go get -u github.com/AlekSi/gocov-xml)
misspell is not installed (go get -u github.com/client9/misspell/cmd/misspell)
golint is not installed (go get -u github.com/golang/lint/golint)
goimports is not installed (go get -u golang.org/x/tools/cmd/goimports)
mockgen is not installed (go get -u github.com/golang/mock/mockgen)
dep is not installed (go get -u github.com/golang/dep/cmd/dep)
Missing dependency. Aborting. You can fix by installing the tool listed above or running make depend-install.
make: *** [depend-install] Error 1
Is something missing in the Makefile? Or is it due to GOPATH change in Go 1.10?
Hi,
I think there is a problem with the configuration of Go. Especially the $GOPATH/bin folder must not be in your PATH and therefore the binaries are not found.
Check this out: https://github.com/golang/go/wiki/SettingGOPATH
Hello,
I had an issue with the Makefile as well.
vendor/github.com/google/certificate-transparency-go/x509/root_cgo_darwin.go:210: cannot use nil as type _Ctype_CFDataRef in assignment
vendor/github.com/google/certificate-transparency-go/x509/root_cgo_darwin.go:211: cannot use nil as type _Ctype_CFDataRef in assignment
vendor/github.com/google/certificate-transparency-go/x509/root_cgo_darwin.go:221: cannot convert nil to type _Ctype_CFDataRef
The dep was pulling in an x509 file with a bug. Updating the dependency and rerunning
dep ensure
as suggested to gaurs did the trick.Could I ask you some question about the how to write chaincode with third-party packages?
Hi,
Yes no problem, post a comment or send me an email at: contact@chainhero.io.
To make it short, you need to provide a vendor directory to your chaincode that will be packaged and sent to peers.
Thanks you so much it’s working well now.
Hello, CHAIN HERO,
May I ask you about how to authentication the user at Hyperledger Fabric by using the Hyperledger Fabric CA? Is it the correct or not if I register the new user(ROLE user) and use their certificate to execute the Chaincode?
Thanks in advanced.
Hi, Thanks and very useful with detailed explanation.
I noticed you built from fabric-sdk-go instead of fabric. Why didn’t you build from fabric directly?
May i know why you use this approach.
Thanks
Hello and thank you for your return!
So we use Fabric’s SDK because it’s made for that. You could communicate directly with the network using Fabric, but it involves a lot more code, with no real benefit. The SDK was written to facilitate this communication process and limit the specificity of the code.
Hello and thank you for this tutorials, I am a beginner of learning hyperledger fabric . I am in trouble with writing blockchain/setup.go. The problem is that I don’t find the api package in fabric-sdk-go directory. There are pkg, scripts,test,third_party packages inside fabric-sdk-go directory. Finally, hope you not aware of my poor english.
Hi,
Thank you for this feedback!
You must probably use a more recent version of the Fabric Go SDK than the one in the tutorial. Even if the differences are minimal, there was a change of package. I strongly encourage you to use the same version as the tutorial so you won’t have any more mistakes for the future. Check the Fabric Go SDK installation section: https://chainhero.io/2018/03/tutorial-build-blockchain-app-2/#fabric-sdk-go
It is necessary to position yourself to the revision “614551a752802488988921a730b172dada7def1d” in the directory of the SDK Fabric Go:
Thank you for U reply. I try this.
im doing everything in the tutorial and right before “d. Clean up and Makefile”
I get this error code:
[fabric_sdk_go] 2018/03/29 17:15:57 UTC - config.initConfig -> INFO config fabric_sdk_go logging level is set to: INFO
Unable to initialize the Fabric SDK: failed to create channel: create channel failed: failed broadcast to orderer: Orderer Server Status Code: (400) BAD_REQUEST. Description:
Help please!
Hello,
You seems to have the exact same problem as @haithem.
Here is my answer to him, tell me if it helps.
—-
Hello,
In order for us to answer as quick and precise as possible we need you to give us more informations about your distro.
However, I might understand what’s going on here. In fact, it seems that the environment was already up when you executed this command line.
Try to execute
cd $GOPATH/src/github.com/chainHero/heroes-service/fixtures && docker-compose down
Then redo the command that gave you this error.
—-
heroes-service/fixtures && \
> docker-compose up -d && \
> cd .. && \
> ./heroes-service
ca.org1.hf.chainhero.io is up-to-date
orderer.hf.chainhero.io is up-to-date
peer1.org1.hf.chainhero.io is up-to-date
peer0.org1.hf.chainhero.io is up-to-date
[fabric_sdk_go] 2018/03/30 12:29:35 UTC - config.initConfig -> INFO config fabric_sdk_go logging level is set to: INFO
Unable to initialize the Fabric SDK: failed to create channel: create channel failed: failed broadcast to orderer: Orderer Server Status Code: (400) BAD_REQUEST. Description:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x9a587d]
goroutine 1 [running]:
github.com/chainHero/heroes-service/blockchain.(*FabricSetup).InstallAndInstantiateCC(0xc42018ad00, 0x28, 0xc420165e90)
/home/haithem/go/src/github.com/chainHero/heroes-service/blockchain/setup.go:102 +0x1ad
main.main()
/home/haithem/go/src/github.com/chainHero/heroes-service/main.go:37 +0x1f1
Whats wrong here?
Hello,
In order for us to answer as quick and precise as possible we need you to give us more informations about your distro.
However, I might understand what’s going on here. In fact, it seems that the environment was already up when you executed this command line.
Try to execute
cd $GOPATH/src/github.com/chainHero/heroes-service/fixtures && docker-compose down
Then redo the command that gave you this error.
I have followed the steps up to “d” successfully. The last step of “d”
~/go/src/github.com/chainHero/heroes-service$ make all
results in:
Stop environnement ...
Removing network fabsdkgo_default
WARNING: Network fabsdkgo_default not found.
Environnement down
Clean up ...
Clean up done
Build ...
Solving failure: No versions of github.com/milagro-crypto/amcl met constraints:
master: Could not introduce github.com/milagro-crypto/amcl@master due to multiple problematic subpackages:
Subpackage github.com/milagro-crypto/amcl/version3/go/amcl is missing. (Package is required by
github.com/hyperledger/fabric@release-1.1.) Subpackage github.com/milagro-crypto/amcl/version3/go/amcl/FP256BN is
missing. (Package is required by github.com/hyperledger/fabric@release-1.1.)
With several more subpackage problems.
I went to the milago-crypto github page. Indeed the files are missing from version 3. I noticed that the errors specify that the missing files a required by fabric@release-1.1.
Is this the issue? Since fabric 1.1 is new are there some inconsistencies that have to to be addressed?
Thanks for any and all help!
~Jake
Hello,
In order for us to answer as quick and precise as possible I need you to give me more informations about your distro.
Moreover, did you already download the Hyperledger Fabric SDK Go before following this tutorial, or it’s the first time that you downloaded it ?
Hello Jake,
We figured out what gave you this error. Here is the explanation of the issue and its solution.
To be short, our tutorial is using the latest version of Hyperledger Fabric. And it was working fine with it at the time when we released this tutorial.
And as a matter of fact, we did not anticipate the fact that Hyperledger Fabric was being often updated . Therefore, instead of fixing the version of Hyperledger Fabric to 1.0.5, the tutorial keep using its newest version. Which recently lead to the issue you experienced.
To fix this issue follow these steps :
-> Remove the “vendor” folder
cd $GOPATH/src/github.com/chainHero/heroes-service && rm -rf vendor
-> Remove the “Gopkg.lock” file
cd $GOPATH/src/github.com/chainHero/heroes-service && rm -f Gopkg.lock
Edit the “Gopkg.toml” and make it match with the new “Gopkg.toml” which is available in our repository : https://github.com/chainHero/heroes-service/blob/v1.0.5/Gopkg.toml
Once those steps are done, you can execute the command which was giving you this error :
cd $GOPATH/src/github.com/chainHero/heroes-service && make
Please tell us if it works.
Hi,
The same error for me…and first time Hyperledger Fabric SDK Go too. And before I use on amcl python config64.py and I installed FP256BN so the directory is there ..I do not understand
cd $GOPATH/src/github.com/chainHero/heroes-service && make
Stop environment ...
Removing network fabsdkgo_default
WARNING: Network fabsdkgo_default not found.
Environment down
Clean up ...
Clean up done
Build ...
Solving failure: No versions of github.com/milagro-crypto/amcl met constraints:
master: Could not introduce github.com/milagro-crypto/amcl@master due to multiple problematic subpackages:
Subpackage github.com/milagro-crypto/amcl/version3/go/amcl is missing. (Package is required by github.com/hyperledger/fabric@release-1.1.) Subpackage github.com/milagro-crypto/amcl/version3/go/amcl/FP256BN is missing. (Package is required by github.com/hyperledger/fabric@release-1.1.)
Hello @Pruvost,
Try to delete the vendor folder and the Gopkg.lock :
rm -rf $GOPATH/src/github.com/chainHero/heroes-service/Gopkg.lock && \
rm -rf $GOPATH/src/github.com/chainHero/heroes-service/vendor
Then, try to re-execute this function :
cd $GOPATH/src/github.com/chainHero/heroes-service && make
Please let us know if it works.
I too have the same problem. It didn’t go away after the above steps.
anyone got the solution for above error? I am facing the same issue.
Ubuntu 14.04
I didn’t download Hyperledger fabric before this tutorial.
This is the first tutorial I am following for Hyperledger and followed all the steps as they are mention in the tutorial.
Hello Ashwani,
We figured out what gave you this error. Here is the explanation of the issue and its solution.
To be short, our tutorial is using the latest version of Hyperledger Fabric. And it was working fine with it at the time when we released this tutorial.
And as a matter of fact, we did not anticipate the fact that Hyperledger Fabric was being often updated . Therefore, instead of fixing the version of Hyperledger Fabric to 1.0.5, the tutorial keep using its newest version. Which recently lead to the issue you experienced.
To fix this issue follow these steps :
-> Remove the “vendor” folder
cd $GOPATH/src/github.com/chainHero/heroes-service && rm -rf vendor
-> Remove the “Gopkg.lock” file
cd $GOPATH/src/github.com/chainHero/heroes-service && rm -f Gopkg.lock
Edit the “Gopkg.toml” and make it match with the new “Gopkg.toml” which is available in our repository : https://github.com/chainHero/heroes-service/blob/v1.0.5/Gopkg.toml
Once those steps are done, you can execute the command which was giving you this error :
cd $GOPATH/src/github.com/chainHero/heroes-service && make
Please tell us if it works.
Thanks for the update.I didn’t find “reply” button on your answer, so posting it here.
The error which I was getting earlier is gone, but now getting the below issues:-
main.go:6:2: cannot find package “github.com/chainHero/heroes-service/web” in any of:
/home/ashwani/go/src/github.com/chainHero/heroes-service/vendor/github.com/chainHero/heroes-service/web (vendor tree)
/usr/local/go/src/github.com/chainHero/heroes-service/web (from $GOROOT)
/home/ashwani/go/src/github.com/chainHero/heroes-service/web (from $GOPATH)
main.go:7:2: cannot find package “github.com/chainHero/heroes-service/web/controllers” in any of:
/home/ashwani/go/src/github.com/chainHero/heroes-service/vendor/github.com/chainHero/heroes-service/web/controllers (vendor tree)
/usr/local/go/src/github.com/chainHero/heroes-service/web/controllers (from $GOROOT)
/home/ashwani/go/src/github.com/chainHero/heroes-service/web/controllers (from $GOPATH)
make: *** [build] Error 1
Hello Ashwani,
You are using the main.go available in the repository (which is what you are suppose to have at the end of the tutorial) however you did not follow the tutorial till its end. So right now you are trying to compile the web files without created them. We are creating the web files at the end of the tutorial.
Go back to this part of the tutorial and you should be fine : https://github.com/chainHero/heroes-service/tree/v1.0.5#c-test
Please tell us if it helps.
Thanks for the update, I had figured that out and fixed the issue.
In every section below where it is explained what needs to be edited in a particular file there’s a link :- “The file is available here”. I assumed that it’s taking me to particular revision number of the file and not the final commit.
I think I copied the main.go file from the github link – that’s why I copied the final version of it.
Anyways that issue is sorted out and the application is working fine.
Thanks for the help.
Hello Vivek,
We figured out what gave you this error. Here is the explanation of the issue and its solution.
To be short, our tutorial is using the latest version of Hyperledger Fabric. And it was working fine with it at the time when we released this tutorial.
And as a matter of fact, we did not anticipate the fact that Hyperledger Fabric was being often updated . Therefore, instead of fixing the version of Hyperledger Fabric to 1.0.5, the tutorial keep using its newest version. Which recently lead to the issue you experienced.
To fix this issue follow these steps :
-> Remove the “vendor” folder
cd $GOPATH/src/github.com/chainHero/heroes-service && rm -rf vendor
-> Remove the “Gopkg.lock” file
cd $GOPATH/src/github.com/chainHero/heroes-service && rm -f Gopkg.lock
Edit the “Gopkg.toml” and make it match with the new “Gopkg.toml” which is available in our repository : https://github.com/chainHero/heroes-service/blob/v1.0.5/Gopkg.toml
Once those steps are done, you can execute the command which was giving you this error :
cd $GOPATH/src/github.com/chainHero/heroes-service && make
Please tell us if it works.
Hello Pruvost,
We figured out what gave you this error. Here is the explanation of the issue and its solution.
To be short, our tutorial is using the latest version of Hyperledger Fabric. And it was working fine with it at the time when we released this tutorial.
And as a matter of fact, we did not anticipate the fact that Hyperledger Fabric was being often updated . Therefore, instead of fixing the version of Hyperledger Fabric to 1.0.5, the tutorial keep using its newest version. Which recently lead to the issue you experienced.
To fix this issue follow these steps :
-> Remove the “vendor” folder
cd $GOPATH/src/github.com/chainHero/heroes-service && rm -rf vendor
-> Remove the “Gopkg.lock” file
cd $GOPATH/src/github.com/chainHero/heroes-service && rm -f Gopkg.lock
Edit the “Gopkg.toml” and make it match with the new “Gopkg.toml” which is available in our repository : https://github.com/chainHero/heroes-service/blob/v1.0.5/Gopkg.toml
Once those steps are done, you can execute the command which was giving you this error :
cd $GOPATH/src/github.com/chainHero/heroes-service && make
Please tell us if it works.
Got this error while running command make depend-install :
Installing dependencies ...
package github.com/axw/gocov/gocov
imports golang.org/x/tools/cover: unrecognized import path "golang.org/x/tools/cover" (https fetch: Get https://golang.org/x/tools/cover?go-get=1: proxyconnect tcp: EOF)
package golang.org/x/lint: unrecognized import path "golang.org/x/lint" (https fetch: Get https://golang.org/x/lint?go-get=1: proxyconnect tcp: EOF)
package golang.org/x/tools/cmd/goimports: unrecognized import path "golang.org/x/tools/cmd/goimports" (https fetch: Get https://golang.org/x/tools/cmd/goimports?go-get=1: proxyconnect tcp: EOF)
Installing dep@v0.4.1 to /home/rajani/go/bin ...
HEAD is now at 37d9ea0 dep: Sharpen `dep prune` warning message
gocov is not installed (go get -u github.com/axw/gocov/...)
golint is not installed (go get -u github.com/golang/lint/golint)
goimports is not installed (go get -u golang.org/x/tools/cmd/goimports)
Missing dependency. Aborting. You can fix by installing the tool listed above or running make depend-install.
Makefile:178: recipe for target 'depend-install' failed
make: *** [depend-install] Error 1
Hello Sir,
May you tell us your version of Golang :
go version
If it’s not already the case (even if it should if you followed the tutorial), update Go to at least 1.9.2.
However it seems that it was a connection problem and not something else (cf. https fetch: Get https://golang.org/x/lint?go-get=1: proxyconnect tcp: EOF). Maybe their server was down for few minutes while you tried to run this command. Can you try to re-execute
make depend-install
.Please let us know if it works.
When running make on fabric-sdk-go I am getting below error,
grouped write of manifest, lock and vendor: error while writing out vendor tree: failed to write dep tree: failed to prune github.com/google/certificate-transparency-go: failed to prune nested vendor directories: remove /tmp/dep324719032/vendor/github.com/google/certificate-transparency-go/vendor/github.com/coreos/etcd/cmd/vendor/golang.org/x/sys/unix: directory not empty
Makefile:382: recipe for target 'populate-vendor' failed
make: *** [populate-vendor] Error 1
I have checked out the fabric-sdk to revision 614551a752802488988921a730b172dada7def1d
Please let me know what went wrong here.
Thanks,
Vinayak.
Hello Vinayak,
Try to delete the vendor folder :
cd $GOPATH/src/github.com/hyperledger/fabric-sdk-go && \
rm -r vendor
Then, repopulate it :
cd $GOPATH/src/github.com/hyperledger/fabric-sdk-go && \
make populate
Please let us know if it works.
Hi, thank you so much for your helpful blog.
I got a lot of useful information here.
I followed your instruction and It is working well. While I was working on this, I have two questions.
1. I created fixtures directory by your other blog, https://chainhero.io/2018/04/tutorial-hyperledger-fabric-how-to-build-your-first-network/
I cannot run your application with this fixtures. Initialization step complains that bad certificates. In my case, I could run your application with only fixtures in the application.
I don’t know the reason.
2. When I run your application by “go run main.go” without makefile, chain code instantiation step complains a lot like this.
[fabsdk/fab] 2018/05/09 07:47:14 UTC - channel.orderersFromChannelCfg -> WARN Getting orderers from endpoint config channels.orderer is deprecated, use entity matchers to override orderer configuration
[fabsdk/fab] 2018/05/09 07:47:14 UTC - channel.orderersFromChannelCfg -> WARN visit https://github.com/hyperledger/fabric-sdk-go/blob/master/test/fixtures/config/overrides/local_entity_matchers.yaml for samples
[fabsdk/fab] 2018/05/09 07:47:15 UTC - connection.(*DeliverConnection).Receive -> WARN Received error from stream: [rpc error: code = Unimplemented desc = unknown service protos.Deliver]. Sending disconnected event.
[fabsdk/fab] 2018/05/09 07:47:15 UTC - client.(*Client).monitorConnection -> WARN Event client has disconnected. Details: rpc error: code = Unimplemented desc = unknown service protos.Deliver
[fabsdk/fab] 2018/05/09 07:47:15 UTC - client.(*Client).monitorConnection -> WARN Attempting to reconnect...
[fabsdk/fab] 2018/05/09 07:47:15 UTC - connection.(*DeliverConnection).Receive -> WARN Received error from stream: [rpc error: code = Unimplemented desc = unknown service protos.Deliver]. Sending disconnected event.
[fabsdk/fab] 2018/05/09 07:47:15 UTC - client.(*Client).monitorConnection -> WARN Event client has disconnected. Details: rpc error: code = Unimplemented desc = unknown service protos.Deliver
[fabsdk/fab] 2018/05/09 07:47:15 UTC - client.(*Client).monitorConnection -> WARN Attempting to reconnect...
[fabsdk/fab] 2018/05/09 07:47:15 UTC - connection.(*DeliverConnection).Receive -> WARN Received error from stream: [rpc error: code = Unimplemented desc = unknown service protos.Deliver]. Sending disconnected event.
[fabsdk/fab] 2018/05/09 07:47:15 UTC - client.(*Client).monitorConnection -> WARN Event client has disconnected. Details: rpc error: code = Unimplemented desc = unknown service protos.Deliver
The application works with only binary file by makefile. How do I run the application by go run?
Thank you.
Hello Lee,
1. There is a particular step while creating your network ? I’m talking about that : https://github.com/chainHero/heroes-service-network#be-careful-you-need-to-change-something-in-the-file- . Make sure you follow it, your error is very likely to come from this.
2. I’m not sure to understand. Can you try to :
a. Clone the repo :
git clone https://github.com/chainHero/heroes-service.git
b. Open 2 terminals
c. Launch the network
cd $GOPATH/src/github.com/chainhero/heroes-service/fixtures && docker-compose up
d. Launch the application
cd $GOPATH/src/github.com/chainhero/heroes-service && go run main.go
Can you tell me if it works ? From what I understand about your issue it seems to be a network problem. Let me know if it’s working like that and I’ll try my best to help you better.
Hi,
When i run “make” from step 5.e
It return error:
Initialization Successful
Unable to install and instantiate the chaincode: failed to instantiate the chaincode: send instantiate chaincode proposal failed: Multiple errors occurred:
Transaction processor (localhost:7051) returned error for txID '437be6c28eef48bee63c3954e9faa3203a267ab96e7357c5c5a28d98a8c3ef4e': gRPC Transport Status Code: (2) Unknown. Description: Error starting container: Failed to generate platform-specific docker build: Error returned from build: 2 "# github.com/chainHero/heroes-service/chaincode
chaincode/input/src/github.com/chainHero/heroes-service/chaincode/main.go:66: illegal UTF-8 sequence
chaincode/input/src/github.com/chainHero/heroes-service/chaincode/main.go:94: illegal UTF-8 sequence
chaincode/input/src/github.com/chainHero/heroes-service/chaincode/main.go:126: illegal UTF-8 sequence
"
Transaction processor (localhost:8051) returned error for txID '437be6c28eef48bee63c3954e9faa3203a267ab96e7357c5c5a28d98a8c3ef4e': gRPC Transport Status Code: (2) Unknown. Description: Error starting container: Failed to generate platform-specific docker build: Error returned from build: 2 "# github.com/chainHero/heroes-service/chaincode
chaincode/input/src/github.com/chainHero/heroes-service/chaincode/main.go:66: illegal UTF-8 sequence
chaincode/input/src/github.com/chainHero/heroes-service/chaincode/main.go:94: illegal UTF-8 sequence
chaincode/input/src/github.com/chainHero/heroes-service/chaincode/main.go:126: illegal UTF-8 sequence
I try to get all config, it still error.
Have you any ideas to help me?
I have problem when run “make”
Here is my error:
Initialization Successful
Unable to install and instantiate the chaincode: failed to instantiate the chaincode: send instantiate chaincode proposal failed: Multiple errors occurred:
Transaction processor (localhost:7051) returned error for txID '19bf04d84780378b780b9ff7b19b13062eb419517d3f726ec81538afe587faa6': gRPC Transport Status Code: (2) Unknown. Description: Error starting container: Failed to generate platform-specific docker build: Error returned from build: 2 "# github.com/chainHero/heroes-service/chaincode
chaincode/input/src/github.com/chainHero/heroes-service/chaincode/main.go:88: illegal UTF-8 sequence
Can you help me!
I had tried step by step on tutorials already
Hello Maximin,
This error seems to be due to a typo error which sneak in your copy/paste command.
Try to clone the repository and re execute the application :
cd $GOPATH/src/github.com/chainhero/ && git clone https://github.com/chainHero/heroes-service.git
make
Tell me if it works and I’ll come back to you to find what exactly the issue is.
Maxime,
It seems that on Github you are using “chainHero” in the path but in this tutorial you are using “chainhero”.
Is this correct or just an faulty oberservation?
Thanks.
PM
Hey PM,
Well I’m not sure to understand properly what are you trying to say. This page is just a mirror of the github page.
I guess you are looking on the old version of the tutorial.
Anyway, if you are sure about yourself please tell me where the difference is and I will correct the mistake.
Maxime
Actually it is my mistake as was referring to both pages inadvertently but now I am looking only at github page and all file/folder names are consistent.
One question on intialization of Fabric SDK, you have used syntax as below:
"sdk, err := fabsdk.New(config.FromFile(setup.ConfigFile))"
But I cannot find any documentation around “FromFile” function in the Go SDK(v1.1) for creating an instance of apiconfig. Do you mind clarifying the syntax above or point me to the right documentation. I also tried downloading the exact version (1.0.05) with the link you provided above the git command does not retrieve any file in the fabric-sdk-go folder and shows following output:
git checkout 614551a752802488988921a730b172dada7def1d
HEAD is now at 614551a... [FAB-8299] Rename ChannelConfig to Config
Thanks for your help!
Hey PM,
For development purpose we didn’t use either V 1.1 or any version. We are checking out to a specific commit. This one to be precise : 614551a752802488988921a730b172dada7def1d.
And now you can find the function you are talking about here : https://github.com/hyperledger/fabric-sdk-go/blob/614551a752802488988921a730b172dada7def1d/pkg/config/config.go#L84, and its documentation here https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/core/config#FromFile
Last but not least, you are saying that you are going inside the fabric-sdk-go folder and checking out to a specific version and that it does not work. But I don’t understand what you are trying to do, therefore I cannot answer you properly. The folder where the program is finding all of the dependencies is the “vendor” folder, ruled by the “Gopkg.toml” file.
Did it help you ? Let me know about it,
Maxime
hello,
I got a some question that can’t find ‘NewClient’ function it is.
so, I’ll try find it but i can’t see it at the gosdk-doc,
there is only ‘New’ func of here : https://godoc.org/github.com/hyperledger/fabric-sdk-go
Please, comment for me
Thank you
Hello Brian,
You are looking at the newest gosdk-doc, that’s why you cannot see the
NewClient
function. They must have refactored it by now toNew
. If you really need the documentation at this exact version, check this out https://godoc.org/golang.org/x/tools/cmd/godoc.Maxime
Hello,
First of all, that’s a really greate tutorial, really really good job !! Thanks a lot !
I’ve been customising the chaincode and the fixture network. Now I’m trying to adapt this app to a non-TLS Fabric network (actually a Fabric network over Kubernetes). But I can’t find the way to disable TLS inside the config.yaml. Is it possible to do so ?
Monny
Hello Monny,
Actually, we are not managing this kind of configuration in the config.yaml file but instead through environment variable.
So to disable TLS you must set in each container the TLS_ENABLED value to false :
– For the orderer, add an environment variable named ORDERER_GENERAL_TLS_ENABLED and set it to false.
– For the ca, add an environment variable named FABRIC_CA_SERVER_TLS_ENABLED and set it to false.
– For the peer, add an environment variable named CORE_PEER_TLS_ENABLED and set it to false.
You should be all set up right now !
Maxime
I agree on this, all my dockers have these environment variable set to false. And the network works well by itself (setting up the channel and interacting with a chaincode through CLI container)
But then when I try to connect do a make dev to connect the SDK to a fresh non-TLS network I have an error looking like
Unable to initialize the Fabric SDK: failed to create channel: create channel failed: failed broadcast to orderer: NewAtomicBroadcastClient failed: gRPC Transport Status Code: (14) Unavailable. Description: all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: authentication handshake failed: tls: first record does not look like a TLS handshake"
Hi,
Did you remove the s in the communication protocol with the orderers and peers (in the config.yaml)?
Hi ChainHero !
Hooo right !! I’m able to initialize the SDK and install the chaincode. Thanks !
Still have some debug to todo, but it helped a lot
Hey !
The web application is able to handle multiple queries at the same time (multiple sessions querying the ledger at the same time).
But it cannot handle multiple invokations at the same time, you got a MVCC read error. It’s quite logic and understandable. But then, their is kind of a event registering error, that prevent the app to run normaly.
To avoid this situation what do you think about creating a queue with a channel in heroes-service/blockchain/invoke.go ?
Monny
Hey,
Indeed, you are absolutely right. You have two possibilities: either there is a central server and then it is easy to make a queue for the invocation, or there are several servers and then you have to use an external service that manages this queue (like FIFO AWS SQS queue).
Hello Maxime,
firstly, thank you for offering such a great tutorial.This is really really helpful !
I got some errors when I run the chaincode on my own distributed fabric network.Everything goes well until changing the ledger using chaincode.There are the errors.
Environment up
Start app ...
[fabric_sdk_go] 2018/06/12 06:36:12 UTC - config.initConfig -> INFO config fabric_sdk_go logging level is set to: INFO
Initilization Successful
chaincode Installation & Instantiation Successful
[fabric_sdk_go] 2018/06/12 06:36:23 UTC - msp.(*bccspmsp).DeserializeIdentity -> INFO Obtaining identity
[fabric_sdk_go] 2018/06/12 06:36:23 UTC - msp.(*bccspmsp).DeserializeIdentity -> INFO Obtaining identity
Response from the query hello:world
[fabric_sdk_go] 2018/06/12 06:36:23 UTC - msp.(*bccspmsp).DeserializeIdentity -> INFO Obtaining identity
[fabric_sdk_go] 2018/06/12 06:36:23 UTC - msp.(*bccspmsp).DeserializeIdentity -> INFO Obtaining identity
Unable to invoke hello,transaction ID:
[fabric_sdk_go] 2018/06/12 06:36:31 UTC - msp.(*bccspmsp).DeserializeIdentity -> INFO Obtaining identity
[fabric_sdk_go] 2018/06/12 06:36:31 UTC - msp.(*bccspmsp).DeserializeIdentity -> INFO Obtaining identity
, which shows “Unable to invoke hello”.
Then I look into the logs of peer.I find this error.
2018-06-12 14:36:31.585 CST [committer/txvalidator] validateTx -> ERRO 750 VSCCValidateTx for transaction txId = 45ee8c2c731051a9a316a3664c6dae7b2091cf94e628d05a4a0d642a07864923 returned error: VSCC error: endorsement policy failure, err: signature set did not satisfy policy
, which shows the endorsement policy has not be satisfied.But I did not find anywhere to change the endorsement policy while using fabric go sdk.There is my config.yaml file.
name: "chainHero-network"
description: "The network which will host my first blockchain"
version: 2
client:
organization: Org2
logging:
level: info
peer:
timeout:
connection: 3s
queryResponse: 45s
executeTxResponse: 30s
eventService:
timeout:
connection: 3s
registrationResponse: 3s
orderer:
timeout:
connection: 3s
response: 5s
cryptoconfig:
path: "${GOPATH}/src/github.com/gosdk/heroes-service/fixture/crypto-config"
credentialStore:
path: "/tmp/heroes-service-kvs"
cryptoStore:
path: "/tmp/heroes-service-msp"
BCCSP:
security:
enabled: true
default:
provider: "SW"
hashAlgorithm: "SHA2"
softVerify: true
ephemeral: false
level: 256
tlsCerts:
systemCertPool: false
channels:
mychannel:
orderers:
- orderer0.example.com
peers:
peer0.org2.example.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
peer1.org2.example.com:
endorsingPeer: true
chaincodeQuery: true
ledgerQuery: true
eventSource: true
organizations:
Org2:
mspid: Org2MSP
cryptoPath: "peerOrganizations/org2.example.com/users/{userName}@org2.example.com/msp"
peers:
- peer0.org2.example.com
- peer1.org2.example.com
certificateAuthorities:
- ca_peerOrg2
orderers:
orderer0.example.com:
url: grpcs://172.29.101.155:7050
grpcOptions:
ssl-target-name-override: orderer0.example.com
grpc-max-send-message-length: 15
tlsCACerts:
path: "${GOPATH}/src/github.com/gosdk/heroes-service/fixture/crypto-config/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem"
peers:
peer0.org2.example.com:
url: grpcs://172.29.101.157:7051
eventUrl: grpcs://172.29.101.157:7053
grpcOptions:
ssl-target-name-override: peer0.org2.example.com
grpc.http2.keepalive_time: 15
tlsCACerts:
path: "${GOPATH}/src/github.com/gosdk/heroes-service/fixture/crypto-config/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem"
peer1.org2.example.com:
url: grpcs://172.29.101.227:7051
eventUrl: grpcs://172.29.101.227:7053
grpcOptions:
ssl-target-name-override: peer1.org2.example.com
grpc.http2.keepalive_time: 15
tlsCACerts:
path: "${GOPATH}/src/github.com/gosdk/heroes-service/fixture/crypto-config/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem"
certificateAuthorities:
ca1:
url: https://172.29.101.157:7054
httpOptions:
verify: false
registrar:
enrollId: admin
enrollSecret: adminpw
caName: ca_peerOrg2
Hi @zqdou,
Did you keep the code from our tutorial ? As you created a new network, you need to change several things, endorsement policy included.
You can set the endorsement policy when you Instantiate the chaincode.
ccPolicy := cauthdsl.SignedByAnyMember([]string{"org1.hf.chainhero.io"})
https://github.com/chainHero/heroes-service/blob/c34b3ef76afb05dbe465e7f74dd136e9ded551dd/blockchain/setup.go#L111
In your case it would be :
ccPolicy := cauthdsl.SignedByAnyMember([]string{"org2.example.com"})
Have a great day,
Maxime
Hello,
I have a fabric network with 4 orderers.When I configure the config.yaml under orerder0 , everything goes well.BUT, when I change the orderer0 into orderer1,I get some problems listing below.
Start app ...
[fabric_sdk_go] 2018/06/13 01:53:52 UTC - config.initConfig -> INFO config fabric_sdk_go logging level is set to: INFO
unable to initialize the Fabric SDK: failed to create channel:create channel failed: failed broadcast to orderer: NewAtomicBroadcastClient failed: gRPC Transport Status Code: (14) Unavailable. Description: all SubConns are in TransientFailure
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x99d4f7]
What can I do ?
Looking forward your apply!
Thanks!
Hi @July,
I do not see why changing orderer0 to orderer1 would cause your program to have a Segmentation Fault.
Moreover, I cannot do anything for you if i cannot see your configuration file ..
Maxime
I get an error about make depend-install
It’s temme tha gocovisn’t installed gocov-xml misspell golint goimports mockgen dep
How i can solve it
Hi @ekanut,
This seems to be an issue relative to your $GOPATH.
Can you check if it is properly setted ?
Also, make sure that you are in
$GOPATH/src/github.com/hyperledger/fabric-sdk-go
when runningmake depend-install
.Tell me if it helps,
Maxime
I am using ubuntu 16.04 and getting this error:
[fabric_sdk_go] 2018/06/19 11:51:04 UTC - config.initConfig -> INFO config fabric_sdk_go logging level is set to: INFO
Unable to initialize the Fabric SDK: failed to create channel: create channel failed: failed broadcast to orderer: Orderer Server Status Code: (400) BAD_REQUEST. Description:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x9ac25d]
goroutine 1 [running]:
github.com/chainHero/heroes-service/blockchain.(*FabricSetup).InstallAndInstantiateCC(0xc4201a6d00, 0x28, 0xc420183e90)
/home/dhruv/go/src/github.com/chainHero/heroes-service/blockchain/setup.go:102 +0x1ad
main.main()
/home/dhruv/go/src/github.com/chainHero/heroes-service/main.go:37 +0x14b
I went through the comments other people also encountered this problem and I tried the given solutions but it is not helping as such.
Please help.
TIA
Hi @Dhruv,
It seems to be a network issue.
Can you try to reproduce the error and tell me what the command
docker ps
says ? Paste the output here.Looking forward your message,
Maxime
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c91d5931e670 whatsloan-peer0.org1.hf.whatsloan.com-whatsloan-service-1.0-40f78900327e24d01788779fae55a2e9530ffd492ecbfcfd47c69cca540c7c04 "chaincode -peer.add…" 6 minutes ago Up 6 minutes whatsloan-peer0.org1.hf.whatsloan.com-whatsloan-service-1.0
256dae02ae0b whatsloan-peer1.org1.hf.whatsloan.com-whatsloan-service-1.0-0cadaf5f9a154506644d1d038b1b6c6a486569af3fbe85cd4b4de6fd2ae7c98e "chaincode -peer.add…" 6 minutes ago Up 6 minutes whatsloan-peer1.org1.hf.whatsloan.com-whatsloan-service-1.0
ebee9cbaec8a hyperledger/fabric-peer:x86_64-1.0.5 "peer node start" 7 minutes ago Up 7 minutes 0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp peer1.org1.hf.whatsloan.com
e1aaced6e094 hyperledger/fabric-peer:x86_64-1.0.5 "peer node start" 7 minutes ago Up 7 minutes 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0.org1.hf.whatsloan.com
5034fc460109 hyperledger/fabric-ca:x86_64-1.0.5 "sh -c 'fabric-ca-se…" 7 minutes ago Up 7 minutes 0.0.0.0:7054->7054/tcp ca.org1.hf.whatsloan.com
6bbc0f448d5a hyperledger/fabric-orderer:x86_64-1.0.5 "orderer" 7 minutes ago Up 7 minutes 0.0.0.0:7050->7050/tcp orderer.hf.whatsloan.com
Hi, please use the last tutorial version (with Hyperledger Fabric v1.1.0) available here: https://chainhero.io/2018/06/tutorial-build-blockchain-app-v1-1-0/
Hey,
this is indeed written and compiled very well. For a first timer like me its like a holy grail!! kudos!!.
As you would have guessed by now I am a totally newbie and have a very basic question.
I am trying to change the state couchDB to level DB. i am trying to execute a query on the chain. Can you kindly point out where have you configured this and how to change this to levelDB?
Thanks in advance.
Hi @Girish,
You can change de stateDB using the docker-compose.yaml file.
https://hyperledger-fabric.readthedocs.io/en/release-1.1/couchdb_as_state_database.html#couchdb-configuration
Just add this to your docker environement : CORE_LEDGER_STATE_STATEDATABASE=goleveldb
Note: Why would you want to use LevelDB ? CouchDB is much more useful for query. See https://hyperledger-fabric.readthedocs.io/en/release-1.1/couchdb_as_state_database.html?highlight=rich%20query#state-database-options
Tell me if it helps,
Maxime
Hello, ChainHero
Thanks for all of these. Since you instructed me a lot, I made it.
It works!!
Hi Team,
May I know how much disk space required as I have 20G and getting disk full error while make
# cd $GOPATH/src/github.com/hyperledger/fabric-sdk-go ; \
> make
ERROR: failed to register layer: Error processing tar file(exit status 1): write /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/libsctp.so: no space left on device
make[1]: *** [integration-tests-stable] Error 1
make[1]: Leaving directory `/root/go/src/github.com/hyperledger/fabric-sdk-go'
make: *** [integration-test] Error 2
[root@ip-192-168-1-135 fabric-sdk-go]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 484M 56K 484M 1% /dev
tmpfs 494M 0 494M 0% /dev/shm
/dev/xvda1 20G 20G 331M 99% /
Hi, what takes up a lot of space is the docker images (for the v1.0.5):
~$ docker image list | grep "^hyperledger/fabric-" | grep x86_64-1.0.5
hyperledger/fabric-tools x86_64-1.0.5 6a8993b718c8 6 months ago 1.33GB
hyperledger/fabric-couchdb x86_64-1.0.5 9a58db2d2723 6 months ago 1.5GB
hyperledger/fabric-kafka x86_64-1.0.5 b8c5172bb83c 6 months ago 1.29GB
hyperledger/fabric-zookeeper x86_64-1.0.5 68945f4613fc 6 months ago 1.32GB
hyperledger/fabric-orderer x86_64-1.0.5 368c78b6f03b 6 months ago 151MB
hyperledger/fabric-peer x86_64-1.0.5 c2ab022f0bdb 6 months ago 154MB
hyperledger/fabric-javaenv x86_64-1.0.5 50890cc3f0cd 6 months ago 1.41GB
hyperledger/fabric-ccenv x86_64-1.0.5 33feadb8f7a6 6 months ago 1.28GB
hyperledger/fabric-ca x86_64-1.0.5 002c9089e464 6 months ago 238MB
There is 8,673 GB of images.
You need at least 10 GB of free space to proceed, I think.
[root@ip-192-168-1-135 heroes-service]# pwd
/root/go/src/github.com/chainHero/heroes-service
# make
Stop environment ...
Stopping peer0.org1.hf.chainhero.io ... done
Stopping peer1.org1.hf.chainhero.io ... done
Stopping orderer.hf.chainhero.io ... done
Stopping ca.org1.hf.chainhero.io ... done
Removing peer0.org1.hf.chainhero.io ... done
Removing peer1.org1.hf.chainhero.io ... done
Removing orderer.hf.chainhero.io ... done
Removing ca.org1.hf.chainhero.io ... done
Removing network fabsdkgo_default
Environment down
Clean up ...
Clean up done
Build ...
error while parsing /root/go/src/github.com/chainHero/heroes-service/Gopkg.toml: manifest validation failed: unable to load TomlTree from string: (7, 1): unexpected token
make: *** [build] Error 1
Check your Gopkg.toml file, there is an issue at the line 6 or 7 (compare with https://github.com/chainHero/heroes-service/blob/v1.1.0/Gopkg.toml )
First of all, thanks for a detailed tutorial. It’s very useful.
Last line :
It’s the end for the first part. A more complex application is coming…….. May I know by when(tentative date) it is expected?
Hello…thank you for the tutorial. However, I got some problems. When i executes command “make depend-install” i got warning:
Installing dependencies ...
Installing dep@v0.4.1 to /home/spark/go/bin ...
HEAD is now at 37d9ea0a dep: Sharpen `dep prune` warning message
And when i execute command "make" i got this warning:
created by testing.(*T).Run
/snap/go/2130/src/testing/testing.go:824 +0x565
FAIL github.com/hyperledger/fabric-sdk-go/pkg/fabric-txn/resmgmtclient 0.557s
ok github.com/hyperledger/fabric-sdk-go/pkg/fabric-txn/selection/dynamicselection (cached) coverage: 78.5% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabric-txn/selection/dynamicselection/pgresolver (cached) coverage: 79.4% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabric-txn/selection/staticselection (cached) coverage: 100.0% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabric-txn/txnhandler (cached) coverage: 84.2% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabsdk (cached) coverage: 79.6% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defclient (cached) coverage: 83.8% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defcore (cached) coverage: 89.5% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defsvc (cached) coverage: 100.0% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/provider/chpvdr (cached) coverage: 68.2% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/provider/fabpvdr (cached) coverage: 38.5% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/logging (cached) coverage: 84.1% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/logging/decorator (cached) coverage: 95.7% of statements
ok github.com/hyperledger/fabric-sdk-go/pkg/logging/modlog (cached) coverage: 88.5% of statements
? github.com/hyperledger/fabric-sdk-go/pkg/logging/utils [no test files]
Makefile:204: recipe for target 'unit-test' failed
make: *** [unit-test] Error 1
What should I do to fix it?? Thank you.
Hi, please use the last tutorial version (with Hyperledger Fabric v1.1.0) available here: https://chainhero.io/2018/06/tutorial-build-blockchain-app-v1-1-0/
Hi chainHero,
Your article very useful for me. But I got some problems
1. I initialized fabric-sdk-go and installed chaincode successfully
Initialization Successful
Chaincode Installation & Instantiation Successful
2. docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28243d664075 saneko-peer0.org1.saneko.io-saneko-network-1.0-52b0eb6822719383a5260b71118bcf50c935054f07434b0dd461cf10ae05bc28 "chaincode -peer.add…" About a minute ago Up About a minute saneko-peer0.org1.saneko.io-saneko-network-1.0
0ebb3e8c0133 saneko-peer1.org1.saneko.io-saneko-network-1.0-1562801782ea944634d345ffd60e5ed4336f5902ed4ce586ef763e1ee1f4ecf3 "chaincode -peer.add…" About a minute ago Up About a minute saneko-peer1.org1.saneko.io-saneko-network-1.0
76abd3195d23 hyperledger/fabric-peer:x86_64-1.0.5 "peer node start" About a minute ago Up About a minute 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0.org1.saneko.io
1f9df5e59833 hyperledger/fabric-peer:x86_64-1.0.5 "peer node start" About a minute ago Up About a minute 0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp peer1.org1.saneko.io
6834d55143e8 hyperledger/fabric-ca:x86_64-1.0.5 "sh -c 'fabric-ca-se…" About a minute ago Up About a minute 0.0.0.0:7054->7054/tcp ca.org1.saneko.io
3f67c32c02f1 hyperledger/fabric-orderer:x86_64-1.0.5 "orderer" About a minute ago Up About a minute 0.0.0.0:7050->7050/tcp orderer.saneko.io
3. However when i invoked the system show errors
failed to move funds: send transaction proposal failed: Multiple errors occurred: \nTransaction processor (localhost:7051) returned error for txID '0477bf207ff9ce9a5ee3a8df9ec751f9afaea6f8d75a7cf8db7a142255ca7bde': gRPC Transport Status Code: (2) Unknown. Description: chaincode error (status: 500, message: Unknown invoke action, check the second argument.)\nTransaction processor (localhost:8051) returned error for txID '0477bf207ff9ce9a5ee3a8df9ec751f9afaea6f8d75a7cf8db7a142255ca7bde': gRPC Transport Status Code: (2) Unknown. Description: chaincode error (status: 500, message: Unknown invoke action, check the second argument.)
Please help me to fix it . Thanks!
Hey,
I am getting the following error when I run ‘make’ after running ‘make depend-install’ when installing the SDK.
All files have SPDX-License-Identifier headers
Populating vendor ...
Running linters...
Checking ./api
You should check the following golint suggestions:
api/apiconfig/mocks/mockconfig.go:7:1: don't use an underscore in package name
end golint suggestions
Checking ./def
Checking ./pkg
Checking ./test
# github.com/hyperledger/fabric-sdk-go/test/integration
test/integration/base_test_setup.go:103: Wrapf format %v reads arg #2, but call has 1 arg
test/integration/base_test_setup.go:127: Wrapf format %v reads arg #2, but call has 1 arg
Makefile:189: recipe for target 'lint' failed
make: *** [lint] Error 2
Please help.
Hello chainhero. Thanks for the wonderful tutorial
There’s nothing example out there except you presenting fabric-sdk-go but I was worried (our team was worried) because the fabric-sdk-go version you use is outdated with the current release and as far as I am concerned it become problem in the future compatibility. Any plans to upgrade this also? Im really new hyperledger but once I get your point I help maintaning the project,
root@ubuntu:~/go/src/github.com/chainHero/heroes-service# cd $GOPATH/src/github.com/chainHero/heroes-service && make
Stop environment ...
Removing network fabsdkgo_default
WARNING: Network fabsdkgo_default not found.
Environment down
Clean up ...
Clean up done
Build ...
main.go:6:2: cannot find package "github.com/chainHero/heroes-service/web" in any of:
/root/go/src/github.com/chainHero/heroes-service/vendor/github.com/chainHero/heroes-service/web (vendor tree)
/usr/lib/go-1.10/src/github.com/chainHero/heroes-service/web (from $GOROOT)
/root/go/src/github.com/chainHero/heroes-service/web (from $GOPATH)
main.go:7:2: cannot find package "github.com/chainHero/heroes-service/web/controllers" in any of:
/root/go/src/github.com/chainHero/heroes-service/vendor/github.com/chainHero/heroes-service/web/controllers (vendor tree)
/usr/lib/go-1.10/src/github.com/chainHero/heroes-service/web/controllers (from $GOROOT)
/root/go/src/github.com/chainHero/heroes-service/web/controllers (from $GOPATH)
Makefile:9: recipe for target 'build' failed
make: *** [build] Error 1
what happend to my sequence??
I got an error when I ran make:
Creating network "fabsdkgo_default" with the default driver
Creating ca.org1.hf.chainhero.io ...
Creating orderer.hf.chainhero.io ...
Creating ca.org1.hf.chainhero.io
Creating orderer.hf.chainhero.io ... done
Creating peer0.org1.hf.chainhero.io ...
Creating peer1.org1.hf.chainhero.io ...
Creating peer1.org1.hf.chainhero.io
Creating peer1.org1.hf.chainhero.io ... done
SDK created
Ressource management client created
Channel created
Channel joined
Initialization Successful
ccPkg created
Chaincode installed
[fabsdk/fab] 2019/07/04 07:51:08 UTC - peer.(*peerEndorser).sendProposal -> ERRO process proposal failed [rpc error: code = DeadlineExceeded desc = context deadline exceeded]
[fabsdk/fab] 2019/07/04 07:51:08 UTC - peer.(*peerEndorser).sendProposal -> ERRO process proposal failed [rpc error: code = DeadlineExceeded desc = context deadline exceeded]
Unable to install and instantiate the chaincode: failed to instantiate the chaincode: sending deploy transaction proposal failed: Multiple errors occurred:
Transaction processing for endorser [localhost:8051]: gRPC Transport Status Code: (4) DeadlineExceeded. Description: context deadline exceeded
Transaction processing for endorser [localhost:7051]: gRPC Transport Status Code: (4) DeadlineExceeded. Description: context deadline exceeded
can anyone help?
Thanks for the tutorial first.
I have a one question like how to upgrade the chain-code using fabric sdk go? DO you have any idea how we can achieve this without making the network down?
I’m trying to upgrade as like as Fabric cli commands but i’m facing some issues like
2019-10-21 04:40:51.580 UTC [shim] setupChaincodeLogging -> INFO 001 Chaincode log level not provided; defaulting to: INFO
2019-10-21 04:40:51.580 UTC [shim] setupChaincodeLogging -> INFO 002 Chaincode (build level: ) starting up ...
2019-10-21 04:40:54.580 UTC [shim] userChaincodeStreamGetter -> ERRO 003 context deadline exceeded
error trying to connect to local peer
github.com/hyperledger/fabric/core/chaincode/shim.userChaincodeStreamGetter
/opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/shim/chaincode.go:112
github.com/hyperledger/fabric/core/chaincode/shim.Start
/opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/shim/chaincode.go:151
main.main
/opt/gopath/src/heroes-service/main_original.go:30
runtime.main
/opt/go/src/runtime/proc.go:201
runtime.goexit
/opt/go/src/runtime/asm_amd64.s:1333
Error starting Simple chaincode: error trying to connect to local peer: context deadline exceededroot@903af3e6fea2:/opt/gopath/src/heroes-service#
root@903af3e6fea2:/opt/gopath/src/heroes-service#
root@903af3e6fea2:/opt/gopath/src/heroes-service# CORE_PEER_ADDRESS=0.0.0.0:7052 CORE_CHAINCODE_ID_NAME=my:1 ./heroes-service
2019-10-21 04:41:18.152 UTC [shim] setupChaincodeLogging -> INFO 001 Chaincode log level not provided; defaulting to: INFO
2019-10-21 04:41:18.152 UTC [shim] setupChaincodeLogging -> INFO 002 Chaincode (build level: ) starting up ...
Hi there,
thanks a lot for your tutorial, really useful.
I’m trying to implement an external service (an oracle), in golang with fabric-sdk-go, but I’m new to fabric, other than this article, can you suggest me some documentation or good articles about it? thanks.