Hyperledger Composer Rest服务器的Passport-JWT身份验证

Hyperledger Composer是一个用于在Hyperledger Fabric区块链平台上开发区块链应用程序的框架。

我们最近介绍了Hyperledger Composer入门,如果你不熟悉该技术,我建议你阅读如何使用Hyperledger Fabric和Composer构建区块链网络。在本文中,我们将执行以下操作:

  • 创建示例业务网络定义。
  • 使用Docker和PassportJWT身份验证生成Composer Rest服务器。
  • 使用自定义JWT令牌使用Authenticated API。

要理解为什么这不是那么简单,你可以看看这个我一直密切关注的GitHub问题。

如果你熟悉Hyperledger Composer并且拥有示例网络,则可以直接跳转到Hyperledger Composer Rest Server部分。

先决条件

要继续学习,你应该安装以下内容。

1. Hyperledger Composer先决条件

这包括NodeJS LTS版本和Docker。你可以在本文档中找到适用于你的特定平台的说明。

安装完成后,你可以确认它们是否正常工作:

1
2
3
4
5
docker -v
Docker version 18.03.1-ce, build 9ee9f40

node -v
v8.11.2

2. Hyperledger Composer开发环境

这包括Composer CLI客户端:composer-cli,Yeoman Generator:generator-hyperledger-composeryo以及Hyperledger Fabric Docker镜像。我们将在Hyperledger Fabric实例部分中查看Hyperledger Fabric Docker镜像。

1
npm install -g composer-cli yo generator-hyperledger-composer

如果你使用Visual Studio Code进行开发工作,则可能需要安装Hyperledger Composer插件。

你可以在终端上输入composer命令确认已成功安装composer-cli:

1
2
composer -v
v0.19.5

Hyperledger Fabric实例

在开始之前,我们需要运行Hyperledger Fabric的实例。Hyperledger Composer开发环境指南提供了有关如何启动网络的说明,但我们将简要介绍它。

创建一个名为fabric-dev-server的目录,在终端内部拉出Hyperledger Composer提供的样本fabric-dev-server。

1
2
3
4
5
cd fabric-dev-server

curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.tar.gz

tar -xvf fabric-dev-servers.tar.gz

应该有以下文件,这将有助于你快速启动Hyperledger Fabric实例。

1
2
3
ls
DevServer_connection.json createComposerProfile.sh downloadFabric.sh fabric-scripts startFabric.sh teardownAllDocker.sh
_loader.sh createPeerAdminCard.sh fabric-dev-servers.tar.gz package.json stopFabric.sh teardownFabric.sh

要启动实例,请首先下载Hyperledger Fabric镜像。

1
./downloadFabric.sh

你将在系统中注意到以下新的Docker镜像。

1
2
3
4
5
6
7
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hyperledger/fabric-ca x86_64-1.1.0 72617b4fa9b4 2 months ago 299MB
hyperledger/fabric-orderer x86_64-1.1.0 ce0c810df36a 2 months ago 180MB
hyperledger/fabric-peer x86_64-1.1.0 b023f9be0771 2 months ago 187MB
hyperledger/fabric-ccenv x86_64-1.1.0 c8b4909d8d46 2 months ago 1.39GB
hyperledger/fabric-couchdb x86_64-0.4.6 7e73c828fc5b 3 months ago 1.56GB

接下来,启动Hyperledger Fabric实例。

1
./startFabric.sh

这些脚本需要几分钟才能完成。它创建了一个composer_defaultDocker网络,并在该网络中运行容器,以便它们可以通过自定义主机名进行通信。完成后,你可以通过检查正在运行的Docker容器来检查正在运行的Hyperledger Fabric的状态。

1
2
3
4
5
6
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4d59ab99ac8c hyperledger/fabric-peer:x86_64-1.1.0 "peer node start" 12 seconds ago Up 19 seconds 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0.org1.example.com
5985d3ceeb34 hyperledger/fabric-ca:x86_64-1.1.0 "sh -c 'fabric-ca-se…" 14 seconds ago Up 20 seconds 0.0.0.0:7054->7054/tcp ca.org1.example.com
1163c18322f3 hyperledger/fabric-couchdb:x86_64-0.4.6 "tini -- /docker-ent…" 14 seconds ago Up 19 seconds 4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp couchdb
0d4c964f8dc5 hyperledger/fabric-orderer:x86_64-1.1.0 "orderer" 14 seconds ago Up 20 seconds 0.0.0.0:7050->7050/tcp orderer.example.com

