| @@ -71,6 +71,12 @@ public interface DataCodes { | |||
| public static final int PRIVILEGE_SET = 0x410; | |||
| public static final int ROLE_SET = 0x411; | |||
| public static final int SECURITY_INIT_SETTING = 0x420; | |||
| public static final int SECURITY_ROLE_INIT_SETTING = 0x421; | |||
| public static final int SECURITY_USER_AUTH_INIT_SETTING = 0x422; | |||
| // contract types of metadata; | |||
| public static final int METADATA = 0x600; | |||
| @@ -86,10 +92,6 @@ public interface DataCodes { | |||
| public static final int METADATA_CONSENSUS_PARTICIPANT = 0x621; | |||
| public static final int METADATA_SECURITY_INIT_SETTING = 0x622; | |||
| public static final int METADATA_ROLE_INIT_SETTING = 0x623; | |||
| // public static final int METADATA_CONSENSUS_NODE = 0x630; | |||
| // | |||
| // public static final int METADATA_CONSENSUS_SETTING = 0x631; | |||
| @@ -11,6 +11,7 @@ import com.jd.blockchain.ledger.LedgerInitException; | |||
| import com.jd.blockchain.ledger.LedgerInitSetting; | |||
| import com.jd.blockchain.ledger.Operation; | |||
| import com.jd.blockchain.ledger.ParticipantNode; | |||
| import com.jd.blockchain.ledger.SecurityInitSettings; | |||
| import com.jd.blockchain.ledger.TransactionBuilder; | |||
| import com.jd.blockchain.ledger.TransactionContent; | |||
| import com.jd.blockchain.ledger.TransactionRequest; | |||
| @@ -60,8 +61,16 @@ public class LedgerInitializer { | |||
| return initTxContent; | |||
| } | |||
| private static SecurityInitSettings createDefaultSecurityInitSettings() { | |||
| throw new IllegalStateException("Not implemented!"); | |||
| } | |||
| public static LedgerInitializer create(LedgerInitSetting initSetting) { | |||
| // 生成初始化交易,并签署许可; | |||
| return create(initSetting, createDefaultSecurityInitSettings()); | |||
| } | |||
| public static LedgerInitializer create(LedgerInitSetting initSetting, SecurityInitSettings securityInitSettings) { | |||
| // 生成初始化交易; | |||
| TransactionBuilder initTxBuilder = new TxBuilder(null);// 账本初始化交易的账本 hash 为 null; | |||
| initTxBuilder.ledgers().create(initSetting); | |||
| for (ParticipantNode p : initSetting.getConsensusParticipants()) { | |||
| @@ -71,6 +80,7 @@ public class LedgerInitializer { | |||
| } | |||
| // 账本初始化配置声明的创建时间来初始化交易时间戳;注:不能用本地时间,因为共识节点之间的本地时间系统不一致; | |||
| TransactionContent initTxContent = initTxBuilder.prepareContent(initSetting.getCreatedTime()); | |||
| return new LedgerInitializer(initSetting, initTxContent); | |||
| } | |||
| @@ -11,7 +11,7 @@ import com.jd.blockchain.consts.DataCodes; | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| @DataContract(code = DataCodes.METADATA_ROLE_INIT_SETTING) | |||
| @DataContract(code = DataCodes.SECURITY_ROLE_INIT_SETTING) | |||
| public interface RoleInitSettings { | |||
| /** | |||
| @@ -25,4 +25,10 @@ public class SecurityInitData implements SecurityInitSettings { | |||
| RoleInitData roleInitData = new RoleInitData(roleName, ledgerPermissions, transactionPermissions); | |||
| roles.add(roleInitData); | |||
| } | |||
| @Override | |||
| public UserAuthInitSettings[] getUserAuthorizations() { | |||
| // TODO Auto-generated method stub | |||
| return null; | |||
| } | |||
| } | |||
| @@ -10,7 +10,7 @@ import com.jd.blockchain.consts.DataCodes; | |||
| * @author huanghaiquan | |||
| * | |||
| */ | |||
| @DataContract(code = DataCodes.METADATA_SECURITY_INIT_SETTING) | |||
| @DataContract(code = DataCodes.SECURITY_INIT_SETTING) | |||
| public interface SecurityInitSettings { | |||
| /** | |||
| @@ -20,5 +20,8 @@ public interface SecurityInitSettings { | |||
| */ | |||
| @DataField(order = 0, refContract = true, list = true) | |||
| RoleInitSettings[] getRoles(); | |||
| @DataField(order = 1, refContract = true, list = true) | |||
| UserAuthInitSettings[] getUserAuthorizations(); | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| package com.jd.blockchain.ledger; | |||
| import com.jd.blockchain.binaryproto.DataContract; | |||
| import com.jd.blockchain.binaryproto.DataField; | |||
| import com.jd.blockchain.binaryproto.PrimitiveType; | |||
| import com.jd.blockchain.consts.DataCodes; | |||
| import com.jd.blockchain.utils.Bytes; | |||
| @DataContract(code = DataCodes.SECURITY_USER_AUTH_INIT_SETTING) | |||
| public interface UserAuthInitSettings { | |||
| @DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||
| Bytes getUserAddress(); | |||
| @DataField(order = 2, primitiveType = PrimitiveType.TEXT, list = true) | |||
| String[] getRoles(); | |||
| @DataField(order = 3, refEnum = true) | |||
| RolesPolicy getPolicy(); | |||
| } | |||
| @@ -1,8 +1,7 @@ | |||
| package test.com.jd.blockchain.tools.initializer; | |||
| package test.com.jd.blockchain.ledger; | |||
| import static org.junit.Assert.assertArrayEquals; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNull; | |||
| import static org.junit.Assert.assertTrue; | |||
| import java.io.IOException; | |||
| @@ -18,18 +17,41 @@ import java.util.TimeZone; | |||
| import org.junit.Test; | |||
| import org.springframework.core.io.ClassPathResource; | |||
| import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
| import com.jd.blockchain.crypto.AddressEncoding; | |||
| import com.jd.blockchain.crypto.KeyGenUtils; | |||
| import com.jd.blockchain.crypto.PubKey; | |||
| import com.jd.blockchain.ledger.LedgerInitOperation; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ConsensusParticipantConfig; | |||
| import com.jd.blockchain.ledger.LedgerPermission; | |||
| import com.jd.blockchain.ledger.RoleInitData; | |||
| import com.jd.blockchain.ledger.RolesPolicy; | |||
| import com.jd.blockchain.ledger.TransactionPermission; | |||
| import com.jd.blockchain.ledger.LedgerInitProperties.ConsensusParticipantConfig; | |||
| import com.jd.blockchain.ledger.UserRegisterOperation; | |||
| import com.jd.blockchain.utils.codec.HexUtils; | |||
| public class LedgerInitPropertiesTest { | |||
| static { | |||
| DataContractRegistry.register(LedgerInitOperation.class); | |||
| DataContractRegistry.register(UserRegisterOperation.class); | |||
| } | |||
| public static final String PASSWORD = "abc"; | |||
| public static final String[] PUB_KEYS = { "3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9", | |||
| "3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX", | |||
| "3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x", | |||
| "3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk" }; | |||
| public static final String[] PRIV_KEYS = { | |||
| "177gjzHTznYdPgWqZrH43W3yp37onm74wYXT4v9FukpCHBrhRysBBZh7Pzdo5AMRyQGJD7x", | |||
| "177gju9p5zrNdHJVEQnEEKF4ZjDDYmAXyfG84V5RPGVc5xFfmtwnHA7j51nyNLUFffzz5UT", | |||
| "177gjtwLgmSx5v1hFb46ijh7L9kdbKUpJYqdKVf9afiEmAuLgo8Rck9yu5UuUcHknWJuWaF", | |||
| "177gk1pudweTq5zgJTh8y3ENCTwtSFsKyX7YnpuKPo7rKgCkCBXVXh5z2syaTCPEMbuWRns" }; | |||
| private static String expectedCreatedTimeStr = "2019-08-01 14:26:58.069+0800"; | |||
| @@ -166,7 +188,7 @@ public class LedgerInitPropertiesTest { | |||
| @Test | |||
| public void testPubKeyAddress() { | |||
| String[] pubKeys = TestConsts.PUB_KEYS; | |||
| String[] pubKeys = PUB_KEYS; | |||
| int index = 0; | |||
| for (String pubKeyStr : pubKeys) { | |||
| System.out.println("[" + index + "][配置] = " + pubKeyStr); | |||
| @@ -0,0 +1,144 @@ | |||
| # Copyright (c) 2007-2013 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags | |||
| # | |||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||
| # you may not use this file except in compliance with the License. | |||
| # You may obtain a copy of the License at | |||
| # | |||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||
| # | |||
| # Unless required by applicable law or agreed to in writing, software | |||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| # See the License for the specific language governing permissions and | |||
| # limitations under the License. | |||
| ############################################ | |||
| ####### Communication Configurations ####### | |||
| ############################################ | |||
| #HMAC algorithm used to authenticate messages between processes (HmacMD5 is the default value) | |||
| #This parameter is not currently being used being used | |||
| #system.authentication.hmacAlgorithm = HmacSHA1 | |||
| #Specify if the communication system should use a thread to send data (true or false) | |||
| system.communication.useSenderThread = true | |||
| #Force all processes to use the same public/private keys pair and secret key. This is useful when deploying experiments | |||
| #and benchmarks, but must not be used in production systems. | |||
| system.communication.defaultkeys = true | |||
| ############################################ | |||
| ### Replication Algorithm Configurations ### | |||
| ############################################ | |||
| #Timeout to asking for a client request | |||
| system.totalordermulticast.timeout = 2000 | |||
| #Maximum batch size (in number of messages) | |||
| system.totalordermulticast.maxbatchsize = 400 | |||
| #Number of nonces (for non-determinism actions) generated | |||
| system.totalordermulticast.nonces = 10 | |||
| #if verification of leader-generated timestamps are increasing | |||
| #it can only be used on systems in which the network clocks | |||
| #are synchronized | |||
| system.totalordermulticast.verifyTimestamps = false | |||
| #Quantity of messages that can be stored in the receive queue of the communication system | |||
| system.communication.inQueueSize = 500000 | |||
| # Quantity of messages that can be stored in the send queue of each replica | |||
| system.communication.outQueueSize = 500000 | |||
| #Set to 1 if SMaRt should use signatures, set to 0 if otherwise | |||
| system.communication.useSignatures = 0 | |||
| #Set to 1 if SMaRt should use MAC's, set to 0 if otherwise | |||
| system.communication.useMACs = 1 | |||
| #Set to 1 if SMaRt should use the standard output to display debug messages, set to 0 if otherwise | |||
| system.debug = 0 | |||
| #Print information about the replica when it is shutdown | |||
| system.shutdownhook = true | |||
| ############################################ | |||
| ###### State Transfer Configurations ####### | |||
| ############################################ | |||
| #Activate the state transfer protocol ('true' to activate, 'false' to de-activate) | |||
| system.totalordermulticast.state_transfer = true | |||
| #Maximum ahead-of-time message not discarded | |||
| system.totalordermulticast.highMark = 10000 | |||
| #Maximum ahead-of-time message not discarded when the replica is still on EID 0 (after which the state transfer is triggered) | |||
| system.totalordermulticast.revival_highMark = 10 | |||
| #Number of ahead-of-time messages necessary to trigger the state transfer after a request timeout occurs | |||
| system.totalordermulticast.timeout_highMark = 200 | |||
| ############################################ | |||
| ###### Log and Checkpoint Configurations ### | |||
| ############################################ | |||
| system.totalordermulticast.log = true | |||
| system.totalordermulticast.log_parallel = false | |||
| system.totalordermulticast.log_to_disk = false | |||
| system.totalordermulticast.sync_log = false | |||
| #Period at which BFT-SMaRt requests the state to the application (for the state transfer state protocol) | |||
| system.totalordermulticast.checkpoint_period = 1000 | |||
| system.totalordermulticast.global_checkpoint_period = 120000 | |||
| system.totalordermulticast.checkpoint_to_disk = false | |||
| system.totalordermulticast.sync_ckp = false | |||
| ############################################ | |||
| ###### Reconfiguration Configurations ###### | |||
| ############################################ | |||
| #The ID of the trust third party (TTP) | |||
| system.ttp.id = 7002 | |||
| #This sets if the system will function in Byzantine or crash-only mode. Set to "true" to support Byzantine faults | |||
| system.bft = true | |||
| #Custom View Storage; | |||
| #view.storage.handler=bftsmart.reconfiguration.views.DefaultViewStorage | |||
| #Number of servers in the group | |||
| system.servers.num = 4 | |||
| #Maximum number of faulty replicas | |||
| system.servers.f = 1 | |||
| #Replicas ID for the initial view, separated by a comma. | |||
| # The number of replicas in this parameter should be equal to that specified in 'system.servers.num' | |||
| system.initial.view = 0,1,2,3 | |||
| #Configuration of all node servers; | |||
| #PubKey of node server with specified ID, with base58 encoding. | |||
| system.server.0.pubkey= | |||
| system.server.0.network.host=127.0.0.1 | |||
| system.server.0.network.port=8900 | |||
| system.server.0.network.secure=false | |||
| system.server.1.pubkey= | |||
| system.server.1.network.host=127.0.0.1 | |||
| system.server.1.network.port=8910 | |||
| system.server.1.network.secure=false | |||
| system.server.2.pubkey= | |||
| system.server.2.network.host=127.0.0.1 | |||
| system.server.2.network.port=8920 | |||
| system.server.2.network.secure=false | |||
| system.server.3.pubkey= | |||
| system.server.3.network.host=127.0.0.1 | |||
| system.server.3.network.port=8920 | |||
| system.server.3.network.secure=false | |||
| @@ -0,0 +1 @@ | |||
| 3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x | |||
| @@ -0,0 +1,158 @@ | |||
| #账本的种子;一段16进制字符,最长可以包含64个字符;可以用字符“-”分隔,以便更容易读取; | |||
| ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe | |||
| #账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途; | |||
| ledger.name=test | |||
| #声明账本的创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区 | |||
| created-time=2019-08-01 14:26:58.069+0800 | |||
| #----------------------------------------------- | |||
| # 初始的角色名称列表;可选项; | |||
| # 角色名称不区分大小写,最长不超过20个字符;多个角色名称之间用半角的逗点“,”分隔; | |||
| # 系统会预置一个默认角色“DEFAULT”,所有未指定角色的用户都以赋予该角色的权限;若初始化时未配置默认角色的权限,则为默认角色分配所有权限; | |||
| # | |||
| # 注:如果声明了角色,但未声明角色对应的权限清单,这会忽略该角色的初始化; | |||
| # | |||
| security.roles=DEFAULT, ADMIN, MANAGER, GUEST | |||
| # 赋予角色的账本权限清单;可选项; | |||
| # 可选的权限如下; | |||
| # AUTHORIZE_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, | |||
| # REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, | |||
| # SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT, | |||
| # APPROVE_TX, CONSENSUS_TX | |||
| # 多项权限之间用逗点“,”分隔; | |||
| # | |||
| security.role.DEFAULT.ledger-privileges=REGISTER_USER, REGISTER_DATA_ACCOUNT | |||
| # 赋予角色的交易权限清单;可选项; | |||
| # 可选的权限如下; | |||
| # DIRECT_OPERATION, CONTRACT_OPERATION | |||
| # 多项权限之间用逗点“,”分隔; | |||
| # | |||
| security.role.DEFAULT.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION | |||
| # 其它角色的配置示例; | |||
| # 系统管理员角色:只能操作全局性的参数配置和用户注册,只能执行直接操作指令; | |||
| security.role.ADMIN.ledger-privileges=CONFIGURE_ROLES, AUTHORIZE_USER_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, REGISTER_USER | |||
| security.role.ADMIN.tx-privileges=DIRECT_OPERATION | |||
| # 业务主管角色:只能够执行账本数据相关的操作,包括注册用户、注册数据账户、注册合约、升级合约、写入数据等;能够执行直接操作指令和调用合约; | |||
| security.role.MANAGER.ledger-privileges=CONFIGURE_ROLES, AUTHORIZE_USER_ROLES, REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT, | |||
| security.role.MANAGER.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION | |||
| # 访客角色:不具备任何的账本权限,只有数据读取的操作;也只能够通过调用合约来读取数据; | |||
| security.role.GUEST.ledger-privileges= | |||
| security.role.GUEST.tx-privileges=CONTRACT_OPERATION | |||
| #----------------------------------------------- | |||
| #共识服务提供者;必须; | |||
| consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
| #共识服务的参数配置;必须; | |||
| consensus.conf=classpath:bftsmart.config | |||
| #密码服务提供者列表,以英文逗点“,”分隔;必须; | |||
| crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ | |||
| com.jd.blockchain.crypto.service.sm.SMCryptoService | |||
| #参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
| cons_parti.count=4 | |||
| #第0个参与方的名称; | |||
| cons_parti.0.name=jd.com | |||
| #第0个参与方的公钥文件路径; | |||
| cons_parti.0.pubkey-path=keys/jd-com.pub | |||
| #第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 | |||
| #第0个参与方的角色清单;可选项; | |||
| cons_parti.0.roles=ADMIN, MANAGER | |||
| #第0个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项; | |||
| cons_parti.0.roles-policy=UNION | |||
| #第0个参与方的共识服务的主机地址; | |||
| cons_parti.0.consensus.host=127.0.0.1 | |||
| #第0个参与方的共识服务的端口; | |||
| cons_parti.0.consensus.port=8900 | |||
| #第0个参与方的共识服务是否开启安全连接; | |||
| cons_parti.0.consensus.secure=true | |||
| #第0个参与方的账本初始服务的主机; | |||
| cons_parti.0.initializer.host=127.0.0.1 | |||
| #第0个参与方的账本初始服务的端口; | |||
| cons_parti.0.initializer.port=8800 | |||
| #第0个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.0.initializer.secure=true | |||
| #第1个参与方的名称; | |||
| cons_parti.1.name=at.com | |||
| #第1个参与方的公钥文件路径; | |||
| cons_parti.1.pubkey-path=keys/at-com.pub | |||
| #第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX | |||
| #第1个参与方的角色清单;可选项; | |||
| cons_parti.1.roles=MANAGER | |||
| #第1个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项; | |||
| cons_parti.1.roles-policy=UNION | |||
| #第1个参与方的共识服务的主机地址; | |||
| cons_parti.1.consensus.host=127.0.0.1 | |||
| #第1个参与方的共识服务的端口; | |||
| cons_parti.1.consensus.port=8910 | |||
| #第1个参与方的共识服务是否开启安全连接; | |||
| cons_parti.1.consensus.secure=false | |||
| #第1个参与方的账本初始服务的主机; | |||
| cons_parti.1.initializer.host=127.0.0.1 | |||
| #第1个参与方的账本初始服务的端口; | |||
| cons_parti.1.initializer.port=8810 | |||
| #第1个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.1.initializer.secure=false | |||
| #第2个参与方的名称; | |||
| cons_parti.2.name=bt.com | |||
| #第2个参与方的公钥文件路径; | |||
| cons_parti.2.pubkey-path=classpath:keys/parti2.pub | |||
| #第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.2.pubkey= | |||
| #第2个参与方的角色清单;可选项; | |||
| cons_parti.2.roles=MANAGER | |||
| #第2个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项; | |||
| cons_parti.2.roles-policy=UNION | |||
| #第2个参与方的共识服务的主机地址; | |||
| cons_parti.2.consensus.host=127.0.0.1 | |||
| #第2个参与方的共识服务的端口; | |||
| cons_parti.2.consensus.port=8920 | |||
| #第2个参与方的共识服务是否开启安全连接; | |||
| cons_parti.2.consensus.secure=false | |||
| #第2个参与方的账本初始服务的主机; | |||
| cons_parti.2.initializer.host=127.0.0.1 | |||
| #第2个参与方的账本初始服务的端口; | |||
| cons_parti.2.initializer.port=8820 | |||
| #第2个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.2.initializer.secure=true | |||
| #第3个参与方的名称; | |||
| cons_parti.3.name=xt.com | |||
| #第3个参与方的公钥文件路径; | |||
| cons_parti.3.pubkey-path=keys/xt-com.pub | |||
| #第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
| cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk | |||
| #第3个参与方的角色清单;可选项; | |||
| cons_parti.3.roles=GUEST | |||
| #第3个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项; | |||
| cons_parti.3.roles-policy=INTERSECT | |||
| #第3个参与方的共识服务的主机地址; | |||
| cons_parti.3.consensus.host=127.0.0.1 | |||
| #第3个参与方的共识服务的端口; | |||
| cons_parti.3.consensus.port=8930 | |||
| #第3个参与方的共识服务是否开启安全连接; | |||
| cons_parti.3.consensus.secure=false | |||
| #第3个参与方的账本初始服务的主机; | |||
| cons_parti.3.initializer.host=127.0.0.1 | |||
| #第3个参与方的账本初始服务的端口; | |||
| cons_parti.3.initializer.port=8830 | |||
| #第3个参与方的账本初始服务是否开启安全连接; | |||
| cons_parti.3.initializer.secure=false | |||