use of com.jd.blockchain.contract.ContractException in project jdchain-core by blockchain-jd-com.
the class ContractCodeDeployOperationHandle method doProcess.
@Override
protected void doProcess(ContractCodeDeployOperation op, LedgerTransactionContext transactionContext, TransactionRequestExtension requestContext, LedgerQuery ledger, OperationHandleContext handleContext, EventManager manager) {
// TODO: 请求者应该提供合约账户的公钥签名,以确保注册人对注册的地址和公钥具有合法的使用权;
// 权限校验;
SecurityPolicy securityPolicy = SecurityContext.getContextUsersPolicy();
securityPolicy.checkEndpointPermission(LedgerPermission.UPGRADE_CONTRACT, MultiIDsPolicy.AT_LEAST_ONE);
// 校验合约内容
byte[] chainCode = op.getChainCode();
if (chainCode == null || chainCode.length == 0) {
throw new ContractException(String.format("Contract[%s] content is empty !!!", op.getContractID().getAddress().toBase58()));
}
if (chainCode.length > MAX_SIZE_OF_CONTRACT) {
throw new ContractException(String.format("Contract[%s] content is great than the max size[%s]!", op.getContractID().getAddress().toBase58(), MAX_SIZE_OF_CONTRACT));
}
// 校验合约代码,不通过会抛出异常
try {
if ((null == op.getLang() || op.getLang().equals(ContractLang.Java)) && !CONTRACT_PROCESSOR.verify(chainCode)) {
throw new ContractException(String.format("Contract[%s] verify fail !!!", op.getContractID().getAddress().toBase58()));
}
} catch (Exception e) {
throw new ContractException(String.format("Contract[%s] verify fail !!!", op.getContractID().getAddress().toBase58()));
}
// 校验合约状态
ContractAccount contract = transactionContext.getDataset().getContractAccountSet().getAccount(op.getContractID().getAddress());
if (null != contract && contract.getState() != AccountState.NORMAL) {
throw new IllegalTransactionException("Can not change contract[" + contract.getAddress() + "] in " + contract.getState() + " state.");
}
// chainCodeVersion != null? then use it;
long contractVersion = op.getChainCodeVersion();
if (contractVersion != -1L) {
long rst = 0;
rst = ((ContractAccountSetEditor) (transactionContext.getDataset().getContractAccountSet())).update(op.getContractID().getAddress(), op.getChainCode(), contractVersion, op.getLang());
if (rst < 0) {
throw new ContractVersionConflictException();
}
} else {
ContractAccount account = ((ContractAccountSetEditor) (transactionContext.getDataset().getContractAccountSet())).deploy(op.getContractID().getAddress(), op.getContractID().getPubKey(), op.getAddressSignature(), op.getChainCode(), op.getLang());
LOGGER.info("Update contract {}:{}", account.getAddress().toString(), account.getChainCodeVersion());
account.setPermission(new AccountDataPermission(AccountType.CONTRACT, requestContext.getEndpointAddresses().toArray(new Bytes[0])));
}
}
use of com.jd.blockchain.contract.ContractException in project jdchain-core by blockchain-jd-com.
the class LedgerQueryController method getDataEntries.
@RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, path = GET_KV_VERSION_LIST)
@Override
public TypedKVEntry[] getDataEntries(@PathVariable(name = "ledgerHash") HashDigest ledgerHash, @PathVariable(name = "address") String address, @RequestBody KVInfoVO kvInfoVO) {
// parse kvInfoVO;
List<String> keyList = new ArrayList<>();
List<Long> versionList = new ArrayList<>();
if (kvInfoVO != null) {
for (KVDataVO kvDataVO : kvInfoVO.getData()) {
for (Long version : kvDataVO.getVersion()) {
keyList.add(kvDataVO.getKey());
versionList.add(version);
}
}
}
String[] keys = keyList.toArray(new String[keyList.size()]);
Long[] versions = versionList.toArray(new Long[versionList.size()]);
if (keys == null || keys.length == 0) {
return null;
}
if (versions == null || versions.length == 0) {
return null;
}
if (keys.length != versions.length) {
throw new ContractException("keys.length!=versions.length!");
}
LedgerQuery ledger = ledgerService.getLedger(ledgerHash);
LedgerBlock block = ledger.getLatestBlock();
DataAccountSet dataAccountSet = ledger.getDataAccountSet(block);
DataAccount dataAccount = dataAccountSet.getAccount(Bytes.fromBase58(address));
if (dataAccount == null) {
return null;
}
TypedKVEntry[] entries = new TypedKVEntry[keys.length];
long ver = -1;
for (int i = 0; i < entries.length; i++) {
// ver = dataAccount.getDataVersion(Bytes.fromString(keys[i]));
ver = versions[i];
if (ver < 0) {
entries[i] = new TypedKVData(keys[i], -1, null);
} else {
if (dataAccount.getDataset().getDataCount() == 0 || dataAccount.getDataset().getValue(keys[i], ver) == null) {
// is the address is not exist; the result is null;
entries[i] = new TypedKVData(keys[i], -1, null);
} else {
BytesValue value = dataAccount.getDataset().getValue(keys[i], ver);
entries[i] = new TypedKVData(keys[i], ver, value);
}
}
}
return entries;
}
use of com.jd.blockchain.contract.ContractException in project jdchain-core by blockchain-jd-com.
the class InstantiatedContractCode method doProcessEvent.
@Override
protected BytesValue doProcessEvent(Object contractInstance, ContractEventContext eventContext) {
// 反序列化参数;
Method handleMethod = contractDefinition.getType().getHandleMethod(eventContext.getEvent());
if (handleMethod == null) {
throw new ContractException(String.format("Contract[%s:%s] has no handle method to handle event[%s]!", getAddress().toString(), contractDefinition.getType().getName(), eventContext.getEvent()));
}
BytesValueList bytesValues = eventContext.getArgs();
Object[] args = BytesValueEncoding.decode(bytesValues, handleMethod.getParameterTypes());
return BytesValueEncoding.encodeSingle(ReflectionUtils.invokeMethod(handleMethod, contractInstance, args), handleMethod.getReturnType());
}
Aggregations