为composer设置Hyperledger Fabric实例的最后一步是生成凭据。Composer允许你通过在.card文件中保存相关信息来完成此操作。此文件通常基于连接配置文件生成,该配置文件在JSON文件中定义。我们下载的fabric-dev-server在文件fabric-dev-server/fabric-scripts/hlfv11/createPeerAdminCard.sh中有文件。

编辑创建连接配置文件的部分(撰写本文时的第78行)。它开始于:

1
cat << EOF > DevServer_connection.json

编辑内容以使用主机名,而不是默认的${HOST}。我们正在编辑的属性是ordererspeerscertificationAuthorities

createPeerAdminCard.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
cat << EOF > DevServer_connection.json
{
"name": "hlfv1",
"x-type": "hlfv1",
"x-commitTimeout": 300,
"version": "1.0.0",
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300",
"eventHub": "300",
"eventReg": "300"
},
"orderer": "300"
}
}
},
"channels": {
"composerchannel": {
"orderers": [
"orderer.example.com"
],
"peers": {
"peer0.org1.example.com": {}
}
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.example.com"
],
"certificateAuthorities": [
"ca.org1.example.com"
]
}
},
"orderers": {
"orderer.example.com": {
"url": "grpc://orderer.example.com:7050"
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpc://peer0.org1.example.com:7051",
"eventUrl": "grpc://peer0.org1.example.com:7053"
}
},
"certificateAuthorities": {
"ca.org1.example.com": {
"url": "http://ca.org1.example.com:7054",
"caName": "ca.org1.example.com"
}
}
}
EOF
...

与原始文件的不同之处在于我们已将${HOST}替换为自定义主机名。我们正在做他的,因为Composer Rest Server将作为Docker容器运行,它将使用这个主机名访问网络中的相关容器。

但请注意,我们仍需要从终端访问同行,证书颁发机构和订购者。它们已经被Docker暴露在我们的主机上,并且正在侦听localhost上的特定端口。因此,我们需要将这些主机名的记录添加到/etc/hosts文件中,以便在从我们的主机中调用时可以解析为localhost。你可能需要使用sudo

/etc/hosts

1
2
3
4
5
6
7
8
9
10
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
127.0.0.1 orderer.example.com peer0.org1.example.com ca.org1.example.com

现在,我们可以通过在fabric-dev-server目录中运行它来继续创建节点管理卡。

1
./createPeerAdminCard.sh

要检查现有卡,请运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
composer card list
The following Business Network Cards are available:

Connection Profile: hlfv1
┌─────────────────┬───────────┬──────────────────┐
│ Card Name │ UserId │ Business Network │
├─────────────────┼───────────┼──────────────────┤
│ PeerAdmin@hlfv1 │ PeerAdmin │ │
└─────────────────┴───────────┴──────────────────┘


Issue composer card list --card <Card Name> to get details a specific card

Command succeeded

商业网络

接下来,我们将创建一个示例业务网络。我们称之为tutorial-network,与Hyperledger文档中给出的名称相同。

我们的业务网络将是Hyperledger Yeoman生成器生成的默认网络。我们没有改变它,因为这里的主要重点是验证Composer Rest Server。

我们将使用我们开始时安装的generator-hyperledger-composer。使用以下内容,并在相关时进行更换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
yo hyperledger-composer:businessnetwork
Welcome to the business network generator
? Business network name: tutorial-network
? Description: tutorial network
? Author name: Christopher Ganga
? Author email: ganga.chris@gmail.com
? License: Apache-2.0
? Namespace: org.example.biznet
? Do you want to generate an empty template network? No: generate a populated sample network
create package.json
create README.md
create models/org.example.biznet.cto
create permissions.acl
create .eslintrc.yml
create features/sample.feature
create features/support/index.js
create test/logic.js
create lib/logic.js

这将生成一个名为tutorial-network的目录,其中包含以下内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.
├── README.md
├── features
│ ├── sample.feature
│ └── support
│ └── index.js
├── lib
│ └── logic.js
├── models
│ └── org.example.biznet.cto
├── package.json
├── permissions.acl
└── test
└── logic.js

5 directories, 8 files

部署业务网络

创建业务网络后,我们将继续构建存档文件,并将其部署到Hyperledger Fabric的现有运行实例。

在tutorial-network目录的根目录中,创建业务网络存档。

1
composer archive create -t dir -n .

这将创建存档文件tutorial-network@0.0.1.bna

现在我们有了归档文件,我们可以继续将网络安装到节点中。运行此命令以安装网络:

1
composer network install --card PeerAdmin@hlfv1 --archiveFile tutorial-network@0.0.1.bna

接下来,我们通过运行启动网络:

1
composer network start --networkName tutorial-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card

