创建本地节点¶
目录
手动创建节点¶
A node can be created manually by creating a folder that contains the following items:
The Corda JAR
- Can be downloaded from https://r3.bintray.com/corda/net/corda/corda/ (under /4.1-RC01/corda-4.1-RC01.jar)
A node configuration file entitled
node.conf
, configured as per 节点的配置A folder entitled
cordapps
containing any CorDapp JARs you want the node to loadOptional: A webserver JAR entitled
corda-webserver.jar
that will connect to the node via RPC- The (deprecated) default webserver can be downloaded from http://r3.bintray.com/corda/net/corda/corda-webserver/ (under /4.1-RC01/corda-webserver-4.1-RC01.jar)
- A Spring Boot alternative can be found here: https://github.com/corda/spring-webserver
一个节点可以通过创建一个包含下边项目的文件夹来创建:
Corda JAR
- 可以从 https://r3.bintray.com/corda/net/corda/corda/ 下载 (在 /4.1-RC01/corda-4.1-RC01.jar 下)
一个节点的配置文件为
node.conf
, 像 节点的配置 所说的那样进行配置一个名为
cordapps
文件夹包含了你想要节点加载的任何的 CorDapp JARs可选的: 一个名为
corda-webserver.jar
的 webserver JAR,可以通过 RPC 连接到节点- (已废弃的) 默认的 webserver 可以从 http://r3.bintray.com/corda/net/corda/corda-webserver/ 下载(在 /4.1-RC01/corda-webserver-4.1-RC01.jar 下)
- 一个 Spring Boot 能够在这里找到: https://github.com/corda/spring-webserver
The remaining files and folders described in 节点文件夹结构 will be generated at runtime.
在 节点文件夹结构 中描述的剩余的文件和文件夹将会在运行时生成。
Cordform 任务¶
Corda provides a gradle plugin called Cordform
that allows you to automatically generate and configure a set of
nodes for testing and demos. Here is an example Cordform
task called deployNodes
that creates three nodes, defined
in the Kotlin CorDapp Template:
Corda 提供了一个叫做 Cordform
的 gradle plugin,它允许你自动地生成和配置一套节点的信息用于测试和 demos。下边是一个叫做 deployNodes
的 Cordform
任务,它在 Kotlin CorDapp Template 项目中创建了 3 个节点:
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
directory "./build/nodes"
nodeDefaults {
cordapps = [
"net.corda:corda-finance-contracts:$corda_release_version",
"net.corda:corda-finance-workflows:$corda_release_version",
"net.corda:corda-confidential-identities:$corda_release_version"
]
}
node {
name "O=Notary,L=London,C=GB"
// The notary will offer a validating notary service.
notary = [validating : true]
p2pPort 10002
rpcSettings {
port 10003
adminPort 10023
}
// No webport property, so no webserver will be created.
h2Port 10004
// Starts an internal SSH server providing a management shell on the node.
sshdPort 2223
extraConfig = [
// Setting the JMX reporter type.
jmxReporterType: 'JOLOKIA',
// Setting the H2 address.
h2Settings: [ address: 'localhost:10030' ]
]
}
node {
name "O=PartyA,L=London,C=GB"
p2pPort 10005
rpcSettings {
port 10006
adminPort 10026
}
webPort 10007
h2Port 10008
// Grants user1 all RPC permissions.
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
}
node {
name "O=PartyB,L=New York,C=US"
p2pPort 10009
rpcSettings {
port 10010
adminPort 10030
}
webPort 10011
h2Port 10012
// Grants user1 the ability to start the MyFlow flow.
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["StartFlow.net.corda.flows.MyFlow"]]]
}
}
Running this task will create three nodes in the build/nodes
folder:
- A
Notary
node that:- Offers a validating notary service
- Will not have a webserver (since
webPort
is not defined) - Is running the
corda-finance
CorDapp
PartyA
andPartyB
nodes that:- Are not offering any services
- Will have a webserver (since
webPort
is defined) - Are running the
corda-finance
CorDapp - Have an RPC user,
user1
, that can be used to log into the node via RPC
运行这个任务会在 build/nodes
文件夹下创建 3 个节点:
- 一个
Notary
节点:- 提供一个 validating notary 服务
- 不会有 webserver(因为
webPort
没有定义) - 会运行 corda-finance CorDapp
PartyA
和PartyB
节点:- 不提供任何服务
- 会有一个 webserver(因为
webPort
被定义了) - 运行
corda-finance
CorDapp - 有一个 RPC 用户 -
user1
,可以通过 RPC 登陆到节点
Additionally, all three nodes will include any CorDapps defined in the project’s source folders, even though these
CorDapps are not listed in each node’s cordapps
entry. This means that running the deployNodes
task from the
template CorDapp, for example, would automatically build and add the template CorDapp to each node.
另外,所有的三个节点都会包含任何在项目的 source 文件夹中定义的任何 CorDapp,即使这些 CorDapps 没有被列在每个节点的 cordapps
entry。这就意味着在 template CorDapp 中运行这个 deployNodes
任务会自动 build 并将这个 template CorDapp 添加到每个节点中。
You can extend deployNodes
to generate additional nodes.
你可以扩展这个 deployNodes
来生成更多的节点。
警告
When adding nodes, make sure that there are no port clashes!
警告
当添加节点的时候,要确保没有端口冲突!
To extend node configuration beyond the properties defined in the deployNodes
task use the configFile
property with the path (relative or absolute) set to an additional configuration file.
This file should follow the standard 节点的配置 format, as per node.conf. The properties from this file will be appended to the generated node configuration. Note, if you add a property already created by the ‘deployNodes’ task, both properties will be present in the file.
The path to the file can also be added while running the Gradle task via the -PconfigFile
command line option. However, the same file will be applied to all nodes.
Following the previous example PartyB
node will have additional configuration options added from a file none-b.conf
:
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
[...]
node {
name "O=PartyB,L=New York,C=US"
[...]
// Grants user1 the ability to start the MyFlow flow.
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["StartFlow.net.corda.flows.MyFlow"]]]
configFile = "samples/trader-demo/src/main/resources/node-b.conf"
}
}
Cordform parameter drivers of the node entry lists paths of the files to be copied to the ./drivers subdirectory of the node. To copy the same file to all nodes ext.drivers can be defined in the top level and reused for each node via drivers=ext.drivers`.
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
ext.drivers = ['lib/my_common_jar.jar']
[...]
node {
name "O=PartyB,L=New York,C=US"
[...]
drivers = ext.drivers + ['lib/my_specific_jar.jar']
}
}
Signing Cordapp JARs¶
The default behaviour of Cordform is to deploy CorDapp JARs “as built”:
- prior to Corda 4 all CorDapp JARs were unsigned.
- as of Corda 4, CorDapp JARs created by the Gradle cordapp plugin are signed by a Corda development certificate by default.
The Cordform signing
entry can be used to override and customise the signing of CorDapp JARs.
Signing the CorDapp enables its contract classes to use signature constraints instead of other types of the constraints API: 合约约束.
The sign task may use an external keystore, or create a new one.
The signing
entry may contain the following parameters:
enabled
the control flag to enable signing process, by default is set tofalse
, set totrue
to enable signingall
if set totrue
(by default) all CorDapps inside cordapp subdirectory will be signed, otherwise iffalse
then only the generated Cordapp will be signedoptions
any relevant parameters of SignJar ANT task and GenKey ANT task, by default the JAR file is signed by Corda development key, the external keystore can be specified, the minimal list of required options is shown below, for other options referer to SignJar task:keystore
the path to the keystore file, by default cordadevcakeys.jks keystore is shipped with the pluginalias
the alias to sign under, the default value is cordaintermediatecastorepass
the keystore password, the default value is cordacadevpasskeypass
the private key password if it’s different than the password for the keystore, the default value is cordacadevkeypassstoretype
the keystore type, the default value is JKSdname
the distinguished name for entity, the option is used whengenerateKeystore true
onlykeyalg
the method to use when generating name-value pair, the value defaults to RSA as Corda doesn’t support DSA, the option is used whengenerateKeystore true
only
generateKeystore
the flag to generate a keystore, it is set tofalse
by default. If set totrue
then ad hock keystore is created and its key isused instead of the default Corda development key or any external key. The sameoptions
to specify an external keystore are used to define the newly created keystore. Additionallydname
andkeyalg
are required. Other options are described in GenKey task. If the existing keystore is already present the task will reuse it, however if the file is inside the build directory, then it will be deleted when Gradle clean task is run.
The example below shows the minimal set of options
needed to create a dummy keystore:
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
signing {
enabled true
generateKeystore true
all false
options {
keystore "./build/nodes/jarSignKeystore.p12"
alias "cordapp-signer"
storepass "secret1!"
storetype "PKCS12"
dname "OU=Dummy Cordapp Distributor, O=Corda, L=London, C=GB"
keyalg "RSA"
}
}
//...
Contracts classes from signed CorDapp JARs will be checked by signature constraints by default.
You can force them to be checked by zone constraints by adding contract class names to includeWhitelist
entry,
the list will generate include_whitelist.txt file used internally by Network Bootstrapper tool.
Refer to API: 合约约束 to understand implication of different constraint types before adding includeWhitelist
to deployNodes
task.
The snippet below configures contracts classes from Finance CorDapp to be verified using zone constraints instead of signature constraints:
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
includeWhitelist = [ "net.corda.finance.contracts.asset.Cash", "net.corda.finance.contracts.asset.CommercialPaper" ]
//...
Specifying a custom webserver¶
By default, any node listing a web port will use the default development webserver, which is not production-ready. You
can use your own webserver JAR instead by using the webserverJar
argument in a Cordform
node
configuration
block:
node {
name "O=PartyA,L=New York,C=US"
webPort 10005
webserverJar "lib/my_webserver.jar"
}
The webserver JAR will be copied into the node’s build
folder with the name corda-webserver.jar
.
警告
This is an experimental feature. There is currently no support for reading the webserver’s port from the
node’s node.conf
file.
The Dockerform task¶
The Dockerform
is a sister task of Cordform
that provides an extra file allowing you to easily spin up
nodes using docker-compose
. It supports the following configuration options for each node:
name
notary
cordapps
rpcUsers
useTestClock
There is no need to specify the nodes’ ports, as every node has a separate container, so no ports conflict will occur.
Every node will expose port 10003
for RPC connections.
The nodes’ webservers will not be started. Instead, you should interact with each node via its shell over SSH
(see the node configuration options). You have to enable the shell by adding the
following line to each node’s node.conf
file:
sshd { port = 2222 }
Where 2222
is the port you want to open to SSH into the shell.
Below you can find the example task from the IRS Demo included in the samples directory of main Corda GitHub repository:
def rpcUsersList = [
['username' : "user",
'password' : "password",
'permissions' : [
"StartFlow.net.corda.irs.flows.AutoOfferFlow\$Requester",
"StartFlow.net.corda.irs.flows.UpdateBusinessDayFlow\$Broadcast",
"StartFlow.net.corda.irs.api.NodeInterestRates\$UploadFixesFlow",
"InvokeRpc.vaultQueryBy",
"InvokeRpc.networkMapSnapshot",
"InvokeRpc.currentNodeTime",
"InvokeRpc.wellKnownPartyFromX500Name"
]]
]
// (...)
task deployNodes(type: net.corda.plugins.Dockerform, dependsOn: ['jar']) {
nodeDefaults {
cordapps = [
"net.corda:corda-finance-contracts:$corda_release_version",
"net.corda:corda-finance-workflows:$corda_release_version",
"net.corda:corda-confidential-identities:$corda_release_version"
]
}
node {
name "O=Notary Service,L=Zurich,C=CH"
notary = [validating : true]
rpcUsers = rpcUsersList
useTestClock true
}
node {
name "O=Bank A,L=London,C=GB"
rpcUsers = rpcUsersList
useTestClock true
}
node {
name "O=Bank B,L=New York,C=US"
rpcUsers = rpcUsersList
useTestClock true
}
node {
name "O=Regulator,L=Moscow,C=RU"
rpcUsers = rpcUsersList
useTestClock true
}
}
Running the Cordform/Dockerform tasks¶
To create the nodes defined in our deployNodes
task, run the following command in a terminal window from the root
of the project where the deployNodes
task is defined:
- Linux/macOS:
./gradlew deployNodes
- Windows:
gradlew.bat deployNodes
This will create the nodes in the build/nodes
folder. There will be a node folder generated for each node defined
in the deployNodes
task, plus a runnodes
shell script (or batch file on Windows) to run all the nodes at once
for testing and development purposes. If you make any changes to your CorDapp source or deployNodes
task, you will
need to re-run the task to see the changes take effect.
If the task is a Dockerform
task, running the task will also create an additional Dockerfile
in each node
directory, and a docker-compose.yml
file in the build/nodes
directory.
You can now run the nodes by following the instructions in Running a node.