@@ -67,6 +67,7 @@ public interface DataCodes { | |||
// contract types of metadata; | |||
public static final int METADATA = 0x600; | |||
public static final int METADATA_V2 = 0x601; | |||
public static final int METADATA_INIT_SETTING = 0x610; | |||
@@ -25,6 +25,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
static { | |||
DataContractRegistry.register(LedgerMetadata.class); | |||
DataContractRegistry.register(LedgerMetadata_V2.class); | |||
} | |||
private static Logger LOGGER = LoggerFactory.getLogger(LedgerAdminAccount.class); | |||
@@ -40,7 +41,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
private final Bytes rolePrivilegePrefix; | |||
private final Bytes userRolePrefix; | |||
private LedgerMetadata origMetadata; | |||
private LedgerMetadata_V2 origMetadata; | |||
private LedgerMetadataImpl metadata; | |||
@@ -225,7 +226,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
return BinaryProtocol.encode(setting, LedgerSettings.class); | |||
} | |||
private LedgerMetadata loadAndVerifyMetadata(HashDigest adminAccountHash) { | |||
private LedgerMetadata_V2 loadAndVerifyMetadata(HashDigest adminAccountHash) { | |||
Bytes key = encodeMetadataKey(adminAccountHash); | |||
byte[] bytes = storage.get(key); | |||
HashFunction hashFunc = Crypto.getHashFunction(adminAccountHash.getAlgorithm()); | |||
@@ -253,7 +254,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
* @see com.jd.blockchain.ledger.core.LedgerAdministration#getMetadata() | |||
*/ | |||
@Override | |||
public LedgerMetadata getMetadata() { | |||
public LedgerMetadata_V2 getMetadata() { | |||
return metadata; | |||
} | |||
@@ -325,7 +326,7 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
@Override | |||
public boolean isUpdated() { | |||
return updated || participants.isUpdated(); | |||
return updated || participants.isUpdated() || rolePrivileges.isUpdated() || userRoles.isUpdated(); | |||
} | |||
@Override | |||
@@ -392,12 +393,12 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
updated = false; | |||
} | |||
private LedgerMetadata deserializeMetadata(byte[] bytes) { | |||
private LedgerMetadata_V2 deserializeMetadata(byte[] bytes) { | |||
return BinaryProtocol.decode(bytes); | |||
} | |||
private byte[] serializeMetadata(LedgerMetadataImpl config) { | |||
return BinaryProtocol.encode(config, LedgerMetadata.class); | |||
return BinaryProtocol.encode(config, LedgerMetadata_V2.class); | |||
} | |||
@Override | |||
@@ -426,11 +427,12 @@ public class LedgerAdminAccount implements Transactional, LedgerAdminInfo { | |||
public LedgerMetadataImpl() { | |||
} | |||
public LedgerMetadataImpl(LedgerMetadata metadata) { | |||
public LedgerMetadataImpl(LedgerMetadata_V2 metadata) { | |||
this.seed = metadata.getSeed(); | |||
// this.setting = metadata.getSetting(); | |||
this.participantsHash = metadata.getParticipantsHash(); | |||
this.settingsHash = metadata.getSettingsHash(); | |||
this.rolePrivilegesHash = metadata.getRolePrivilegesHash(); | |||
this.userRolesHash = metadata.getUserRolesHash(); | |||
} | |||
@Override | |||
@@ -15,10 +15,10 @@ import com.jd.blockchain.consts.DataCodes; | |||
public enum LedgerPermission { | |||
/** | |||
* 设置角色权限;<br> | |||
* 授权角色权限;<br> | |||
* 包括:创建角色、设置角色的权限代码、分配用户角色; | |||
*/ | |||
SET_ROLE_PERMISSION((byte) 0x01), | |||
AUTHORIZE_ROLES((byte) 0x01), | |||
/** | |||
* 设置共识协议;<br> | |||
@@ -8,6 +8,7 @@ import com.jd.blockchain.storage.service.ExPolicyKVStorage.ExPolicy; | |||
import com.jd.blockchain.storage.service.VersioningKVEntry; | |||
import com.jd.blockchain.storage.service.VersioningKVStorage; | |||
import com.jd.blockchain.storage.service.utils.BufferedKVStorage; | |||
import com.jd.blockchain.storage.service.utils.VersioningKVData; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.Transactional; | |||
import com.jd.blockchain.utils.io.BytesUtils; | |||
@@ -62,12 +63,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||
/** | |||
* 创建一个新的 MerkleDataSet; | |||
* | |||
* @param setting | |||
* 密码设置; | |||
* @param exPolicyStorage | |||
* 默克尔树的存储; | |||
* @param versioningStorage | |||
* 数据的存储; | |||
* @param setting 密码设置; | |||
* @param exPolicyStorage 默克尔树的存储; | |||
* @param versioningStorage 数据的存储; | |||
*/ | |||
public MerkleDataSet(CryptoSetting setting, String keyPrefix, ExPolicyKVStorage exPolicyStorage, | |||
VersioningKVStorage versioningStorage) { | |||
@@ -149,7 +147,7 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||
} | |||
return values; | |||
} | |||
public VersioningKVEntry[] getLatestDataEntries(int fromIndex, int count) { | |||
if (count > LedgerConsts.MAX_LIST_COUNT) { | |||
throw new IllegalArgumentException("Count exceed the upper limit[" + LedgerConsts.MAX_LIST_COUNT + "]!"); | |||
@@ -158,16 +156,19 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||
throw new IllegalArgumentException("Index out of bound!"); | |||
} | |||
VersioningKVEntry[] values = new VersioningKVEntry[count]; | |||
byte[] bytesValue; | |||
for (int i = 0; i < count; i++) { | |||
MerkleDataNode dataNode = merkleTree.getData(fromIndex + i); | |||
Bytes dataKey = encodeDataKey(dataNode.getKey()); | |||
values[i] = valueStorage.getEntry(dataKey, dataNode.getVersion()); | |||
bytesValue = valueStorage.get(dataKey, dataNode.getVersion()); | |||
values[i] = new VersioningKVData(dataNode.getKey(), dataNode.getVersion(), bytesValue); | |||
} | |||
return values; | |||
} | |||
/** | |||
* get the data at the specific index; | |||
* | |||
* @param fromIndex | |||
* @return | |||
*/ | |||
@@ -179,15 +180,15 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||
/** | |||
* get the key at the specific index; | |||
* | |||
* @param fromIndex | |||
* @return | |||
*/ | |||
public String getKeyAtIndex(int fromIndex) { | |||
MerkleDataNode dataNode = merkleTree.getData(fromIndex); | |||
return new String(dataNode.getKey().toBytes()); | |||
return new String(dataNode.getKey().toBytes()); | |||
} | |||
/** | |||
* Create or update the value associated the specified key if the version | |||
* checking is passed.<br> | |||
@@ -199,12 +200,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||
* If updating is performed, the version of the key increase by 1. <br> | |||
* If creating is performed, the version of the key initialize by 0. <br> | |||
* | |||
* @param key | |||
* The key of data; | |||
* @param value | |||
* The value of data; | |||
* @param version | |||
* The expected latest version of the key. | |||
* @param key The key of data; | |||
* @param value The value of data; | |||
* @param version The expected latest version of the key. | |||
* @return The new version of the key. <br> | |||
* If the key is new created success, then return 0; <br> | |||
* If the key is updated success, then return the new version;<br> | |||
@@ -226,12 +224,9 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||
* If updating is performed, the version of the key increase by 1. <br> | |||
* If creating is performed, the version of the key initialize by 0. <br> | |||
* | |||
* @param key | |||
* The key of data; | |||
* @param value | |||
* The value of data; | |||
* @param version | |||
* The expected latest version of the key. | |||
* @param key The key of data; | |||
* @param value The value of data; | |||
* @param version The expected latest version of the key. | |||
* @return The new version of the key. <br> | |||
* If the key is new created success, then return 0; <br> | |||
* If the key is updated success, then return the new version;<br> | |||
@@ -430,7 +425,12 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||
if (latestVersion < 0) { | |||
return null; | |||
} | |||
return valueStorage.getEntry(key, latestVersion); | |||
Bytes dataKey = encodeDataKey(key); | |||
byte[] value = valueStorage.get(dataKey, latestVersion); | |||
if (value == null) { | |||
return null; | |||
} | |||
return new VersioningKVData(key, latestVersion, value); | |||
} | |||
public VersioningKVEntry getDataEntry(Bytes key, long version) { | |||
@@ -441,7 +441,12 @@ public class MerkleDataSet implements Transactional, MerkleProvable { | |||
return null; | |||
} | |||
version = version < 0 ? latestVersion : version; | |||
return valueStorage.getEntry(key, version); | |||
Bytes dataKey = encodeDataKey(key); | |||
byte[] value = valueStorage.get(dataKey, version); | |||
if (value == null) { | |||
return null; | |||
} | |||
return new VersioningKVData(key, version, value); | |||
} | |||
public MerkleDataEntry getMerkleEntry(Bytes key, long version) { | |||
@@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.utils.Bytes; | |||
/** | |||
* 参与方证书数据对象; | |||
@@ -12,7 +13,7 @@ import com.jd.blockchain.ledger.ParticipantNode; | |||
public class ParticipantCertData implements ParticipantNode { | |||
private int id; | |||
private String address; | |||
private Bytes address; | |||
private String name; | |||
private PubKey pubKey; | |||
@@ -26,14 +27,14 @@ public class ParticipantCertData implements ParticipantNode { | |||
this.pubKey = participantNode.getPubKey(); | |||
} | |||
public ParticipantCertData(String address, String name, PubKey pubKey) { | |||
public ParticipantCertData(Bytes address, String name, PubKey pubKey) { | |||
this.address = address; | |||
this.name = name; | |||
this.pubKey = pubKey; | |||
} | |||
@Override | |||
public String getAddress() { | |||
public Bytes getAddress() { | |||
return address; | |||
} | |||
@@ -73,9 +73,8 @@ public class ParticipantDataSet implements Transactional, MerkleProvable { | |||
} | |||
} | |||
private Bytes encodeKey(String address) { | |||
// return id + ""; | |||
return Bytes.fromString(address); | |||
private Bytes encodeKey(Bytes address) { | |||
return address; | |||
} | |||
/** | |||
@@ -87,7 +86,7 @@ public class ParticipantDataSet implements Transactional, MerkleProvable { | |||
* @param address | |||
* @return | |||
*/ | |||
public ParticipantNode getParticipant(String address) { | |||
public ParticipantNode getParticipant(Bytes address) { | |||
Bytes key = encodeKey(address); | |||
byte[] bytes = dataset.getValue(key); | |||
if (bytes == null) { | |||
@@ -95,11 +94,11 @@ public class ParticipantDataSet implements Transactional, MerkleProvable { | |||
} | |||
return BinaryProtocol.decode(bytes); | |||
} | |||
public ParticipantNode[] getParticipants() { | |||
byte[][] bytes = dataset.getLatestValues(0, (int)dataset.getDataCount()); | |||
byte[][] bytes = dataset.getLatestValues(0, (int) dataset.getDataCount()); | |||
ParticipantNode[] pns = new ParticipantNode[bytes.length]; | |||
for (int i = 0; i < pns.length; i++) { | |||
pns[i] = BinaryProtocol.decode(bytes[i]); | |||
} | |||
@@ -17,7 +17,7 @@ public interface PrivilegeSet { | |||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||
LedgerPrivilege getLedgerPrivilege(); | |||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||
@DataField(order = 2, primitiveType = PrimitiveType.BYTES) | |||
TransactionPrivilege getTransactionPrivilege(); | |||
} |
@@ -12,11 +12,6 @@ import com.jd.blockchain.utils.Transactional; | |||
public class RolePrivilegeDataSet implements Transactional, MerkleProvable, RolePrivilegeSettings { | |||
/** | |||
* 角色名称的最大 Unicode 字符数; | |||
*/ | |||
public static final int MAX_ROLE_NAME_LENGTH = 20; | |||
private MerkleDataSet dataset; | |||
public RolePrivilegeDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, | |||
@@ -60,22 +55,30 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||
} | |||
/** | |||
* 加入新的角色授权; <br> | |||
* | |||
* 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode 字符; | |||
* @param ledgerPrivilege | |||
* @param txPrivilege | |||
* | |||
*/ | |||
@Override | |||
public void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) { | |||
RolePrivileges roleAuth = new RolePrivileges(roleName, -1, ledgerPrivilege, | |||
txPrivilege); | |||
public long addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege) { | |||
RolePrivileges roleAuth = new RolePrivileges(roleName, -1, ledgerPrivilege, txPrivilege); | |||
long nv = setRolePrivilege(roleAuth); | |||
if (nv < 0) { | |||
throw new LedgerException("Role[" + roleName + "] already exist!"); | |||
} | |||
return nv; | |||
} | |||
@Override | |||
public long addRolePrivilege(String roleName, LedgerPermission[] ledgerPermissions, | |||
TransactionPermission[] txPermissions) { | |||
LedgerPrivilege ledgerPrivilege = new LedgerPrivilege(); | |||
for (LedgerPermission lp : ledgerPermissions) { | |||
ledgerPrivilege.enable(lp); | |||
} | |||
TransactionPrivilege txPrivilege = new TransactionPrivilege(); | |||
for (TransactionPermission tp : txPermissions) { | |||
txPrivilege.enable(tp); | |||
} | |||
return addRolePrivilege(roleName, ledgerPrivilege, txPrivilege); | |||
} | |||
/** | |||
@@ -144,7 +147,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||
roleAuth.getTransactionPrivilege().enable(permissions); | |||
return setRolePrivilege(roleAuth); | |||
} | |||
/** | |||
* 禁止角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
@@ -162,7 +165,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||
roleAuth.getLedgerPrivilege().disable(permissions); | |||
return setRolePrivilege(roleAuth); | |||
} | |||
/** | |||
* 禁止角色指定的权限; <br> | |||
* 如果角色不存在,则返回 -1; | |||
@@ -248,7 +251,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||
PrivilegeSet privilege = BinaryProtocol.decode(kv.getValue()); | |||
return new RolePrivileges(roleName, kv.getVersion(), privilege); | |||
} | |||
@Override | |||
public RolePrivileges[] getRolePrivileges(int index, int count) { | |||
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(index, count); | |||
@@ -256,8 +259,7 @@ public class RolePrivilegeDataSet implements Transactional, MerkleProvable, Role | |||
PrivilegeSet privilege; | |||
for (int i = 0; i < pns.length; i++) { | |||
privilege = BinaryProtocol.decode(kvEntries[i].getValue()); | |||
pns[i] = new RolePrivileges(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(), | |||
privilege); | |||
pns[i] = new RolePrivileges(kvEntries[i].getKey().toUTF8String(), kvEntries[i].getVersion(), privilege); | |||
} | |||
return pns; | |||
} | |||
@@ -3,6 +3,11 @@ package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
public interface RolePrivilegeSettings { | |||
/** | |||
* 角色名称的最大 Unicode 字符数; | |||
*/ | |||
public static final int MAX_ROLE_NAME_LENGTH = 20; | |||
long getRoleCount(); | |||
@@ -15,7 +20,20 @@ public interface RolePrivilegeSettings { | |||
* @param ledgerPrivilege | |||
* @param txPrivilege | |||
*/ | |||
void addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege); | |||
long addRolePrivilege(String roleName, LedgerPrivilege ledgerPrivilege, TransactionPrivilege txPrivilege); | |||
/** | |||
* 加入新的角色授权; <br> | |||
* | |||
* 如果指定的角色已经存在,则引发 {@link LedgerException} 异常; | |||
* | |||
* @param roleName 角色名称;不能超过 {@link #MAX_ROLE_NAME_LENGTH} 个 Unicode | |||
* 字符; | |||
* @param ledgerPermissions 给角色授予的账本权限列表; | |||
* @param txPermissions 给角色授予的交易权限列表; | |||
* @return | |||
*/ | |||
long addRolePrivilege(String roleName, LedgerPermission[] ledgerPermissions, TransactionPermission[] txPermissions); | |||
/** | |||
* 更新角色授权; <br> | |||
@@ -2,6 +2,7 @@ package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.binaryproto.BinaryProtocol; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.AuthorizationException; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.LedgerException; | |||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | |||
@@ -11,12 +12,7 @@ import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.Transactional; | |||
public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleSettings { | |||
/** | |||
* 角色名称的最大 Unicode 字符数; | |||
*/ | |||
public static final int MAX_ROLE_NAME_LENGTH = 20; | |||
private MerkleDataSet dataset; | |||
public UserRoleDataSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exPolicyStorage, | |||
@@ -55,7 +51,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||
} | |||
@Override | |||
public long getRoleCount() { | |||
public long getUserCount() { | |||
return dataset.getDataCount(); | |||
} | |||
@@ -74,7 +70,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||
roleAuth.addRoles(roles); | |||
long nv = setUserRolesAuthorization(roleAuth); | |||
if (nv < 0) { | |||
throw new LedgerException("Roles authorization of User[" + userAddress + "] already exists!"); | |||
throw new AuthorizationException("Roles authorization of User[" + userAddress + "] already exists!"); | |||
} | |||
} | |||
@@ -86,6 +82,9 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||
* @return | |||
*/ | |||
private long setUserRolesAuthorization(UserRoles userRoles) { | |||
if (userRoles.getRoleCount() > MAX_ROLES_PER_USER) { | |||
throw new AuthorizationException("The number of roles exceeds the maximum range!"); | |||
} | |||
byte[] rolesetBytes = BinaryProtocol.encode(userRoles, RoleSet.class); | |||
return dataset.setValue(userRoles.getUserAddress(), rolesetBytes, userRoles.getVersion()); | |||
} | |||
@@ -100,7 +99,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||
public void updateUserRoles(UserRoles userRoles) { | |||
long nv = setUserRolesAuthorization(userRoles); | |||
if (nv < 0) { | |||
throw new LedgerException("Update to roles of user[" + userRoles.getUserAddress() | |||
throw new AuthorizationException("Update to roles of user[" + userRoles.getUserAddress() | |||
+ "] failed due to wrong version[" + userRoles.getVersion() + "] !"); | |||
} | |||
} | |||
@@ -146,7 +145,7 @@ public class UserRoleDataSet implements Transactional, MerkleProvable, UserRoleS | |||
} | |||
@Override | |||
public UserRoles[] getRoleAuthorizations() { | |||
public UserRoles[] getUserRoles() { | |||
VersioningKVEntry[] kvEntries = dataset.getLatestDataEntries(0, (int) dataset.getDataCount()); | |||
UserRoles[] pns = new UserRoles[kvEntries.length]; | |||
RoleSet roleset; | |||
@@ -5,7 +5,17 @@ import com.jd.blockchain.utils.Bytes; | |||
public interface UserRoleSettings { | |||
long getRoleCount(); | |||
/** | |||
* 单一用户可被授权的角色数量的最大值; | |||
*/ | |||
public static final int MAX_ROLES_PER_USER = 20; | |||
/** | |||
* 进行了授权的用户的数量; | |||
* | |||
* @return | |||
*/ | |||
long getUserCount(); | |||
/** | |||
* 加入新的用户角色授权; <br> | |||
@@ -48,6 +58,11 @@ public interface UserRoleSettings { | |||
*/ | |||
UserRoles getUserRoles(Bytes userAddress); | |||
UserRoles[] getRoleAuthorizations(); | |||
/** | |||
* 返回全部的用户授权; | |||
* | |||
* @return | |||
*/ | |||
UserRoles[] getUserRoles(); | |||
} |
@@ -79,6 +79,10 @@ public class UserRoles implements RoleSet { | |||
* @param roles | |||
*/ | |||
public void setRoles(String[] roles) { | |||
TreeSet<String> rs = new TreeSet<String>(); | |||
for (String r : roles) { | |||
rs.add(r); | |||
} | |||
this.roles = rs; | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
package test.com.jd.blockchain.ledger; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertNotNull; | |||
@@ -9,7 +10,6 @@ import static org.junit.Assert.assertTrue; | |||
import java.util.Arrays; | |||
import java.util.Random; | |||
import com.jd.blockchain.ledger.LedgerMetadata; | |||
import org.junit.Test; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
@@ -21,15 +21,23 @@ import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.ledger.LedgerMetadata_V2; | |||
import com.jd.blockchain.ledger.LedgerSettings; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.ledger.core.CryptoConfig; | |||
import com.jd.blockchain.ledger.core.LedgerAdminAccount; | |||
import com.jd.blockchain.ledger.core.LedgerConfiguration; | |||
import com.jd.blockchain.ledger.core.LedgerPermission; | |||
import com.jd.blockchain.ledger.core.RolePrivilegeSettings; | |||
import com.jd.blockchain.ledger.core.RolePrivileges; | |||
import com.jd.blockchain.ledger.core.RolesPolicy; | |||
import com.jd.blockchain.ledger.core.TransactionPermission; | |||
import com.jd.blockchain.ledger.core.UserRoleSettings; | |||
import com.jd.blockchain.ledger.core.UserRoles; | |||
import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | |||
import com.jd.blockchain.transaction.ConsensusParticipantData; | |||
import com.jd.blockchain.transaction.LedgerInitSettingData; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.io.BytesUtils; | |||
import com.jd.blockchain.utils.net.NetworkAddress; | |||
public class LedgerAdminAccountTest { | |||
@@ -40,7 +48,7 @@ public class LedgerAdminAccountTest { | |||
private Random rand = new Random(); | |||
@Test | |||
public void test() { | |||
public void testSerialization() { | |||
String keyPrefix = ""; | |||
LedgerInitSettingData initSetting = new LedgerInitSettingData(); | |||
ConsensusParticipantData[] parties = new ConsensusParticipantData[5]; | |||
@@ -49,7 +57,7 @@ public class LedgerAdminAccountTest { | |||
bckeys[i] = BlockchainKeyGenerator.getInstance().generate(); | |||
parties[i] = new ConsensusParticipantData(); | |||
parties[i].setId(i); | |||
parties[i].setAddress(AddressEncoding.generateAddress(bckeys[i].getPubKey()).toBase58()); | |||
parties[i].setAddress(AddressEncoding.generateAddress(bckeys[i].getPubKey())); | |||
parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); | |||
parties[i].setName("Participant[" + i + "]"); | |||
parties[i].setPubKey(bckeys[i].getPubKey()); | |||
@@ -66,7 +74,6 @@ public class LedgerAdminAccountTest { | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
CryptoConfig cryptoSetting = new CryptoConfig(); | |||
cryptoSetting.setSupportedProviders(supportedProviders); | |||
cryptoSetting.setAutoVerifyHash(true); | |||
@@ -83,12 +90,20 @@ public class LedgerAdminAccountTest { | |||
LedgerAdminAccount ledgerAdminAccount = new LedgerAdminAccount(initSetting, keyPrefix, testStorage, | |||
testStorage); | |||
ledgerAdminAccount.getRolePrivileges().addRolePrivilege("DEFAULT", | |||
new LedgerPermission[] { LedgerPermission.AUTHORIZE_ROLES, LedgerPermission.REGISTER_USER, | |||
LedgerPermission.APPROVE_TX }, | |||
new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION, | |||
TransactionPermission.CONTRACT_OPERATION }); | |||
ledgerAdminAccount.getUserRoles().addUserRoles(parties[0].getAddress(), RolesPolicy.UNION, "DEFAULT"); | |||
// New created instance is updated until being committed; | |||
assertTrue(ledgerAdminAccount.isUpdated()); | |||
// Hash of account is null until being committed; | |||
assertNull(ledgerAdminAccount.getHash()); | |||
LedgerMetadata meta = ledgerAdminAccount.getMetadata(); | |||
LedgerMetadata_V2 meta = ledgerAdminAccount.getMetadata(); | |||
assertNull(meta.getParticipantsHash()); | |||
// Commit, and check the storage keys; | |||
@@ -101,83 +116,145 @@ public class LedgerAdminAccountTest { | |||
meta = ledgerAdminAccount.getMetadata(); | |||
assertNotNull(meta.getParticipantsHash()); | |||
assertNotNull(meta.getSettingsHash()); | |||
assertNotNull(meta.getRolePrivilegesHash()); | |||
assertNotNull(meta.getUserRolesHash()); | |||
assertNotNull(ledgerAdminAccount.getRolePrivileges().getRolePrivilege("DEFAULT")); | |||
// ---------------------- | |||
// Reload account from storage with readonly mode, and check the integrity of | |||
// data; | |||
HashDigest adminAccHash = ledgerAdminAccount.getHash(); | |||
LedgerAdminAccount reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, | |||
LedgerAdminAccount reloadAdminAccount1 = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, | |||
testStorage, true); | |||
LedgerMetadata_V2 meta2 = reloadAdminAccount1.getMetadata(); | |||
assertNotNull(meta2.getParticipantsHash()); | |||
assertNotNull(meta2.getSettingsHash()); | |||
assertNotNull(meta2.getRolePrivilegesHash()); | |||
assertNotNull(meta2.getUserRolesHash()); | |||
// verify realod settings of admin account; | |||
verifyRealoadingSettings(reloadAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata()); | |||
verifyRealoadingSettings(reloadAdminAccount1, adminAccHash, ledgerAdminAccount.getMetadata(), | |||
ledgerAdminAccount.getSettings()); | |||
// verify the consensus participant list; | |||
verifyReadlingParities(reloadAdminAccount, parties1); | |||
verifyRealoadingParities(reloadAdminAccount1, parties1); | |||
// It will throw exeception because of this account is readonly; | |||
verifyReadonlyState(reloadAdminAccount); | |||
verifyReadonlyState(reloadAdminAccount1); | |||
verifyRealoadingRoleAuthorizations(reloadAdminAccount1, ledgerAdminAccount.getRolePrivileges(), | |||
ledgerAdminAccount.getUserRoles()); | |||
// -------------- | |||
// reload again with writing mode; | |||
reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, false); | |||
LedgerConfiguration newSetting = new LedgerConfiguration(reloadAdminAccount.getPreviousSetting()); | |||
// 重新加载,并进行修改; | |||
LedgerAdminAccount reloadAdminAccount2 = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, false); | |||
LedgerConfiguration newSetting = new LedgerConfiguration(reloadAdminAccount2.getPreviousSetting()); | |||
byte[] newCsSettingBytes = new byte[64]; | |||
rand.nextBytes(newCsSettingBytes); | |||
newSetting.setConsensusSetting(new Bytes(newCsSettingBytes)); | |||
newSetting.getCryptoSetting().setAutoVerifyHash(false); | |||
reloadAdminAccount.setLedgerSetting(newSetting); | |||
reloadAdminAccount2.setLedgerSetting(newSetting); | |||
reloadAdminAccount2.addParticipant(parties[4]); | |||
reloadAdminAccount2.getRolePrivileges().addRolePrivilege("ADMIN", | |||
new LedgerPermission[] { LedgerPermission.APPROVE_TX }, | |||
new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION }); | |||
reloadAdminAccount2.getRolePrivileges().disablePermissions("DEFAULT", TransactionPermission.CONTRACT_OPERATION); | |||
reloadAdminAccount2.getUserRoles().addUserRoles(parties[1].getAddress(), RolesPolicy.UNION, "DEFAULT", "ADMIN"); | |||
reloadAdminAccount.addParticipant(parties[4]); | |||
reloadAdminAccount.commit(); | |||
reloadAdminAccount2.commit(); | |||
LedgerSettings newlyLedgerSettings = reloadAdminAccount2.getSettings(); | |||
// record the new account hash; | |||
HashDigest newAccHash = reloadAdminAccount.getHash(); | |||
LedgerMetadata newMeta = reloadAdminAccount.getMetadata(); | |||
HashDigest newAccHash = reloadAdminAccount2.getHash(); | |||
LedgerMetadata_V2 newMeta = reloadAdminAccount2.getMetadata(); | |||
// load the last version of account and verify again; | |||
reloadAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, testStorage, true); | |||
verifyRealoadingSettings(reloadAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata()); | |||
verifyReadlingParities(reloadAdminAccount, parties1); | |||
verifyReadonlyState(reloadAdminAccount); | |||
LedgerAdminAccount previousAdminAccount = new LedgerAdminAccount(adminAccHash, keyPrefix, testStorage, | |||
testStorage, true); | |||
verifyRealoadingSettings(previousAdminAccount, adminAccHash, ledgerAdminAccount.getMetadata(), | |||
ledgerAdminAccount.getSettings()); | |||
verifyRealoadingParities(previousAdminAccount, parties1); | |||
verifyReadonlyState(previousAdminAccount); | |||
// load the hash of new committing; | |||
reloadAdminAccount = new LedgerAdminAccount(newAccHash, keyPrefix, testStorage, testStorage, true); | |||
verifyRealoadingSettings(reloadAdminAccount, newAccHash, newMeta); | |||
verifyReadlingParities(reloadAdminAccount, parties); | |||
verifyReadonlyState(reloadAdminAccount); | |||
// System.out.println("========= [LedgerAdminAccount Test] Show generated | |||
// storage keys... ======="); | |||
// testStorage.printStoragedKeys(); | |||
LedgerAdminAccount newlyAdminAccount = new LedgerAdminAccount(newAccHash, keyPrefix, testStorage, testStorage, | |||
true); | |||
verifyRealoadingSettings(newlyAdminAccount, newAccHash, newMeta, newlyLedgerSettings); | |||
verifyRealoadingParities(newlyAdminAccount, parties); | |||
verifyReadonlyState(newlyAdminAccount); | |||
// System.out.println("========= [LedgerAdminAccount Test] Show generated storage keys... ======="); | |||
// testStorage.printStoragedKeys(); | |||
} | |||
private void verifyRealoadingSettings(LedgerAdminAccount actualAccount, HashDigest expHash, | |||
LedgerMetadata expMeta) { | |||
private void verifyRealoadingSettings(LedgerAdminAccount actualAccount, HashDigest expAccRootHash, | |||
LedgerMetadata_V2 expMeta, LedgerSettings expLedgerSettings) { | |||
// 验证基本信息; | |||
assertFalse(actualAccount.isUpdated()); | |||
assertTrue(actualAccount.isReadonly()); | |||
assertEquals(expHash, actualAccount.getHash()); | |||
assertEquals(expAccRootHash, actualAccount.getHash()); | |||
// verify metadata; | |||
LedgerMetadata rlmeta = actualAccount.getMetadata(); | |||
assertEquals(expMeta.getParticipantsHash(), rlmeta.getParticipantsHash()); | |||
assertTrue(BytesUtils.equals(expMeta.getSeed(), rlmeta.getSeed())); | |||
assertNotNull(rlmeta.getSettingsHash()); | |||
assertEquals(expMeta.getSettingsHash(), rlmeta.getSettingsHash()); | |||
// assertTrue(expMeta.getSettings().getConsensusSetting().equals(rlmeta.getSettings().getConsensusSetting())); | |||
// assertEquals(expMeta.getSettings().getConsensusProvider(), rlmeta.getSettings().getConsensusProvider()); | |||
// | |||
// assertEquals(expMeta.getSettings().getCryptoSetting().getAutoVerifyHash(), | |||
// rlmeta.getSettings().getCryptoSetting().getAutoVerifyHash()); | |||
// assertEquals(expMeta.getSettings().getCryptoSetting().getHashAlgorithm(), | |||
// rlmeta.getSettings().getCryptoSetting().getHashAlgorithm()); | |||
LedgerMetadata_V2 actualMeta = actualAccount.getMetadata(); | |||
assertArrayEquals(expMeta.getSeed(), actualMeta.getSeed()); | |||
assertEquals(expMeta.getParticipantsHash(), actualMeta.getParticipantsHash()); | |||
assertNotNull(actualMeta.getSettingsHash()); | |||
assertEquals(expMeta.getSettingsHash(), actualMeta.getSettingsHash()); | |||
assertNotNull(actualMeta.getRolePrivilegesHash()); | |||
assertEquals(expMeta.getRolePrivilegesHash(), actualMeta.getRolePrivilegesHash()); | |||
assertNotNull(actualMeta.getUserRolesHash()); | |||
assertEquals(expMeta.getUserRolesHash(), actualMeta.getUserRolesHash()); | |||
LedgerSettings actualLedgerSettings = actualAccount.getSettings(); | |||
assertEquals(expLedgerSettings.getConsensusSetting(), actualLedgerSettings.getConsensusSetting()); | |||
assertEquals(expLedgerSettings.getConsensusProvider(), actualLedgerSettings.getConsensusProvider()); | |||
assertEquals(expLedgerSettings.getCryptoSetting().getAutoVerifyHash(), | |||
actualLedgerSettings.getCryptoSetting().getAutoVerifyHash()); | |||
assertEquals(expLedgerSettings.getCryptoSetting().getHashAlgorithm(), | |||
actualLedgerSettings.getCryptoSetting().getHashAlgorithm()); | |||
} | |||
private void verifyRealoadingRoleAuthorizations(LedgerAdminAccount actualAccount, | |||
RolePrivilegeSettings expRolePrivilegeSettings, UserRoleSettings expUserRoleSettings) { | |||
// 验证基本信息; | |||
RolePrivilegeSettings actualRolePrivileges = actualAccount.getRolePrivileges(); | |||
RolePrivileges[] expRPs = expRolePrivilegeSettings.getRolePrivileges(); | |||
assertEquals(expRPs.length, actualRolePrivileges.getRoleCount()); | |||
for (RolePrivileges expRP : expRPs) { | |||
RolePrivileges actualRP = actualRolePrivileges.getRolePrivilege(expRP.getRoleName()); | |||
assertNotNull(actualRP); | |||
assertArrayEquals(expRP.getLedgerPrivilege().toBytes(), actualRP.getLedgerPrivilege().toBytes()); | |||
assertArrayEquals(expRP.getTransactionPrivilege().toBytes(), actualRP.getTransactionPrivilege().toBytes()); | |||
} | |||
UserRoleSettings actualUserRoleSettings = actualAccount.getUserRoles(); | |||
UserRoles[] expUserRoles = expUserRoleSettings.getUserRoles(); | |||
assertEquals(expUserRoles.length, actualUserRoleSettings.getUserCount()); | |||
for (UserRoles expUR : expUserRoles) { | |||
UserRoles actualUR = actualAccount.getUserRoles().getUserRoles(expUR.getUserAddress()); | |||
assertNotNull(actualUR); | |||
assertEquals(expUR.getPolicy(), actualUR.getPolicy()); | |||
String[] expRoles = expUR.getRoles(); | |||
Arrays.sort(expRoles); | |||
String[] actualRoles = actualUR.getRoles(); | |||
Arrays.sort(actualRoles); | |||
assertArrayEquals(expRoles, actualRoles); | |||
} | |||
} | |||
private void verifyReadlingParities(LedgerAdminAccount actualAccount, ParticipantNode[] expParties) { | |||
private void verifyRealoadingParities(LedgerAdminAccount actualAccount, ParticipantNode[] expParties) { | |||
assertEquals(expParties.length, actualAccount.getParticipantCount()); | |||
ParticipantNode[] actualPaticipants = actualAccount.getParticipants(); | |||
assertEquals(expParties.length, actualPaticipants.length); | |||
@@ -191,11 +268,16 @@ public class LedgerAdminAccountTest { | |||
} | |||
} | |||
private void verifyReadonlyState(LedgerAdminAccount actualAccount) { | |||
/** | |||
* 验证指定账户是否只读; | |||
* | |||
* @param readonlyAccount | |||
*/ | |||
private void verifyReadonlyState(LedgerAdminAccount readonlyAccount) { | |||
ConsensusParticipantData newParti = new ConsensusParticipantData(); | |||
newParti.setId((int) actualAccount.getParticipantCount()); | |||
newParti.setId((int) readonlyAccount.getParticipantCount()); | |||
newParti.setHostAddress( | |||
new NetworkAddress("192.168.10." + (10 + newParti.getAddress()), 10010 + 10 * newParti.getId())); | |||
new NetworkAddress("192.168.10." + (10 + newParti.getId()), 10010 + 10 * newParti.getId())); | |||
newParti.setName("Participant[" + newParti.getAddress() + "]"); | |||
BlockchainKeypair newKey = BlockchainKeyGenerator.getInstance().generate(); | |||
@@ -203,7 +285,7 @@ public class LedgerAdminAccountTest { | |||
Throwable ex = null; | |||
try { | |||
actualAccount.addParticipant(newParti); | |||
readonlyAccount.addParticipant(newParti); | |||
} catch (Exception e) { | |||
ex = e; | |||
} | |||
@@ -211,8 +293,8 @@ public class LedgerAdminAccountTest { | |||
ex = null; | |||
try { | |||
LedgerConfiguration newLedgerSetting = new LedgerConfiguration(actualAccount.getSettings()); | |||
actualAccount.setLedgerSetting(newLedgerSetting); | |||
LedgerConfiguration newLedgerSetting = new LedgerConfiguration(readonlyAccount.getSettings()); | |||
readonlyAccount.setLedgerSetting(newLedgerSetting); | |||
} catch (Exception e) { | |||
ex = e; | |||
} | |||
@@ -76,7 +76,7 @@ public class LedgerInitOperationTest { | |||
keys[i] = BlockchainKeyGenerator.getInstance().generate(); | |||
parties[i] = new ConsensusParticipantData(); | |||
// parties[i].setId(i); | |||
parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58()); | |||
parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey())); | |||
parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); | |||
parties[i].setName("Participant[" + i + "]"); | |||
parties[i].setPubKey(keys[i].getPubKey()); | |||
@@ -117,7 +117,7 @@ public class LedgerInitOperationTest { | |||
for (int i = 0; i < parties.length; i++) { | |||
keys[i] = BlockchainKeyGenerator.getInstance().generate(); | |||
parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58(), | |||
parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()), | |||
"Participant[" + i + "]", keys[i].getPubKey()); | |||
} | |||
@@ -76,7 +76,7 @@ public class LedgerInitSettingSerializeTest { | |||
keys[i] = BlockchainKeyGenerator.getInstance().generate(); | |||
parties[i] = new ConsensusParticipantData(); | |||
// parties[i].setId(i); | |||
parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58()); | |||
parties[i].setAddress(AddressEncoding.generateAddress(keys[i].getPubKey())); | |||
parties[i].setHostAddress(new NetworkAddress("192.168.10." + (10 + i), 10010 + 10 * i)); | |||
parties[i].setName("Participant[" + i + "]"); | |||
parties[i].setPubKey(keys[i].getPubKey()); | |||
@@ -84,7 +84,7 @@ public class LedgerInitSettingSerializeTest { | |||
ConsensusParticipantData[] parties1 = Arrays.copyOf(parties, 4); | |||
ledgerInitSettingData.setConsensusParticipants(parties1); | |||
byte[] encode = BinaryProtocol.encode(ledgerInitSettingData, LedgerInitSetting.class); | |||
LedgerInitSetting decode = BinaryProtocol.decode(encode); | |||
@@ -121,7 +121,7 @@ public class LedgerInitSettingSerializeTest { | |||
for (int i = 0; i < parties.length; i++) { | |||
keys[i] = BlockchainKeyGenerator.getInstance().generate(); | |||
parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()).toBase58(), | |||
parties[i] = new ParticipantCertData(AddressEncoding.generateAddress(keys[i].getPubKey()), | |||
"Participant[" + i + "]", keys[i].getPubKey()); | |||
} | |||
@@ -209,7 +209,7 @@ public class LedgerManagerTest { | |||
parties[0].setName("John"); | |||
AsymmetricKeypair kp0 = signatureFunction.generateKeypair(); | |||
parties[0].setPubKey(kp0.getPubKey()); | |||
parties[0].setAddress(AddressEncoding.generateAddress(kp0.getPubKey()).toBase58()); | |||
parties[0].setAddress(AddressEncoding.generateAddress(kp0.getPubKey())); | |||
parties[0].setHostAddress(new NetworkAddress("127.0.0.1", 9000)); | |||
parties[1] = new ConsensusParticipantData(); | |||
@@ -217,7 +217,7 @@ public class LedgerManagerTest { | |||
parties[1].setName("Mary"); | |||
AsymmetricKeypair kp1 = signatureFunction.generateKeypair(); | |||
parties[1].setPubKey(kp1.getPubKey()); | |||
parties[1].setAddress(AddressEncoding.generateAddress(kp1.getPubKey()).toBase58()); | |||
parties[1].setAddress(AddressEncoding.generateAddress(kp1.getPubKey())); | |||
parties[1].setHostAddress(new NetworkAddress("127.0.0.1", 9010)); | |||
parties[2] = new ConsensusParticipantData(); | |||
@@ -225,7 +225,7 @@ public class LedgerManagerTest { | |||
parties[2].setName("Jerry"); | |||
AsymmetricKeypair kp2 = signatureFunction.generateKeypair(); | |||
parties[2].setPubKey(kp2.getPubKey()); | |||
parties[2].setAddress(AddressEncoding.generateAddress(kp2.getPubKey()).toBase58()); | |||
parties[2].setAddress(AddressEncoding.generateAddress(kp2.getPubKey())); | |||
parties[2].setHostAddress(new NetworkAddress("127.0.0.1", 9020)); | |||
parties[3] = new ConsensusParticipantData(); | |||
@@ -233,7 +233,7 @@ public class LedgerManagerTest { | |||
parties[3].setName("Tom"); | |||
AsymmetricKeypair kp3 = signatureFunction.generateKeypair(); | |||
parties[3].setPubKey(kp3.getPubKey()); | |||
parties[3].setAddress(AddressEncoding.generateAddress(kp3.getPubKey()).toBase58()); | |||
parties[3].setAddress(AddressEncoding.generateAddress(kp3.getPubKey())); | |||
parties[3].setHostAddress(new NetworkAddress("127.0.0.1", 9030)); | |||
initSetting.setConsensusParticipants(parties); | |||
@@ -78,7 +78,7 @@ public class LedgerMetaDataTest { | |||
// LedgerConfiguration ledgerConfiguration = new LedgerConfiguration(consensusProvider, | |||
// new Bytes(consensusSettingBytes), cryptoConfig); | |||
HashDigest settingsHash = Crypto.getHashFunction("SHA256").hash(consensusSettingBytes); | |||
LedgerAdminAccount.LedgerMetadataImpl ledgerMetadata = new LedgerAdminAccount.LedgerMetadataImpl(); | |||
ledgerMetadata.setSeed(seed); | |||
@@ -188,7 +188,7 @@ public class LedgerMetaDataTest { | |||
String name = "John"; | |||
// NetworkAddress consensusAddress = new NetworkAddress("192.168.1.1", 9001, | |||
// false); | |||
String address = AddressEncoding.generateAddress(pubKey).toBase58(); | |||
Bytes address = AddressEncoding.generateAddress(pubKey); | |||
ParticipantCertData participantCertData = new ParticipantCertData(address, name, pubKey); | |||
// encode and decode | |||
@@ -72,7 +72,7 @@ public class LedgerTestUtils { | |||
parties[i].setId(0); | |||
parties[i].setName("Parti-" + i); | |||
parties[i].setPubKey(partiKeys[i].getPubKey()); | |||
parties[i].setAddress(AddressEncoding.generateAddress(partiKeys[i].getPubKey()).toBase58()); | |||
parties[i].setAddress(AddressEncoding.generateAddress(partiKeys[i].getPubKey())); | |||
parties[i].setHostAddress(new NetworkAddress("192.168.1." + (10 + i), 9000)); | |||
} | |||
@@ -125,13 +125,13 @@ public class LedgerTestUtils { | |||
return txReqBuilder.buildRequest(); | |||
} | |||
public static TransactionRequest createTxRequest_DataAccountReg(BlockchainKeypair dataAccountID, HashDigest ledgerHash, | |||
BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { | |||
public static TransactionRequest createTxRequest_DataAccountReg(BlockchainKeypair dataAccountID, | |||
HashDigest ledgerHash, BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { | |||
TxBuilder txBuilder = new TxBuilder(ledgerHash); | |||
txBuilder.dataAccounts().register(dataAccountID.getIdentity()); | |||
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); | |||
if (signers != null) { | |||
for (BlockchainKeypair signer : signers) { | |||
@@ -141,16 +141,17 @@ public class LedgerTestUtils { | |||
if (nodeKeypair != null) { | |||
txReqBuilder.signAsNode(nodeKeypair); | |||
} | |||
return txReqBuilder.buildRequest(); | |||
} | |||
public static TransactionRequest createTxRequest_DataAccountWrite(Bytes dataAccountAddress, String key, String value, long version, HashDigest ledgerHash, | |||
BlockchainKeypair nodeKeypair, BlockchainKeypair... signers) { | |||
public static TransactionRequest createTxRequest_DataAccountWrite(Bytes dataAccountAddress, String key, | |||
String value, long version, HashDigest ledgerHash, BlockchainKeypair nodeKeypair, | |||
BlockchainKeypair... signers) { | |||
TxBuilder txBuilder = new TxBuilder(ledgerHash); | |||
txBuilder.dataAccount(dataAccountAddress).setText(key, value, version); | |||
TransactionRequestBuilder txReqBuilder = txBuilder.prepareRequest(); | |||
if (signers != null) { | |||
for (BlockchainKeypair signer : signers) { | |||
@@ -160,7 +161,7 @@ public class LedgerTestUtils { | |||
if (nodeKeypair != null) { | |||
txReqBuilder.signAsNode(nodeKeypair); | |||
} | |||
return txReqBuilder.buildRequest(); | |||
} | |||
@@ -58,6 +58,18 @@ public class MerkleDataSetTest { | |||
mds.setValue("C", "C".getBytes(), -1); | |||
mds.commit(); | |||
byte[] va = mds.getValue("A"); | |||
assertNotNull(va); | |||
assertEquals("A", new String(va)); | |||
byte[] vc = mds.getValue("C"); | |||
VersioningKVEntry ventry = mds.getDataEntry("C"); | |||
assertNotNull(vc); | |||
assertNotNull(ventry); | |||
assertEquals("C", new String(vc)); | |||
assertEquals("C", ventry.getKey().toUTF8String()); | |||
HashDigest root1 = mds.getRootHash(); | |||
// 1个KV项的存储KEY的数量= 1 + 1(保存SN) + Merkle节点数量; | |||
@@ -0,0 +1,70 @@ | |||
package test.com.jd.blockchain.ledger; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertTrue; | |||
import static org.junit.Assert.fail; | |||
import org.junit.Test; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.core.CryptoConfig; | |||
import com.jd.blockchain.ledger.core.LedgerPermission; | |||
import com.jd.blockchain.ledger.core.RolePrivilegeDataSet; | |||
import com.jd.blockchain.ledger.core.RolePrivileges; | |||
import com.jd.blockchain.ledger.core.TransactionPermission; | |||
import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | |||
public class RolePrivilegeDataSetTest { | |||
private static final String[] SUPPORTED_PROVIDER_NAMES = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
private static final CryptoAlgorithm HASH_ALGORITHM = Crypto.getAlgorithm("SHA256"); | |||
private static final CryptoProvider[] SUPPORTED_PROVIDERS = new CryptoProvider[SUPPORTED_PROVIDER_NAMES.length]; | |||
static { | |||
for (int i = 0; i < SUPPORTED_PROVIDER_NAMES.length; i++) { | |||
SUPPORTED_PROVIDERS[i] = Crypto.getProvider(SUPPORTED_PROVIDER_NAMES[i]); | |||
} | |||
} | |||
@Test | |||
public void testAddRolePrivilege() { | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
cryptoConfig.setSupportedProviders(SUPPORTED_PROVIDERS); | |||
cryptoConfig.setHashAlgorithm(HASH_ALGORITHM); | |||
MemoryKVStorage testStorage = new MemoryKVStorage(); | |||
String roleName = "DEFAULT"; | |||
String prefix = "role-privilege/"; | |||
RolePrivilegeDataSet rolePrivilegeDataset = new RolePrivilegeDataSet(cryptoConfig, prefix, testStorage, | |||
testStorage); | |||
rolePrivilegeDataset.addRolePrivilege(roleName, new LedgerPermission[] { LedgerPermission.REGISTER_USER }, | |||
new TransactionPermission[] { TransactionPermission.CONTRACT_OPERATION }); | |||
rolePrivilegeDataset.commit(); | |||
RolePrivileges rolePrivilege = rolePrivilegeDataset.getRolePrivilege(roleName); | |||
assertNotNull(rolePrivilege); | |||
HashDigest rootHash = rolePrivilegeDataset.getRootHash(); | |||
RolePrivilegeDataSet newRolePrivilegeDataset = new RolePrivilegeDataSet(rootHash, cryptoConfig, prefix, | |||
testStorage, testStorage, true); | |||
rolePrivilege = newRolePrivilegeDataset.getRolePrivilege(roleName); | |||
assertNotNull(rolePrivilege); | |||
assertTrue(rolePrivilege.getLedgerPrivilege().isEnable(LedgerPermission.REGISTER_USER)); | |||
assertTrue(rolePrivilege.getTransactionPrivilege().isEnable(TransactionPermission.CONTRACT_OPERATION)); | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
package test.com.jd.blockchain.ledger; | |||
import static org.junit.Assert.assertArrayEquals; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import org.junit.Test; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||
import com.jd.blockchain.ledger.BlockchainKeypair; | |||
import com.jd.blockchain.ledger.core.CryptoConfig; | |||
import com.jd.blockchain.ledger.core.RolesPolicy; | |||
import com.jd.blockchain.ledger.core.UserRoleDataSet; | |||
import com.jd.blockchain.ledger.core.UserRoles; | |||
import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | |||
public class UserRoleDataSetTest { | |||
private static final String[] SUPPORTED_PROVIDER_NAMES = { ClassicCryptoService.class.getName(), | |||
SMCryptoService.class.getName() }; | |||
private static final CryptoAlgorithm HASH_ALGORITHM = Crypto.getAlgorithm("SHA256"); | |||
private static final CryptoProvider[] SUPPORTED_PROVIDERS = new CryptoProvider[SUPPORTED_PROVIDER_NAMES.length]; | |||
static { | |||
for (int i = 0; i < SUPPORTED_PROVIDER_NAMES.length; i++) { | |||
SUPPORTED_PROVIDERS[i] = Crypto.getProvider(SUPPORTED_PROVIDER_NAMES[i]); | |||
} | |||
} | |||
@Test | |||
public void testAddUserRoles() { | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setAutoVerifyHash(true); | |||
cryptoConfig.setSupportedProviders(SUPPORTED_PROVIDERS); | |||
cryptoConfig.setHashAlgorithm(HASH_ALGORITHM); | |||
MemoryKVStorage testStorage = new MemoryKVStorage(); | |||
String prefix = "user-roles/"; | |||
UserRoleDataSet userRolesDataset = new UserRoleDataSet(cryptoConfig, prefix, testStorage, testStorage); | |||
BlockchainKeypair bckp = BlockchainKeyGenerator.getInstance().generate(); | |||
String[] authRoles = { "DEFAULT", "MANAGER" }; | |||
userRolesDataset.addUserRoles(bckp.getAddress(), RolesPolicy.UNION, authRoles); | |||
userRolesDataset.commit(); | |||
assertEquals(1, userRolesDataset.getUserCount()); | |||
UserRoles userRoles = userRolesDataset.getUserRoles(bckp.getAddress()); | |||
assertNotNull(userRoles); | |||
String[] roles = userRoles.getRoles(); | |||
assertEquals(2, roles.length); | |||
assertArrayEquals(authRoles, roles); | |||
assertEquals(RolesPolicy.UNION, userRoles.getPolicy()); | |||
} | |||
} |
@@ -0,0 +1,17 @@ | |||
package com.jd.blockchain.ledger; | |||
public class AuthorizationException extends LedgerException { | |||
private static final long serialVersionUID = -4418553411943356320L; | |||
public AuthorizationException(String message) { | |||
super(message); | |||
} | |||
public AuthorizationException(String message, Throwable cause) { | |||
super(message, cause); | |||
} | |||
} |
@@ -9,7 +9,7 @@ import com.jd.blockchain.consts.DataCodes; | |||
public interface LedgerAdminInfo { | |||
@DataField(order = 1, refContract = true) | |||
LedgerMetadata getMetadata(); | |||
LedgerMetadata_V2 getMetadata(); | |||
@DataField(order = 2, refContract = true) | |||
LedgerSettings getSettings(); | |||
@@ -13,7 +13,7 @@ import com.jd.blockchain.crypto.HashDigest; | |||
* @author huanghaiquan | |||
* | |||
*/ | |||
@DataContract(code = DataCodes.METADATA, name = "LEDGER-METADATA-V2") | |||
@DataContract(code = DataCodes.METADATA_V2, name = "LEDGER-METADATA-V2") | |||
public interface LedgerMetadata_V2 extends LedgerMetadata { | |||
/** | |||
@@ -5,6 +5,7 @@ import com.jd.blockchain.binaryproto.DataField; | |||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||
import com.jd.blockchain.consts.DataCodes; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.utils.Bytes; | |||
/** | |||
* 参与方节点; | |||
@@ -30,8 +31,8 @@ public interface ParticipantNode {// extends ConsensusNode, ParticipantInfo { | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 1, primitiveType = PrimitiveType.TEXT) | |||
String getAddress(); | |||
@DataField(order = 1, primitiveType = PrimitiveType.BYTES) | |||
Bytes getAddress(); | |||
/** | |||
* 参与者名称; | |||
@@ -2,13 +2,14 @@ package com.jd.blockchain.transaction; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.net.NetworkAddress; | |||
public class ConsensusParticipantData implements ParticipantNode { | |||
private int id; | |||
private String address; | |||
private Bytes address; | |||
private String name; | |||
@@ -48,11 +49,11 @@ public class ConsensusParticipantData implements ParticipantNode { | |||
this.pubKey = pubKey; | |||
} | |||
public String getAddress() { | |||
public Bytes getAddress() { | |||
return address; | |||
} | |||
public void setAddress(String address) { | |||
public void setAddress(Bytes address) { | |||
this.address = address; | |||
} | |||
@@ -16,7 +16,7 @@ public class ConsensusRealmImpl implements ConsensusRealm { | |||
public ConsensusRealmImpl(ParticipantNode[] nodeList) { | |||
this.nodes = nodeList; | |||
String[] addrs = new String[nodes.length]; | |||
Bytes[] addrs = new Bytes[nodes.length]; | |||
int i = 0; | |||
for (ParticipantNode n : nodes) { | |||
addrs[i++] = n.getAddress(); | |||
@@ -8,19 +8,41 @@ | |||
*/ | |||
package com.jd.blockchain.sdk.converters; | |||
import java.lang.reflect.Field; | |||
import org.apache.commons.codec.binary.Base64; | |||
import com.alibaba.fastjson.JSONArray; | |||
import com.alibaba.fastjson.JSONObject; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.ledger.*; | |||
import com.jd.blockchain.transaction.*; | |||
import com.jd.blockchain.ledger.BlockchainIdentityData; | |||
import com.jd.blockchain.ledger.BytesData; | |||
import com.jd.blockchain.ledger.BytesValue; | |||
import com.jd.blockchain.ledger.BytesValueEncoding; | |||
import com.jd.blockchain.ledger.ContractCodeDeployOperation; | |||
import com.jd.blockchain.ledger.ContractEventSendOperation; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.DataAccountKVSetOperation; | |||
import com.jd.blockchain.ledger.DataAccountRegisterOperation; | |||
import com.jd.blockchain.ledger.DataType; | |||
import com.jd.blockchain.ledger.KVDataEntry; | |||
import com.jd.blockchain.ledger.LedgerInitOperation; | |||
import com.jd.blockchain.ledger.Operation; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.ledger.UserRegisterOperation; | |||
import com.jd.blockchain.transaction.ContractCodeDeployOpTemplate; | |||
import com.jd.blockchain.transaction.ContractEventSendOpTemplate; | |||
import com.jd.blockchain.transaction.DataAccountKVSetOpTemplate; | |||
import com.jd.blockchain.transaction.DataAccountRegisterOpTemplate; | |||
import com.jd.blockchain.transaction.KVData; | |||
import com.jd.blockchain.transaction.LedgerInitOpTemplate; | |||
import com.jd.blockchain.transaction.LedgerInitSettingData; | |||
import com.jd.blockchain.transaction.UserRegisterOpTemplate; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.codec.Base58Utils; | |||
import com.jd.blockchain.utils.codec.HexUtils; | |||
import com.jd.blockchain.utils.io.BytesUtils; | |||
import org.apache.commons.codec.binary.Base64; | |||
import java.lang.reflect.Field; | |||
/** | |||
* | |||
@@ -31,347 +53,348 @@ import java.lang.reflect.Field; | |||
public class ClientResolveUtil { | |||
public static KVDataEntry[] read(KVDataEntry[] kvDataEntries) { | |||
if (kvDataEntries == null || kvDataEntries.length == 0) { | |||
return kvDataEntries; | |||
} | |||
KVDataEntry[] resolveKvDataEntries = new KVDataEntry[kvDataEntries.length]; | |||
// kvDataEntries是代理对象,需要处理 | |||
for (int i = 0; i < kvDataEntries.length; i++) { | |||
KVDataEntry kvDataEntry = kvDataEntries[i]; | |||
String key = kvDataEntry.getKey(); | |||
long version = kvDataEntry.getVersion(); | |||
DataType dataType = kvDataEntry.getType(); | |||
KvData innerKvData = new KvData(key, version, dataType); | |||
Object valueObj = kvDataEntry.getValue(); | |||
switch (dataType) { | |||
case NIL: | |||
break; | |||
case BYTES: | |||
case TEXT: | |||
case JSON: | |||
innerKvData.setValue(valueObj.toString()); | |||
break; | |||
case INT32: | |||
innerKvData.setValue(Integer.parseInt(valueObj.toString())); | |||
break; | |||
case INT64: | |||
innerKvData.setValue(Long.parseLong(valueObj.toString())); | |||
break; | |||
default: | |||
throw new IllegalStateException("Unsupported value type[" + dataType + "] to resolve!"); | |||
} | |||
resolveKvDataEntries[i] = innerKvData; | |||
} | |||
return resolveKvDataEntries; | |||
} | |||
public static Operation read(Operation operation) { | |||
try { | |||
// Class | |||
Class<?> clazz = operation.getClass(); | |||
Field field = clazz.getSuperclass().getDeclaredField("h"); | |||
field.setAccessible(true); | |||
Object object = field.get(operation); | |||
if (object instanceof JSONObject) { | |||
JSONObject jsonObject = (JSONObject) object; | |||
if (jsonObject.containsKey("accountID")) { | |||
return convertDataAccountRegisterOperation(jsonObject); | |||
} else if (jsonObject.containsKey("userID")) { | |||
return convertUserRegisterOperation(jsonObject); | |||
} else if (jsonObject.containsKey("contractID")) { | |||
return convertContractCodeDeployOperation(jsonObject); | |||
} else if (jsonObject.containsKey("writeSet")) { | |||
return convertDataAccountKVSetOperation(jsonObject); | |||
} else if (jsonObject.containsKey("initSetting")) { | |||
return convertLedgerInitOperation(jsonObject); | |||
} else if (jsonObject.containsKey("contractAddress")) { | |||
return convertContractEventSendOperation(jsonObject); | |||
} | |||
} | |||
} catch (Exception e) { | |||
throw new RuntimeException(e); | |||
} | |||
return null; | |||
} | |||
public static Object readValueByBytesValue(BytesValue bytesValue) { | |||
DataType dataType = bytesValue.getType(); | |||
Bytes saveVal = bytesValue.getValue(); | |||
Object showVal; | |||
switch (dataType) { | |||
case BYTES: | |||
// return hex | |||
showVal = HexUtils.encode(saveVal.toBytes()); | |||
break; | |||
case TEXT: | |||
case JSON: | |||
showVal = saveVal.toUTF8String(); | |||
break; | |||
case INT64: | |||
showVal = BytesUtils.toLong(saveVal.toBytes()); | |||
break; | |||
default: | |||
showVal = HexUtils.encode(saveVal.toBytes()); | |||
break; | |||
} | |||
return showVal; | |||
} | |||
public static DataAccountRegisterOperation convertDataAccountRegisterOperation(JSONObject jsonObject) { | |||
JSONObject account = jsonObject.getJSONObject("accountID"); | |||
return new DataAccountRegisterOpTemplate(blockchainIdentity(account)); | |||
} | |||
public static DataAccountKVSetOperation convertDataAccountKVSetOperation(JSONObject jsonObject) { | |||
// 写入集合处理 | |||
JSONArray writeSetObj = jsonObject.getJSONArray("writeSet"); | |||
JSONObject accountAddrObj = jsonObject.getJSONObject("accountAddress"); | |||
String addressBase58 = accountAddrObj.getString("value"); | |||
Bytes address = Bytes.fromBase58(addressBase58); | |||
DataAccountKVSetOpTemplate kvOperation = new DataAccountKVSetOpTemplate(address); | |||
for (int i = 0; i <writeSetObj.size(); i++) { | |||
JSONObject currWriteSetObj = writeSetObj.getJSONObject(i); | |||
long expectedVersion = currWriteSetObj.getLong("expectedVersion"); | |||
JSONObject valueObj = currWriteSetObj.getJSONObject("value"); | |||
String typeStr = valueObj.getString("type"); | |||
String realValBase58 = valueObj.getString("value"); | |||
String key = currWriteSetObj.getString("key"); | |||
DataType dataType = DataType.valueOf(typeStr); | |||
BytesValue bytesValue = BytesData.fromType(dataType, Base58Utils.decode(realValBase58)); | |||
KVData kvData = new KVData(key, bytesValue, expectedVersion); | |||
kvOperation.set(kvData); | |||
} | |||
return kvOperation; | |||
} | |||
public static LedgerInitOperation convertLedgerInitOperation(JSONObject jsonObject) { | |||
JSONObject legerInitObj = jsonObject.getJSONObject("initSetting"); | |||
LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData(); | |||
String ledgerSeedStr = legerInitObj.getString("ledgerSeed"); | |||
// 种子需要做Base64转换 | |||
ledgerInitSettingData.setLedgerSeed(Base64.decodeBase64(BytesUtils.toBytes(ledgerSeedStr))); | |||
String consensusProvider = legerInitObj.getString("consensusProvider"); | |||
ledgerInitSettingData.setConsensusProvider(consensusProvider); | |||
JSONObject cryptoSettingObj = legerInitObj.getJSONObject("cryptoSetting"); | |||
boolean autoVerifyHash = cryptoSettingObj.getBoolean("autoVerifyHash"); | |||
short hashAlgorithm = cryptoSettingObj.getShort("hashAlgorithm"); | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setAutoVerifyHash(autoVerifyHash); | |||
cryptoConfig.setHashAlgorithm(hashAlgorithm); | |||
ledgerInitSettingData.setCryptoSetting(cryptoConfig); | |||
JSONObject consensusSettingsObj = legerInitObj.getJSONObject("consensusSettings"); | |||
Bytes consensusSettings = Bytes.fromBase58(consensusSettingsObj.getString("value")); | |||
ledgerInitSettingData.setConsensusSettings(consensusSettings); | |||
JSONArray consensusParticipantsArray = legerInitObj.getJSONArray("consensusParticipants"); | |||
if (!consensusParticipantsArray.isEmpty()) { | |||
ParticipantNode[] participantNodes = new ParticipantNode[consensusParticipantsArray.size()]; | |||
for (int i = 0; i < consensusParticipantsArray.size(); i++) { | |||
JSONObject currConsensusParticipant = consensusParticipantsArray.getJSONObject(i); | |||
String addressBase58 = currConsensusParticipant.getString("address"); | |||
String name = currConsensusParticipant.getString("name"); | |||
int id = currConsensusParticipant.getInteger("id"); | |||
JSONObject pubKeyObj = currConsensusParticipant.getJSONObject("pubKey"); | |||
String pubKeyBase58 = pubKeyObj.getString("value"); | |||
// 生成ParticipantNode对象 | |||
ParticipantCertData participantCertData = new ParticipantCertData(id, addressBase58, name, new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes())); | |||
participantNodes[i] = participantCertData; | |||
} | |||
ledgerInitSettingData.setConsensusParticipants(participantNodes); | |||
} | |||
return new LedgerInitOpTemplate(ledgerInitSettingData); | |||
} | |||
public static UserRegisterOperation convertUserRegisterOperation(JSONObject jsonObject) { | |||
JSONObject user = jsonObject.getJSONObject("userID"); | |||
return new UserRegisterOpTemplate(blockchainIdentity(user)); | |||
} | |||
public static ContractCodeDeployOperation convertContractCodeDeployOperation(JSONObject jsonObject) { | |||
JSONObject contract = jsonObject.getJSONObject("contractID"); | |||
BlockchainIdentityData blockchainIdentity = blockchainIdentity(contract); | |||
String chainCodeStr = jsonObject.getString("chainCode"); | |||
ContractCodeDeployOpTemplate contractCodeDeployOpTemplate = new ContractCodeDeployOpTemplate(blockchainIdentity, BytesUtils.toBytes(chainCodeStr)); | |||
return contractCodeDeployOpTemplate; | |||
} | |||
public static ContractEventSendOperation convertContractEventSendOperation(JSONObject jsonObject) { | |||
JSONObject contractAddressObj = jsonObject.getJSONObject("contractAddress"); | |||
String contractAddress = contractAddressObj.getString("value"); | |||
String argsStr = jsonObject.getString("args"); | |||
String event = jsonObject.getString("event"); | |||
return new ContractEventSendOpTemplate(Bytes.fromBase58(contractAddress), event, | |||
BytesValueEncoding.encodeArray(new Object[]{argsStr}, null)); | |||
} | |||
private static BlockchainIdentityData blockchainIdentity(JSONObject jsonObject) { | |||
JSONObject addressObj = jsonObject.getJSONObject("address"); | |||
// base58值 | |||
String addressBase58 = addressObj.getString("value"); | |||
Bytes address = Bytes.fromBase58(addressBase58); | |||
JSONObject pubKeyObj = jsonObject.getJSONObject("pubKey"); | |||
// base58值 | |||
String pubKeyBase58 = pubKeyObj.getString("value"); | |||
PubKey pubKey = new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes()); | |||
// 生成对应的对象 | |||
return new BlockchainIdentityData(address, pubKey); | |||
} | |||
public static class CryptoConfig implements CryptoSetting { | |||
private short hashAlgorithm; | |||
private boolean autoVerifyHash; | |||
@Override | |||
public CryptoProvider[] getSupportedProviders() { | |||
return new CryptoProvider[0]; | |||
} | |||
@Override | |||
public short getHashAlgorithm() { | |||
return hashAlgorithm; | |||
} | |||
@Override | |||
public boolean getAutoVerifyHash() { | |||
return autoVerifyHash; | |||
} | |||
public void setHashAlgorithm(short hashAlgorithm) { | |||
this.hashAlgorithm = hashAlgorithm; | |||
} | |||
public void setAutoVerifyHash(boolean autoVerifyHash) { | |||
this.autoVerifyHash = autoVerifyHash; | |||
} | |||
} | |||
public static class ParticipantCertData implements ParticipantNode{ | |||
private int id; | |||
private String address; | |||
private String name; | |||
private PubKey pubKey; | |||
public ParticipantCertData() { | |||
} | |||
public ParticipantCertData(ParticipantNode participantNode) { | |||
this.address = participantNode.getAddress(); | |||
this.name = participantNode.getName(); | |||
this.pubKey = participantNode.getPubKey(); | |||
} | |||
public ParticipantCertData(int id, String address, String name, PubKey pubKey) { | |||
this.id = id; | |||
this.address = address; | |||
this.name = name; | |||
this.pubKey = pubKey; | |||
} | |||
@Override | |||
public String getAddress() { | |||
return address; | |||
} | |||
@Override | |||
public String getName() { | |||
return name; | |||
} | |||
@Override | |||
public PubKey getPubKey() { | |||
return pubKey; | |||
} | |||
public int getId() { | |||
return id; | |||
} | |||
public void setId(int id) { | |||
this.id = id; | |||
} | |||
} | |||
public static class KvData implements KVDataEntry { | |||
private String key; | |||
private long version; | |||
private DataType dataType; | |||
private Object value; | |||
public KvData() { | |||
} | |||
public KvData(String key, long version, DataType dataType) { | |||
this(key, version, dataType, null); | |||
} | |||
public KvData(String key, long version, DataType dataType, Object value) { | |||
this.key = key; | |||
this.version = version; | |||
this.dataType = dataType; | |||
this.value = value; | |||
} | |||
public void setKey(String key) { | |||
this.key = key; | |||
} | |||
public void setVersion(long version) { | |||
this.version = version; | |||
} | |||
public void setDataType(DataType dataType) { | |||
this.dataType = dataType; | |||
} | |||
public void setValue(Object value) { | |||
this.value = value; | |||
} | |||
@Override | |||
public String getKey() { | |||
return key; | |||
} | |||
@Override | |||
public long getVersion() { | |||
return version; | |||
} | |||
@Override | |||
public DataType getType() { | |||
return dataType; | |||
} | |||
@Override | |||
public Object getValue() { | |||
return value; | |||
} | |||
} | |||
public static KVDataEntry[] read(KVDataEntry[] kvDataEntries) { | |||
if (kvDataEntries == null || kvDataEntries.length == 0) { | |||
return kvDataEntries; | |||
} | |||
KVDataEntry[] resolveKvDataEntries = new KVDataEntry[kvDataEntries.length]; | |||
// kvDataEntries是代理对象,需要处理 | |||
for (int i = 0; i < kvDataEntries.length; i++) { | |||
KVDataEntry kvDataEntry = kvDataEntries[i]; | |||
String key = kvDataEntry.getKey(); | |||
long version = kvDataEntry.getVersion(); | |||
DataType dataType = kvDataEntry.getType(); | |||
KvData innerKvData = new KvData(key, version, dataType); | |||
Object valueObj = kvDataEntry.getValue(); | |||
switch (dataType) { | |||
case NIL: | |||
break; | |||
case BYTES: | |||
case TEXT: | |||
case JSON: | |||
innerKvData.setValue(valueObj.toString()); | |||
break; | |||
case INT32: | |||
innerKvData.setValue(Integer.parseInt(valueObj.toString())); | |||
break; | |||
case INT64: | |||
innerKvData.setValue(Long.parseLong(valueObj.toString())); | |||
break; | |||
default: | |||
throw new IllegalStateException("Unsupported value type[" + dataType + "] to resolve!"); | |||
} | |||
resolveKvDataEntries[i] = innerKvData; | |||
} | |||
return resolveKvDataEntries; | |||
} | |||
public static Operation read(Operation operation) { | |||
try { | |||
// Class | |||
Class<?> clazz = operation.getClass(); | |||
Field field = clazz.getSuperclass().getDeclaredField("h"); | |||
field.setAccessible(true); | |||
Object object = field.get(operation); | |||
if (object instanceof JSONObject) { | |||
JSONObject jsonObject = (JSONObject) object; | |||
if (jsonObject.containsKey("accountID")) { | |||
return convertDataAccountRegisterOperation(jsonObject); | |||
} else if (jsonObject.containsKey("userID")) { | |||
return convertUserRegisterOperation(jsonObject); | |||
} else if (jsonObject.containsKey("contractID")) { | |||
return convertContractCodeDeployOperation(jsonObject); | |||
} else if (jsonObject.containsKey("writeSet")) { | |||
return convertDataAccountKVSetOperation(jsonObject); | |||
} else if (jsonObject.containsKey("initSetting")) { | |||
return convertLedgerInitOperation(jsonObject); | |||
} else if (jsonObject.containsKey("contractAddress")) { | |||
return convertContractEventSendOperation(jsonObject); | |||
} | |||
} | |||
} catch (Exception e) { | |||
throw new RuntimeException(e); | |||
} | |||
return null; | |||
} | |||
public static Object readValueByBytesValue(BytesValue bytesValue) { | |||
DataType dataType = bytesValue.getType(); | |||
Bytes saveVal = bytesValue.getValue(); | |||
Object showVal; | |||
switch (dataType) { | |||
case BYTES: | |||
// return hex | |||
showVal = HexUtils.encode(saveVal.toBytes()); | |||
break; | |||
case TEXT: | |||
case JSON: | |||
showVal = saveVal.toUTF8String(); | |||
break; | |||
case INT64: | |||
showVal = BytesUtils.toLong(saveVal.toBytes()); | |||
break; | |||
default: | |||
showVal = HexUtils.encode(saveVal.toBytes()); | |||
break; | |||
} | |||
return showVal; | |||
} | |||
public static DataAccountRegisterOperation convertDataAccountRegisterOperation(JSONObject jsonObject) { | |||
JSONObject account = jsonObject.getJSONObject("accountID"); | |||
return new DataAccountRegisterOpTemplate(blockchainIdentity(account)); | |||
} | |||
public static DataAccountKVSetOperation convertDataAccountKVSetOperation(JSONObject jsonObject) { | |||
// 写入集合处理 | |||
JSONArray writeSetObj = jsonObject.getJSONArray("writeSet"); | |||
JSONObject accountAddrObj = jsonObject.getJSONObject("accountAddress"); | |||
String addressBase58 = accountAddrObj.getString("value"); | |||
Bytes address = Bytes.fromBase58(addressBase58); | |||
DataAccountKVSetOpTemplate kvOperation = new DataAccountKVSetOpTemplate(address); | |||
for (int i = 0; i < writeSetObj.size(); i++) { | |||
JSONObject currWriteSetObj = writeSetObj.getJSONObject(i); | |||
long expectedVersion = currWriteSetObj.getLong("expectedVersion"); | |||
JSONObject valueObj = currWriteSetObj.getJSONObject("value"); | |||
String typeStr = valueObj.getString("type"); | |||
String realValBase58 = valueObj.getString("value"); | |||
String key = currWriteSetObj.getString("key"); | |||
DataType dataType = DataType.valueOf(typeStr); | |||
BytesValue bytesValue = BytesData.fromType(dataType, Base58Utils.decode(realValBase58)); | |||
KVData kvData = new KVData(key, bytesValue, expectedVersion); | |||
kvOperation.set(kvData); | |||
} | |||
return kvOperation; | |||
} | |||
public static LedgerInitOperation convertLedgerInitOperation(JSONObject jsonObject) { | |||
JSONObject legerInitObj = jsonObject.getJSONObject("initSetting"); | |||
LedgerInitSettingData ledgerInitSettingData = new LedgerInitSettingData(); | |||
String ledgerSeedStr = legerInitObj.getString("ledgerSeed"); | |||
// 种子需要做Base64转换 | |||
ledgerInitSettingData.setLedgerSeed(Base64.decodeBase64(BytesUtils.toBytes(ledgerSeedStr))); | |||
String consensusProvider = legerInitObj.getString("consensusProvider"); | |||
ledgerInitSettingData.setConsensusProvider(consensusProvider); | |||
JSONObject cryptoSettingObj = legerInitObj.getJSONObject("cryptoSetting"); | |||
boolean autoVerifyHash = cryptoSettingObj.getBoolean("autoVerifyHash"); | |||
short hashAlgorithm = cryptoSettingObj.getShort("hashAlgorithm"); | |||
CryptoConfig cryptoConfig = new CryptoConfig(); | |||
cryptoConfig.setAutoVerifyHash(autoVerifyHash); | |||
cryptoConfig.setHashAlgorithm(hashAlgorithm); | |||
ledgerInitSettingData.setCryptoSetting(cryptoConfig); | |||
JSONObject consensusSettingsObj = legerInitObj.getJSONObject("consensusSettings"); | |||
Bytes consensusSettings = Bytes.fromBase58(consensusSettingsObj.getString("value")); | |||
ledgerInitSettingData.setConsensusSettings(consensusSettings); | |||
JSONArray consensusParticipantsArray = legerInitObj.getJSONArray("consensusParticipants"); | |||
if (!consensusParticipantsArray.isEmpty()) { | |||
ParticipantNode[] participantNodes = new ParticipantNode[consensusParticipantsArray.size()]; | |||
for (int i = 0; i < consensusParticipantsArray.size(); i++) { | |||
JSONObject currConsensusParticipant = consensusParticipantsArray.getJSONObject(i); | |||
String addressBase58 = currConsensusParticipant.getString("address"); | |||
String name = currConsensusParticipant.getString("name"); | |||
int id = currConsensusParticipant.getInteger("id"); | |||
JSONObject pubKeyObj = currConsensusParticipant.getJSONObject("pubKey"); | |||
String pubKeyBase58 = pubKeyObj.getString("value"); | |||
// 生成ParticipantNode对象 | |||
ParticipantCertData participantCertData = new ParticipantCertData(id, Bytes.fromBase58(addressBase58), | |||
name, new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes())); | |||
participantNodes[i] = participantCertData; | |||
} | |||
ledgerInitSettingData.setConsensusParticipants(participantNodes); | |||
} | |||
return new LedgerInitOpTemplate(ledgerInitSettingData); | |||
} | |||
public static UserRegisterOperation convertUserRegisterOperation(JSONObject jsonObject) { | |||
JSONObject user = jsonObject.getJSONObject("userID"); | |||
return new UserRegisterOpTemplate(blockchainIdentity(user)); | |||
} | |||
public static ContractCodeDeployOperation convertContractCodeDeployOperation(JSONObject jsonObject) { | |||
JSONObject contract = jsonObject.getJSONObject("contractID"); | |||
BlockchainIdentityData blockchainIdentity = blockchainIdentity(contract); | |||
String chainCodeStr = jsonObject.getString("chainCode"); | |||
ContractCodeDeployOpTemplate contractCodeDeployOpTemplate = new ContractCodeDeployOpTemplate(blockchainIdentity, | |||
BytesUtils.toBytes(chainCodeStr)); | |||
return contractCodeDeployOpTemplate; | |||
} | |||
public static ContractEventSendOperation convertContractEventSendOperation(JSONObject jsonObject) { | |||
JSONObject contractAddressObj = jsonObject.getJSONObject("contractAddress"); | |||
String contractAddress = contractAddressObj.getString("value"); | |||
String argsStr = jsonObject.getString("args"); | |||
String event = jsonObject.getString("event"); | |||
return new ContractEventSendOpTemplate(Bytes.fromBase58(contractAddress), event, | |||
BytesValueEncoding.encodeArray(new Object[] { argsStr }, null)); | |||
} | |||
private static BlockchainIdentityData blockchainIdentity(JSONObject jsonObject) { | |||
JSONObject addressObj = jsonObject.getJSONObject("address"); | |||
// base58值 | |||
String addressBase58 = addressObj.getString("value"); | |||
Bytes address = Bytes.fromBase58(addressBase58); | |||
JSONObject pubKeyObj = jsonObject.getJSONObject("pubKey"); | |||
// base58值 | |||
String pubKeyBase58 = pubKeyObj.getString("value"); | |||
PubKey pubKey = new PubKey(Bytes.fromBase58(pubKeyBase58).toBytes()); | |||
// 生成对应的对象 | |||
return new BlockchainIdentityData(address, pubKey); | |||
} | |||
public static class CryptoConfig implements CryptoSetting { | |||
private short hashAlgorithm; | |||
private boolean autoVerifyHash; | |||
@Override | |||
public CryptoProvider[] getSupportedProviders() { | |||
return new CryptoProvider[0]; | |||
} | |||
@Override | |||
public short getHashAlgorithm() { | |||
return hashAlgorithm; | |||
} | |||
@Override | |||
public boolean getAutoVerifyHash() { | |||
return autoVerifyHash; | |||
} | |||
public void setHashAlgorithm(short hashAlgorithm) { | |||
this.hashAlgorithm = hashAlgorithm; | |||
} | |||
public void setAutoVerifyHash(boolean autoVerifyHash) { | |||
this.autoVerifyHash = autoVerifyHash; | |||
} | |||
} | |||
public static class ParticipantCertData implements ParticipantNode { | |||
private int id; | |||
private Bytes address; | |||
private String name; | |||
private PubKey pubKey; | |||
public ParticipantCertData() { | |||
} | |||
public ParticipantCertData(ParticipantNode participantNode) { | |||
this.address = participantNode.getAddress(); | |||
this.name = participantNode.getName(); | |||
this.pubKey = participantNode.getPubKey(); | |||
} | |||
public ParticipantCertData(int id, Bytes address, String name, PubKey pubKey) { | |||
this.id = id; | |||
this.address = address; | |||
this.name = name; | |||
this.pubKey = pubKey; | |||
} | |||
@Override | |||
public Bytes getAddress() { | |||
return address; | |||
} | |||
@Override | |||
public String getName() { | |||
return name; | |||
} | |||
@Override | |||
public PubKey getPubKey() { | |||
return pubKey; | |||
} | |||
public int getId() { | |||
return id; | |||
} | |||
public void setId(int id) { | |||
this.id = id; | |||
} | |||
} | |||
public static class KvData implements KVDataEntry { | |||
private String key; | |||
private long version; | |||
private DataType dataType; | |||
private Object value; | |||
public KvData() { | |||
} | |||
public KvData(String key, long version, DataType dataType) { | |||
this(key, version, dataType, null); | |||
} | |||
public KvData(String key, long version, DataType dataType, Object value) { | |||
this.key = key; | |||
this.version = version; | |||
this.dataType = dataType; | |||
this.value = value; | |||
} | |||
public void setKey(String key) { | |||
this.key = key; | |||
} | |||
public void setVersion(long version) { | |||
this.version = version; | |||
} | |||
public void setDataType(DataType dataType) { | |||
this.dataType = dataType; | |||
} | |||
public void setValue(Object value) { | |||
this.value = value; | |||
} | |||
@Override | |||
public String getKey() { | |||
return key; | |||
} | |||
@Override | |||
public long getVersion() { | |||
return version; | |||
} | |||
@Override | |||
public DataType getType() { | |||
return dataType; | |||
} | |||
@Override | |||
public Object getValue() { | |||
return value; | |||
} | |||
} | |||
} |
@@ -12,11 +12,6 @@ import com.jd.blockchain.utils.io.BytesMap; | |||
public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, KVStorageService, BytesMap<Bytes> { | |||
// private Set<String> keys = new HashSet<>(); | |||
// private Set<String> keys = Collections.synchronizedSet(new HashSet<>()); | |||
// private Map<String, Object> storageMap = new ConcurrentHashMap<>(); | |||
private ExistancePolicyKVStorageMap exStorage = new ExistancePolicyKVStorageMap(); | |||
private VersioningKVStorageMap verStorage = new VersioningKVStorageMap(); | |||
@@ -38,10 +33,6 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, | |||
@Override | |||
public long set(Bytes key, byte[] value, long version) { | |||
return verStorage.set(key, value, version); | |||
// if (v > -1) { | |||
// keys.add(key); | |||
// } | |||
// return v; | |||
} | |||
@Override | |||
@@ -57,10 +48,6 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, | |||
@Override | |||
public boolean set(Bytes key, byte[] value, ExPolicy ex) { | |||
return exStorage.set(key, value, ex); | |||
// if (ok) { | |||
// keys.add(key); | |||
// } | |||
// return ok; | |||
} | |||
@Override | |||
@@ -81,12 +68,10 @@ public class MemoryKVStorage implements ExPolicyKVStorage, VersioningKVStorage, | |||
HashSet<Bytes> keySet = new HashSet<>(exStorage.keySet()); | |||
keySet.addAll(verStorage.keySet()); | |||
return keySet; | |||
// return storageMap.keySet(); | |||
} | |||
public int getStorageCount() { | |||
return exStorage.getCount() + verStorage.getCount(); | |||
// return storageMap.size(); | |||
} | |||
// public void printStoragedKeys() { | |||
@@ -0,0 +1,35 @@ | |||
package com.jd.blockchain.storage.service.utils; | |||
import com.jd.blockchain.storage.service.VersioningKVEntry; | |||
import com.jd.blockchain.utils.Bytes; | |||
public class VersioningKVData implements VersioningKVEntry { | |||
private Bytes key; | |||
private long version; | |||
private byte[] value; | |||
public VersioningKVData(Bytes key, long version, byte[] value) { | |||
this.key = key; | |||
this.version = version; | |||
this.value = value; | |||
} | |||
@Override | |||
public Bytes getKey() { | |||
return key; | |||
} | |||
@Override | |||
public long getVersion() { | |||
return version; | |||
} | |||
@Override | |||
public byte[] getValue() { | |||
return value; | |||
} | |||
} |
@@ -215,38 +215,6 @@ public class VersioningKVStorageMap implements VersioningKVStorage, BytesMap<Byt | |||
} | |||
} | |||
} | |||
private static class VersioningKVData implements VersioningKVEntry { | |||
private Bytes key; | |||
private long version; | |||
private byte[] value; | |||
public VersioningKVData(Bytes key, long version, byte[] value) { | |||
this.key = key; | |||
this.version = version; | |||
this.value = value; | |||
} | |||
@Override | |||
public Bytes getKey() { | |||
return key; | |||
} | |||
@Override | |||
public long getVersion() { | |||
return version; | |||
} | |||
@Override | |||
public byte[] getValue() { | |||
return value; | |||
} | |||
} | |||
// private static class CachedSetEntry implements VersioningKVEntry { | |||
// | |||
@@ -6,16 +6,23 @@ import java.util.Map; | |||
import java.util.Properties; | |||
import java.util.concurrent.ConcurrentHashMap; | |||
import com.jd.blockchain.crypto.*; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import org.springframework.core.io.ClassPathResource; | |||
import com.jd.blockchain.consensus.ConsensusProvider; | |||
import com.jd.blockchain.consensus.ConsensusSettings; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
import com.jd.blockchain.crypto.AsymmetricKeypair; | |||
import com.jd.blockchain.crypto.Crypto; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.CryptoProvider; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.crypto.PrivKey; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.crypto.SignatureDigest; | |||
import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.ledger.core.CryptoConfig; | |||
import com.jd.blockchain.ledger.core.LedgerInitDecision; | |||
import com.jd.blockchain.ledger.core.LedgerInitProposal; | |||
@@ -29,6 +36,8 @@ import com.jd.blockchain.tools.initializer.Prompter; | |||
import com.jd.blockchain.tools.initializer.web.InitConsensusServiceFactory; | |||
import com.jd.blockchain.tools.initializer.web.LedgerInitConsensusService; | |||
import com.jd.blockchain.tools.initializer.web.LedgerInitializeWebController; | |||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.concurrent.ThreadInvoker; | |||
import com.jd.blockchain.utils.concurrent.ThreadInvoker.AsyncCallback; | |||
import com.jd.blockchain.utils.io.FileUtils; | |||
@@ -229,7 +238,7 @@ public class Utils { | |||
private int id; | |||
private String address; | |||
private Bytes address; | |||
private String name; | |||
@@ -243,7 +252,7 @@ public class Utils { | |||
this.id = id; | |||
this.name = name; | |||
this.pubKey = pubKey; | |||
this.address = pubKey.toBase58(); | |||
this.address = AddressEncoding.generateAddress(pubKey); | |||
} | |||
@Override | |||
@@ -252,7 +261,7 @@ public class Utils { | |||
} | |||
@Override | |||
public String getAddress() { | |||
public Bytes getAddress() { | |||
return address; | |||
} | |||
@@ -166,7 +166,8 @@ public class LedgerInitCommand { | |||
// generate binding config; | |||
BindingConfig bindingConf = new BindingConfig(); | |||
bindingConf.getParticipant().setAddress(ledgerInitProperties.getConsensusParticipant(currId).getAddress()); | |||
bindingConf.getParticipant() | |||
.setAddress(ledgerInitProperties.getConsensusParticipant(currId).getAddress().toBase58()); | |||
String encodedPrivKey = KeyGenCommand.encodePrivKey(privKey, base58Pwd); | |||
bindingConf.getParticipant().setPk(encodedPrivKey); | |||
bindingConf.getParticipant().setPassword(base58Pwd); | |||
@@ -9,12 +9,11 @@ import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Properties; | |||
import org.springframework.util.ResourceUtils; | |||
import com.jd.blockchain.crypto.AddressEncoding; | |||
import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.ledger.ParticipantNode; | |||
import com.jd.blockchain.tools.keygen.KeyGenCommand; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.PropertiesUtils; | |||
import com.jd.blockchain.utils.codec.HexUtils; | |||
import com.jd.blockchain.utils.io.FileUtils; | |||
@@ -250,7 +249,7 @@ public class LedgerInitProperties { | |||
private int id; | |||
private String address; | |||
private Bytes address; | |||
private String name; | |||
@@ -271,7 +270,7 @@ public class LedgerInitProperties { | |||
} | |||
@Override | |||
public String getAddress() { | |||
public Bytes getAddress() { | |||
return address; | |||
} | |||
@@ -305,7 +304,7 @@ public class LedgerInitProperties { | |||
public void setPubKey(PubKey pubKey) { | |||
this.pubKey = pubKey; | |||
this.address = AddressEncoding.generateAddress(pubKey).toBase58(); | |||
this.address = AddressEncoding.generateAddress(pubKey); | |||
} | |||
} | |||