此命令可能需要一段时间才能运行,但是当它完成时,你会注意到一个新的Docker容器,其名称以dev-peer0.org1.example.com-tutorial-network-0.0.1 ...开头。运营我们的业务网络。你可以通过运行docker ps来检查这一点。

然后,我们需要导入新的networkadmin卡,以使其在网络中可用。

1
composer card import --file networkadmin.card

你得到一个networkadmin卡名称admin@tutorial-network,我们可以继续使用它。你也可以通过运行composer card list来检查。

最后,为了确保成功部署业务网络,我们可以ping下试试。

1
composer network ping --card admin@tutorial-network

业务网络默认参与者。

由于本文的目标是创建一个经过身份验证的Composer Rest服务器版本,因此我们将创建一个默认参与者,他们将能够创建其他参与者和身份。

/fabric-dev-servers/tutorial-network/models/org.example.biznet.cto文件中参与者的结构是:

1
2
3
4
5
participant SampleParticipant identified by participantId {
o String participantId
o String firstName
o String lastName
}

我们将创建一个参与者并将其绑定到一个身份,以便我们为该参与者获得一张身份证。这是我们要添加的参与者。

1
2
3
4
5
6
{ 
"$class": "org.example.biznet.SampleParticipant",
"participantId": "gangachris",
"firstName": "chris",
"lastName": "ganga"
}

在终端中定义参与者数据。

1
2
3
4
5
participantId=gangachris
firstName=chris
lastName=ganga
PARTICIPANT_CLASS=org.example.biznet.SampleParticipant
participantData="{\"\$class\": \"${PARTICIPANT_CLASS}\", \"participantId\": \"${participantId}\", \"firstName\": \"${firstName}\", \"lastName\": \"${lastName}\"}"

然后将参与者添加到网络中。

1
composer participant add -c admin@tutorial-network  -d "$participantData"

然后我们需要向该参与者发放身份,以便他们拥有身份证。

1
2
composer identity issue -c admin@tutorial-network -f gangachris.card -u $participantId -a "resource:${PARTICIPANT_CLASS}#${participantId
}" -x true

-x标志允许参与者能够发出身份。

Hyperledger Composer Rest服务器(Docker)

部署Composer Rest Server最常见的生产方式是通过Docker。 这主要是因为Hyperldger Fabric实例部署主要通过Kubernetes,Docker在容器网络生态系统中运行。 Swarm或普通的docker-compose样式就像我们现在正在做的那样。

由于我们使用的是passport-jwt,我们需要创建一个我们将在Docker容器中添加的自定义JWT文件。

custom-jwt.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// based on:
// https://github.com/hyperledger/composer/issues/2038

const passportJwt = require('passport-jwt');
const util = require('util');

function CustomJwtStrategy(options, verify) {
options.jwtFromRequest = passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken();
passportJwt.Strategy.call(this, options, verify);
}

util.inherits(CustomJwtStrategy, passportJwt.Strategy);

module.exports = {
Strategy: CustomJwtStrategy
};

