use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.
the class ContractResource method contractCollection.
@POST
@Path("/collection")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "收藏智能合约地址/修改备注名称")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success") })
public RpcClientResult contractCollection(@ApiParam(name = "collection", value = "收藏智能合约地址/修改备注名称", required = true) ContractCollection collection) {
try {
if (collection == null) {
return Result.getFailed(ContractErrorCode.NULL_PARAMETER).toRpcClientResult();
}
// 钱包账户地址
String address = collection.getAccountAddress();
if (StringUtils.isBlank(address)) {
return Result.getFailed(LedgerErrorCode.NULL_PARAMETER).toRpcClientResult();
}
Result<Account> accountResult = accountService.getAccount(address);
if (accountResult.isFailed()) {
return accountResult.toRpcClientResult();
}
// 合约地址
String contractAddress = collection.getContractAddress();
if (!AddressTool.validAddress(contractAddress)) {
return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
}
byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
if (!ContractLedgerUtil.isExistContractAddress(contractAddressBytes)) {
return Result.getFailed(ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST).toRpcClientResult();
}
// 备注名称
String remarkName = collection.getRemarkName();
// 获取合约地址的基本信息, 用到两个信息 - 创建者、创建交易hash
Result<ContractAddressInfoPo> contractAddressInfoPoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
ContractAddressInfoPo contractAddressInfoPo = contractAddressInfoPoResult.getData();
if (contractAddressInfoPo == null) {
return Result.getFailed(ContractErrorCode.DATA_NOT_FOUND).toRpcClientResult();
}
// 获取该合约的收藏数据
Result<ContractCollectionInfoPo> collectionInfoPoResult = contractCollectionStorageService.getContractAddress(contractAddressBytes);
ContractCollectionInfoPo po = collectionInfoPoResult.getData();
Map<String, String> collectorMap;
if (po != null) {
collectorMap = po.getCollectorMap();
if (collectorMap.containsKey(address)) {
String preRemarkName = collectorMap.get(address);
if (preRemarkName.equals(remarkName)) {
// 收藏者的信息没有变化,直接返回
return Result.getSuccess().toRpcClientResult();
}
} else {
collectorMap.put(address, EMPTY);
}
} else {
po = new ContractCollectionInfoPo();
po.setCreater(contractAddressInfoPo.getSender());
po.setContractAddress(contractAddress);
po.setBlockHeight(contractAddressInfoPo.getBlockHeight());
Transaction tx = ledgerService.getTx(contractAddressInfoPo.getCreateTxHash());
if (tx == null) {
return Result.getFailed(ContractErrorCode.TX_NOT_EXIST).toRpcClientResult();
}
po.setCreateTime(tx.getTime());
collectorMap = MapUtil.createHashMap(4);
collectorMap.put(address, EMPTY);
po.setCollectorMap(collectorMap);
}
// 备注名
if (StringUtils.isNotBlank(remarkName)) {
// if (!StringUtils.validAlias(remarkName)) {
// return Result.getFailed(ContractErrorCode.CONTRACT_NAME_FORMAT_INCORRECT).toRpcClientResult();
// }
collectorMap.put(address, remarkName);
}
Result result = contractCollectionStorageService.saveContractAddress(contractAddressBytes, po);
return result.toRpcClientResult();
} catch (Exception e) {
Log.error(e);
return Result.getFailed(LedgerErrorCode.SYS_UNKOWN_EXCEPTION).toRpcClientResult();
}
}
use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.
the class CallContractTxProcessor method onCommit.
@Override
public Result onCommit(CallContractTransaction tx, Object secondaryData) {
try {
ContractResult contractResult = tx.getContractResult();
// 保存调用合约交易的UTXO
Result utxoResult = contractUtxoService.saveUtxoForContractAddress(tx);
if (utxoResult.isFailed()) {
Log.error("save confirmed contract utxo error, reason is {}.", utxoResult.getMsg());
return utxoResult;
}
long blockHeight = tx.getBlockHeight();
/**
* 保存子交易到全网账本、合约账本、本地账本
*/
Collection<ContractTransferTransaction> contractTransferTxs = tx.getContractTransferTxs();
if (contractTransferTxs != null && contractTransferTxs.size() > 0) {
for (ContractTransferTransaction transferTx : contractTransferTxs) {
try {
transferTx.setBlockHeight(blockHeight);
Result result = ledgerService.saveTx(transferTx);
if (result.isFailed()) {
Log.error("save contract transfer tx to ledger error. msg: {}", result.getMsg());
return result;
}
result = contractService.saveContractTransferTx(transferTx);
if (result.isFailed()) {
Log.error("save contract transfer tx to contract ledger error. msg: {}", result.getMsg());
return result;
}
result = accountLedgerService.saveConfirmedTransaction(transferTx);
if (result.isFailed()) {
Log.error("save contract transfer tx to account ledger error. msg: {}", result.getMsg());
return result;
}
} catch (Exception e) {
e.printStackTrace();
Log.error("save contract transfer tx error. msg: {}", e.getMessage());
return Result.getFailed();
}
}
}
// 保存代币交易
CallContractData callContractData = tx.getTxData();
byte[] contractAddress = callContractData.getContractAddress();
Result<ContractAddressInfoPo> contractAddressInfoPoResult = contractAddressStorageService.getContractAddressInfo(contractAddress);
if (contractAddressInfoPoResult.isFailed()) {
return contractAddressInfoPoResult;
}
ContractAddressInfoPo contractAddressInfoPo = contractAddressInfoPoResult.getData();
if (contractAddressInfoPo == null) {
return Result.getFailed(ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST);
}
contractResult.setNrc20(contractAddressInfoPo.isNrc20());
BlockHeader blockHeader = tx.getBlockHeader();
byte[] newestStateRoot = blockHeader.getStateRoot();
// 获取合约当前状态
ProgramStatus status = vmHelper.getContractStatus(newestStateRoot, contractAddress);
boolean isTerminatedContract = ContractUtil.isTerminatedContract(status.ordinal());
// 处理合约执行失败 - 没有transferEvent的情况, 直接从数据库中获取, 若是本地创建的交易,获取到修改为失败交易
if (isTerminatedContract || !contractResult.isSuccess()) {
if (contractAddressInfoPo != null && contractAddressInfoPo.isNrc20() && ContractUtil.isTransferMethod(callContractData.getMethodName())) {
byte[] txHashBytes = tx.getHash().serialize();
byte[] infoKey = ArraysTool.concatenate(callContractData.getSender(), txHashBytes, new VarInt(0).encode());
Result<ContractTokenTransferInfoPo> infoResult = contractTokenTransferStorageService.getTokenTransferInfo(infoKey);
ContractTokenTransferInfoPo po = infoResult.getData();
if (po != null) {
po.setStatus((byte) 2);
contractTokenTransferStorageService.saveTokenTransferInfo(infoKey, po);
// 刷新token余额
if (isTerminatedContract) {
// 终止的合约,回滚token余额
this.rollbackContractToken(po);
contractResult.setError(true);
contractResult.setErrorMessage("this contract has been terminated");
} else {
if (po.getFrom() != null) {
vmHelper.refreshTokenBalance(newestStateRoot, contractAddressInfoPo, AddressTool.getStringAddressByBytes(po.getFrom()), po.getContractAddress());
}
if (po.getTo() != null) {
vmHelper.refreshTokenBalance(newestStateRoot, contractAddressInfoPo, AddressTool.getStringAddressByBytes(po.getTo()), po.getContractAddress());
}
}
}
}
}
if (!isTerminatedContract) {
// 处理合约事件
vmHelper.dealEvents(newestStateRoot, tx, contractResult, contractAddressInfoPo);
}
// 保存合约执行结果
contractService.saveContractExecuteResult(tx.getHash(), contractResult);
} catch (Exception e) {
Log.error("save call contract tx error.", e);
return Result.getFailed();
}
return Result.getSuccess();
}
use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.
the class DeleteContractTxValidator method validate.
@Override
public ValidateResult validate(DeleteContractTransaction tx) throws NulsException {
DeleteContractData txData = tx.getTxData();
byte[] sender = txData.getSender();
byte[] contractAddressBytes = txData.getContractAddress();
Set<String> addressSet = SignatureUtil.getAddressFromTX(tx);
if (!addressSet.contains(AddressTool.getStringAddressByBytes(sender))) {
Log.error("contract delete error: The contract deleter is not the transaction creator.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TX_DATA_VALIDATION_ERROR);
}
Result<ContractAddressInfoPo> contractAddressInfoPoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
if (contractAddressInfoPoResult.isFailed()) {
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), contractAddressInfoPoResult.getErrorCode());
}
ContractAddressInfoPo contractAddressInfoPo = contractAddressInfoPoResult.getData();
if (contractAddressInfoPo == null) {
Log.error("contract delete error: The contract does not exist.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST);
}
if (!ArraysTool.arrayEquals(sender, contractAddressInfoPo.getSender())) {
Log.error("contract delete error: The contract deleter is not the contract creator.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TX_DATA_VALIDATION_ERROR);
}
Result<ContractBalance> result = contractUtxoService.getBalance(contractAddressBytes);
ContractBalance balance = (ContractBalance) result.getData();
if (balance == null) {
Log.error("contract delete error: That balance of the contract is abnormal.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), TransactionErrorCode.TX_DATA_VALIDATION_ERROR);
}
Na totalBalance = balance.getBalance();
if (totalBalance.compareTo(Na.ZERO) != 0) {
Log.error("contract delete error: The balance of the contract is not 0.");
return ValidateResult.getFailedResult(this.getClass().getSimpleName(), ContractErrorCode.CONTRACT_DELETE_BALANCE);
}
return ValidateResult.getSuccessResult();
}
use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.
the class ContractAddressStorageServiceImpl method getContractInfoList.
@Override
public Result<List<ContractAddressInfoPo>> getContractInfoList(byte[] creater) {
List<Entry<byte[], ContractAddressInfoPo>> list = dbService.entryList(ContractStorageConstant.DB_NAME_CONTRACT_ADDRESS, ContractAddressInfoPo.class);
if (list == null || list.size() == 0) {
return Result.getFailed(KernelErrorCode.DATA_NOT_FOUND);
}
List<ContractAddressInfoPo> resultList = new ArrayList<>();
ContractAddressInfoPo po;
for (Entry<byte[], ContractAddressInfoPo> entry : list) {
po = entry.getValue();
if (Arrays.equals(creater, po.getSender())) {
po.setContractAddress(entry.getKey());
resultList.add(po);
}
}
Result<List<ContractAddressInfoPo>> result = Result.getSuccess();
result.setData(resultList);
return result;
}
use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.
the class ContractTxServiceImpl method validateContractDeleteTx.
/**
* 验证创建删除智能合约的交易
*
* @param sender 交易创建者
* @param contractAddress 合约地址
* @return
*/
@Override
public Result validateContractDeleteTx(String sender, String contractAddress) {
AssertUtil.canNotEmpty(sender, "the sender address can not be empty");
AssertUtil.canNotEmpty(contractAddress, "the contractAddress can not be empty");
byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
Result<ContractAddressInfoPo> contractAddressInfoPoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
if (contractAddressInfoPoResult.isFailed()) {
return contractAddressInfoPoResult;
}
ContractAddressInfoPo contractAddressInfoPo = contractAddressInfoPoResult.getData();
if (contractAddressInfoPo == null) {
return Result.getFailed(ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST);
}
BlockHeader blockHeader = NulsContext.getInstance().getBestBlock().getHeader();
// 当前区块状态根
byte[] stateRoot = ContractUtil.getStateRoot(blockHeader);
// 获取合约当前状态
ProgramStatus status = vmHelper.getContractStatus(stateRoot, contractAddressBytes);
boolean isTerminatedContract = ContractUtil.isTerminatedContract(status.ordinal());
if (isTerminatedContract) {
return Result.getFailed(ContractErrorCode.CONTRACT_DELETED);
}
byte[] senderBytes = AddressTool.getAddress(sender);
if (!ArraysTool.arrayEquals(senderBytes, contractAddressInfoPo.getSender())) {
return Result.getFailed(ContractErrorCode.CONTRACT_DELETE_CREATER);
}
Result<ContractBalance> result = contractBalanceManager.getBalance(contractAddressBytes);
ContractBalance balance = (ContractBalance) result.getData();
if (balance == null) {
return result;
}
Na totalBalance = balance.getBalance();
if (totalBalance.compareTo(Na.ZERO) != 0) {
return Result.getFailed(ContractErrorCode.CONTRACT_DELETE_BALANCE);
}
return Result.getSuccess();
}
Aggregations