开发者要能在不完整的终端网络中测试区块链。本文档描述了怎样在本地开发环境中编写,构建,测试区块链。

首先需要有多个Vagrant的终端窗体。一个Vagrant终端运行validating peer,一个运行chaincode,还有一个通过命令行接口或者REST API来执行交易。当启用了安全验证后,还需要一个运行CA服务。

安全设置 (可选)

在命令行终端中,进入工作空间环境下的devenv子目录。登录Vagrant:

vagrant ssh

要在开发环境中启用安全设置,首先要构建并运行CA服务:

cd $GOPATH/src/github.com/hyperledger/fabric/membersrvc
go build
./membersrvc

上面的命令使用membersrvc.yaml中的默认配置构建运行了CA服务。默认配置中包含了很多已经注册到CA中的用户,这些用户写在配置文件的users部分。要在CA中注册其他用户用于测试,需要修改membersrvc.yaml的users部分,增加一对enrollmentID和enrollmentPW。

enrollmentPW前面有一个数字,代表了用户的角色,其中1代表client,2代表non-validating peer,4代表validating peer,8代表auditor。

Vagrant 终端 1 (validating peer)

记住:在启用安全后,要运行peer,首先要修改core.yaml配置文件,设置security.enabled为true。也可以通过把环境变量CORE_SECURITY_ENABLED设置为true来运行peer。要启用交易的隐私和保密(要先启用安全),修改core.yaml的security.privacy为true。也可以通过把环境变量CORE_SECURITY_PRIVACY设置为true来运行peer。

在命令行终端中,进入工作空间环境下的devenv子目录。登录Vagrant:

vagrant ssh

在把security.enabled和security.privacy设置为true之后,再构建和运行peer进程:

cd $GOPATH/src/github.com/hyperledger/fabric/peer
go build
./peer peer --peer-chaincodedev   

也可以通过环境变量来启用security和privacy:

CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true ./peer peer --peer-chaincodedev

Vagrant 终端 2 (chaincode)

在命令行终端中,进入工作空间环境下的devenv子目录。登录Vagrant:

vagrant ssh

构建源码仓库提供的chaincode_example02:

cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
go build

当你已经准备好要开始创建自己的chaincode时,在/fabric/examples/go/chaincode下创建一个子目录用来存放chaincode代码。你可以把chaincode_example02中的文件拷贝进去之后再修改

运行下面的chaincode命令,用validating peer(Vagrant 终端 1)开始并注册chaincode:

CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=0.0.0.0:30303 ./chaincode_example02

chaincode的控制台会显示”Received REGISTERED, ready for invocations”,这证明chaincode已经准备好接收请求了。如果上面没有显示那段信息的话,那就是部署的过程中有错误。请重新看一遍上面的步骤,解决这个问题。遵循下面的步骤发布chaincode,调用或者查询交易。

Vagrant 终端 3 (CLI or REST API)

注意REST API的端口

REST接口的端口在core.yaml中定义的是5000。如果要在Vagrant中发送一个Rest请求给peer节点,使用的是5000端口。如果在Vagrant之外,也就是虚拟机之外发送REST请求,要使用3000端口。这是在构建虚拟机时,配置在Vagrantfile中的。

注意安全功能

现在的安全实现假定终端用户的安全认证发生在应用程序层,而不是在chaincode的基础架构中。只要该安全认证对应用程序来说是合适的就行。在用户认证成功之后 ,应用程序要在CA中执行一次注册。如果尝试在CA中对同一个用户注册第二次,就会报错。在注册期间,应用程序会给CA发送一个请求验证用户是否注册成功,CA会响应一个用户证书和密钥对。从CA收到的注册和交易证书会被存在本地的/var/hyperledger/production/crypto/client/文件夹中。用户要通过指定的peer节点进行交易,就必须要在该节点的认证资料存储目录中有自己的对应的信息。指定peer节点下的目录只允许用户通过该peer节点进行交易。如果终端用户要通过多于一个peer节点来执行交易,应用程序要负责把所有的认证资料复制到其他的peer节点上。这是必须的,因为在CA上重复注册同一个用户会失败。

当安全启用之后,命令行的命令和REST的请求中都必须包含已经登录的注册用户的enrollmentID ,否则就会导致错误。要登录一个注册后的用户,可以通过下面介绍的命令行或者REST API方式。

用下面的命令在命令行中登录,username是membersrvc.yaml的users部分配置的enrollmentID 。

在命令行终端中,进入工作空间环境下的devenv子目录。登录Vagrant:

vagrant ssh

通过命令行接口登录,替换下面的username:

cd $GOPATH/src/github.com/hyperledger/fabric/peer
./peer login <username>

该命令会提示输入密码,这个密码也是在membersrce.yaml中的。

通过REST API登录,发送一个POST请求到/registrar,要包含enrollmentID和enrollmentPW。记住,在Vagrant里面要用5000端口,在Vagrant外面要用3000端口。

REST Request:

POST localhost:3000/registrar

{
    "enrollId": "jim",
    "enrollSecret": "NPKYL39uKbkj"
}

REST Response:

200 OK
{
    "OK": "Login successful for user 'jim'."
}