我们在这里没有添加任何JWT声明,因为我们正在努力使其尽可能简单。我们从请求授权header`passportJwt.ExtractJwt.fromAuthHeaderAsBearerToken()中检索JWT作为承载token,并且库将处理剩余的身份验证。

请注意,我们将从其他地方生成JWT token,可能是将使用Composer Rest Server的客户端。对于Composer Rest Server解码token并为其提供自己的访问token,用于生成原始JWT token的JWT秘密必须用作passport-jwt配置的秘密变量,我们将在稍后看到。

Composer Rest Server还要求JWT token声明具有ID或用户名。(不知道为什么会这样)。

然后,我们将为Composer Rest Server构建一个Docker镜像。创建一个Dockerfile。

Dockerfile

1
2
3
4
5
6
7
8
9
FROM hyperledger/composer-rest-server:0.19.5

RUN npm install --production loopback-connector-mongodb passport-jwt && \
npm cache clean --force && \
ln -s node_modules .node_modules

COPY custom-jwt.js node_modules/custom-jwt.js

COPY .composer /home/composer/.composer

我们将安装passport-jwt和loopback-connector-mongodb作为镜像构建的一部分。然后我们添加我们之前创建的custom-jwt.js文件。

身份证的Composer默认目录是/home/composer/.composer。在构建镜像之前,我们可以从home/composer/.composer目录中复制现有的身份证。我们还需要更改文件权限,以便docker可以在没有EACCESS错误的情况下处理它们。

1
2
3
4
cp -rp ~/.composer .

chmod -R a+rw .composer
find .composer -type d -exec chmod a+x {} +

我们现在可以构建Docker镜像了。

1
docker build -t localhost/composer-rest-server .

请注意,我们安装了loopback-connector-mongodb作为镜像构建的一部分。这意味着我们将使用MongoDB作为存储我们经过身份验证的用户和凭据的首选数据库。因此,我们需要一个正在运行的MongoDB实例。

但是,此实例需要与当前运行的Hyperledger Fabric网络位于相同的Docker网络中。 当我们启动Hyperledger Fabric实例时,创建了一个名为composer_default的网络。为了确认这一点,我们可以运行docker network ls

1
2
3
4
5
6
docker network ls
NETWORK ID NAME DRIVER SCOPE
e7da7b74070e bridge bridge local
bdae606dc573 composer_default bridge local
f0f15a5d479b host host local
e9b986a1141d none null local

你可以看到我们有一个composer_default网络。要检查使用此网络运行的容器,我们可以运行,并检查Container属性。

1
docker network inspect composer_default

你会注意到容器是当前正在运行的容器信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"Containers": {
"0d4c964f8dc5f7cc8acb48a48d5714d6d3a9349b02992c1d60cc87f0d2d0dd2b": {
"Name": "orderer.example.com",
"EndpointID": "3a20963d2a31802e9769448f3a880d9b54369924eac27943e604e191f68c5a8b",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"1163c18322f3194a0df08d40f11cc134ac006a06221091504d7bfee7cc73c13d": {
"Name": "couchdb",
"EndpointID": "1a9f4de2748134bcf1a9c0cb4bbaf06d9e06391eee2b741db163f4165553dfa4",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
....
}

在composer_default网络中运行mongodb容器。

1
docker run -d --name mongo --network composer_default -p 27017:27017 mongo

创建一个文件envvars.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
COMPOSER_CARD=admin@tutorial-network
COMPOSER_NAMESPACES=never
COMPOSER_AUTHENTICATION=true
COMPOSER_MULTIUSER=true
COMPOSER_PROVIDERS='{
"jwt": {
"provider": "jwt",
"module": "/home/composer/node_modules/custom-jwt.js",
"secretOrKey": "gSi4WmttWuvy2ewoTGooigPwSDoxwZOy",
"authScheme": "saml",
"successRedirect": "/",
"failureRedirect":"/"
}
}'
COMPOSER_DATASOURCES='{
"db": {
"name": "db",
"connector": "mongodb",
"host": "mongo"
}
}'

CUSTOM_PROVIDERS环境变量指定我们使用jwt和自定义模块。

由于我们使用的是MongoDB,因此我们的CUSTOM_DATASOURCES环境变量也指向此。

为了使这些变量成为实际的环境变量,我们运行:

1
source envvars.txt

然后我们可以在composer_default网络中运行Docker容器。

1
2
3
4
5
6
7
8
9
10
11
12
docker run \
-d \
-e COMPOSER_CARD=${COMPOSER_CARD} \
-e COMPOSER_NAMESPACES=${COMPOSER_NAMESPACES} \
-e COMPOSER_AUTHENTICATION=${COMPOSER_AUTHENTICATION} \
-e COMPOSER_MULTIUSER=${COMPOSER_MULTIUSER} \
-e COMPOSER_PROVIDERS="${COMPOSER_PROVIDERS}" \
-e COMPOSER_DATASOURCES="${COMPOSER_DATASOURCES}" \
--name rest \
--network composer_default \
-p 3000:3000 \
localhost/composer-rest-server

为确保composer rest server 成功运行,我们检查其日志。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker logs rest
[2018-05-22 22:24:44] PM2 log: Launching in no daemon mode
[2018-05-22 22:24:44] PM2 log: Starting execution sequence in -fork mode- for app name:composer-rest-server id:0
[2018-05-22 22:24:44] PM2 log: App name:composer-rest-server id:0 online
WARNING: NODE_APP_INSTANCE value of '0' did not match any instance config file names.
WARNING: See https://github.com/lorenwest/node-config/wiki/Strict-Mode
Discovering types from business network definition ...
Discovered types from business network definition
Generating schemas for all types in business network definition ...
Generated schemas for all types in business network definition
Adding schemas for all types to Loopback ...
Added schemas for all types to Loopback
Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer

如果你看到最后一行在http://localhost:3000/explorer浏览你的REST API,我们很好。

访问http://localhost:3000/explorer并尝试在任何端点上执行GET将返回401 Unauthorized

验证Composer Rest服务器

要对Composer Rest server进行身份验证,我们需要执行以下操作:

  • 使用作为承载token传递的有效jwt token调用路径http://localhost:3000/auth/jwt/callback
  • 从cookie中检索访问token,因为这是响应返回的方式。
  • 使用检索到的token通过http://localhost:3000/api/wallet/import路由导入身份证。
  • 调用其他端点。

我们将使用Postman进行此练习,因为它是将header传递给请求的直观方式之一,因此我们不会真正做到第二,因为cookie将在后续请求中传递。

但是,如果你有一个客户端使用composer-rest服务器,则需要从返回的access_token cookie中检索token。这是一些用于检索token的示例代码,这是来自Hyperledger结构。我们可能会在另一篇文章中看到建立这样的客户端。

我根据上述加密gSi4WmttWuvy2ewoTGooigPwSDoxwZOy生成了一个JWT token,声称如下:"timestamp":time.Now().UnixNano(),"username": username。语法适用于Golang,但声明是当前时间戳,用户名是gangachris。结果token就是这个。

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE1MjcxNjI1MDQ3NDI1NjUwODcsInVzZXJuYW1lIjoiZ2FuZ2FjaHJpcyJ9.WyARsOhMSDVRjUpd-rPBI1A8-Vpz7pDS6rICXKN8W3U

请注意,此token不安全,因为它没有足够的声明和到期日。这仅用于演示目的。

接下来,我们做一个GET请求http://localhost:3000/auth/jwt/callback后结果eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE1MjcxNjI1MDQ3NDI1NjUwODcsInVzZXJuYW1lIjoiZ2FuZ2FjaHJpcyJ9.WyARsOhMSDVRjUpd-rPBI1A8-Vpz7pDS6rICXKN8W3U作为header。可以在Postman的Authorization选项卡中轻松添加此header。

请注意,我们收到了三个cookie的回复。connect.sidaccess_tokenuserId。如果你熟悉JavaScript,现在可以看到我之前共享的代码如何用于为后续请求提取access_token。

如果现在删除授权标头并调用http://localhost:3000/api/SampleAsset,则不会收到401 Unauthorized错误,但500 A business network card has not been specified

要导入card,我们向http://localhost:3000/api/Wallet/import发出POST请求,并附上我们在创建参与者时生成的身份卡和名称,在本例中为gangachris

请注意,我们会收到204 No Content回复。

要确认card已成功导入,我们将调用http://localhost:3000/api/Wallet

我们收到一个包含钱包列表的回复,以及当前使用的默认值。

在此阶段,我们成功通过身份验证,并调用http://localhost:3000/api/SampleAsset路由,没有任何错误。

注意事项

我们能够在调用http://localhost:3000/auth/jwt/callback之后调用这些请求的唯一原因是因为Postman正在使用它在此请求中获得的cookie以用于后续请求。

当你拥有自定义客户端时,这将不起作用。在这种情况下,你必须通过类似这样的代码检索访问token,然后使用header或查询参数进行后续调用,如下所示。

1
2
3
4
5
curl -v http://localhost:3000/api/system/ping?access_token=xxxxx

or

curl -v -H 'X-Access-Token: xxxxx' http://localhost:3000/api/system/ping

身份验证后的第一个请求必须是对http://localhost:3000/api/Wallet/import的POST,并传递身份验证卡和名称。调用http://localhost:3000/api/Wallet以检查默认钱包并确保它是正确的钱包是有意义的。

通过身份验证后,你可以通过发布到参与者路线来创建其他参与者。在这种情况下,它的POST http://localhost:3000/api/SampleAprticipant。然后为了向他们发一个身份,你必须向http://localhost:3000/api//system/identities/issue发出另一个帖子请求,带有相关参数,这将返回二进制响应,你必须将其保存到.card文件中。

为避免使用Postman,你可以更改我们使用passportJwt.ExtractJwt.fromUrlQueryParameter(“token”)创建的custom-jwt.js文件中的passport-jwt检索jwt token的方式;

1
2
3
4
function CustomJwtStrategy(options, verify) {
options.jwtFromRequest = passportJwt.ExtractJwt.fromUrlQueryParameter("token");
passportJwt.Strategy.call(this, options, verify);
}

一旦更改,你可以访问http://localhost:3000/auth/jwt/callback?query=<token>,然后你将返回swagger页面。

结论

Hyperledger Composer是一个很好的资源,可以帮助你启动并运行Hyperledger Fabric区块链。

你可能拥有一个现有系统,并且你希望集成Hyperledger Fabric,本文简要介绍了实现此目标的方法之一。

希望尽快学习的请访问Fabric区块链开发详解,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、通道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。

======================================================================

分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:

  • EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • ERC721以太坊通证实战,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

汇智网原创翻译,转载请标明出处。这里是原文Hyperledger Composer Rest服务器的Passport-JWT身份验证