Search in sources :

Example 16 with ContractAddressInfoPo

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();
    }
}
Also used : Account(io.nuls.account.model.Account) ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) CreateContractTransaction(io.nuls.contract.entity.tx.CreateContractTransaction) ContractCollectionInfoPo(io.nuls.contract.storage.po.ContractCollectionInfoPo) NulsException(io.nuls.kernel.exception.NulsException) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) ContractResult(io.nuls.contract.dto.ContractResult)

Example 17 with ContractAddressInfoPo

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();
}
Also used : ContractResult(io.nuls.contract.dto.ContractResult) VarInt(io.nuls.kernel.utils.VarInt) CallContractData(io.nuls.contract.entity.txdata.CallContractData) IOException(java.io.IOException) ContractResult(io.nuls.contract.dto.ContractResult) ValidateResult(io.nuls.kernel.validate.ValidateResult) Result(io.nuls.kernel.model.Result) ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) ContractTransferTransaction(io.nuls.contract.entity.tx.ContractTransferTransaction) ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo) BlockHeader(io.nuls.kernel.model.BlockHeader) ProgramStatus(io.nuls.contract.vm.program.ProgramStatus)

Example 18 with ContractAddressInfoPo

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();
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) Na(io.nuls.kernel.model.Na) ContractBalance(io.nuls.contract.ledger.module.ContractBalance) DeleteContractData(io.nuls.contract.entity.txdata.DeleteContractData)

Example 19 with ContractAddressInfoPo

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;
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) Entry(io.nuls.db.model.Entry) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList)

Example 20 with ContractAddressInfoPo

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();
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) ContractBalance(io.nuls.contract.ledger.module.ContractBalance)

Aggregations

ContractAddressInfoPo (io.nuls.contract.storage.po.ContractAddressInfoPo)24 IOException (java.io.IOException)15 NulsException (io.nuls.kernel.exception.NulsException)14 ContractResult (io.nuls.contract.dto.ContractResult)9 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)9 ContractTokenTransferInfoPo (io.nuls.contract.dto.ContractTokenTransferInfoPo)6 VarInt (io.nuls.kernel.utils.VarInt)6 Account (io.nuls.account.model.Account)5 CreateContractTransaction (io.nuls.contract.entity.tx.CreateContractTransaction)4 CreateContractData (io.nuls.contract.entity.txdata.CreateContractData)4 BigInteger (java.math.BigInteger)4 ArrayList (java.util.ArrayList)4 ContractBalance (io.nuls.contract.ledger.module.ContractBalance)3 ContractCollectionInfoPo (io.nuls.contract.storage.po.ContractCollectionInfoPo)3 Result (io.nuls.kernel.model.Result)3 ValidateResult (io.nuls.kernel.validate.ValidateResult)3 LinkedList (java.util.LinkedList)3 List (java.util.List)3 CoinDataResult (io.nuls.account.ledger.model.CoinDataResult)2 ContractTransferTransaction (io.nuls.contract.entity.tx.ContractTransferTransaction)2