通过命令行接口或者REST API发布Chaincode

首先,发送一个chaincode deploy transaction,只发送一次,到validating peer。命令行接口会通过core.yaml中的配置信息连接到validating peer。记住,一般deploy transaction要求一个path参数来定位,构建,发布chaincode。但是由于这里的介绍是为本地开发模式指定的,而且chaincode是手动发布的,所以使用了name参数来替代。

cd $GOPATH/src/github.com/hyperledger/fabric/peer
./peer chaincode deploy -n mycc -c '{"Function":"init", "Args": ["a","100", "b", "200"]}'

也可以使用REST API来运行chaincode deploy transaction。记住,在Vagrant里面使用5000端口,在Vagrant外面使用3000端口。

REST Request:

POST host:port/chaincode

{
    "jsonrpc": "2.0",
    "method": "deploy",
    "params": {
        "type": 1,
        "chaincodeID":{
            "name": "mycc"
        },
        "ctorMsg": {
            "function":"init",
            "args":["a", "100", "b", "200"]
        }
    },
    "id": 1
}

REST Response:

{
    "jsonrpc": "2.0",
    "result": {
        "status": "OK",
        "message": "mycc"
    },
    "id": 1
}

记住,当安全启用之后,要修改命令行的命令和REST API的请求内容,带上登录用户的enrollmentID。在命令行里,通过-u参数传递enrollmentID。在REST API里,通过secureContext。

./peer chaincode deploy -u jim -n mycc -c '{"Function":"init", "Args": ["a","100", "b", "200"]}'

REST Request:

POST host:port/chaincode

{
    "jsonrpc": "2.0",
    "method": "deploy",
    "params": {
        "type": 1,
        "chaincodeID":{
            "name": "mycc"
        },
        "ctorMsg": {
            "function":"init",
            "args":["a", "100", "b", "200"]
        },
        "secureContext": "jim"
    },
    "id": 1
}

上面初始化了一个chaincode,包含了a和b的信息,假设是帐户余额信息,那么现在我们记下了a有100块,b有200块。

通过命令行接口或者REST API调用Chaincode交易

在命令行中通过chaincode调用交易,-n参数需要和chaincode窗口(Vagrant 终端 2)中的-n参数匹配:

./peer chaincode invoke -l golang -n mycc -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'

下面是通过REST API调用,注意端口哦:

REST Request:

POST host:port/chaincode

{
    "jsonrpc": "2.0",
    "method": "invoke",
    "params": {
        "type": 1,
        "chaincodeID":{
            "name":"mycc"
        },
        "ctorMsg": {
            "function":"invoke",
            "args":["a", "b", "10"]
        }
    },
    "id": 3
}

REST Response:

{
    "jsonrpc": "2.0",
    "result": {
        "status": "OK",
        "message": "5a4540e5-902b-422d-a6ab-e70ab36a2e6d"
    },
    "id": 3
}

下面是在启用安全之后的调用方式:

./peer chaincode invoke -u jim -l golang -n mycc -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'

REST Request:

POST host:port/chaincode

{
    "jsonrpc": "2.0",
    "method": "invoke",
    "params": {
        "type": 1,
        "chaincodeID":{
            "name":"mycc"
        },
        "ctorMsg": {
            "function":"invoke",
            "args":["a", "b", "10"]
        },
        "secureContext": "jim"
    },
    "id": 3
}

上面发起了一笔交易,将a的10块钱给了b。

通过命令行接口或者REST API查询Chaincode

查询chaincode中的指定信息:

./peer chaincode query -l golang -n mycc -c '{"Function": "query", "Args": ["b"]}'

下面是响应信息:

210

下面是通过REST API的方式查询chaincode信息:

REST Request:

POST host:port/chaincode

{
    "jsonrpc": "2.0",
    "method": "query",
    "params": {
        "type": 1,
        "chaincodeID":{
            "name":"mycc"
        },
        "ctorMsg": {
            "function":"query",
            "args":["a"]
        }
    },
    "id": 5
}

REST Response:

{
    "jsonrpc": "2.0",
    "result": {
        "status": "OK",
        "message": "90"
    },
    "id": 5
}

下面是安全启用之后的调用方式:

./peer chaincode query -u jim -l golang -n mycc -c '{"Function": "query", "Args": ["b"]}'

REST Request:

POST host:port/chaincode

{
    "jsonrpc": "2.0",
    "method": "query",
    "params": {
        "type": 1,
        "chaincodeID":{
            "name":"mycc"
        },
        "ctorMsg": {
            "function":"query",
            "args":["a"]
        },
        "secureContext": "jim"
    },
    "id": 5
}

删除启用了安全之后,产生的临时文件

在安全模式下测试完chaincode后,要删除CA服务生成的临时文件,要删除客户端注册证书,注册key,交易证书链等等。如果你想注册一个前面已经注册的用户,就必须删除这些文件。

在命令行终端中,进入到工作空间环境的devenv子目录。登录到Vagrant终端:

vagrant ssh

然后运行:

rm -rf /var/hyperledger/production

原文地址:https://github.com/hyperledger/fabric/blob/master/docs/API/SandboxSetup.md