Search in sources :

Example 11 with ContractTokenTransferInfoPo

use of io.nuls.contract.dto.ContractTokenTransferInfoPo 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 12 with ContractTokenTransferInfoPo

use of io.nuls.contract.dto.ContractTokenTransferInfoPo in project nuls by nuls-io.

the class ContractTxServiceImpl method saveUnConfirmedTokenTransfer.

private Result<byte[]> saveUnConfirmedTokenTransfer(CallContractTransaction tx, String sender, String contractAddress, String methodName, String[][] args) {
    try {
        byte[] senderBytes = AddressTool.getAddress(sender);
        byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
        Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
        ContractAddressInfoPo po = contractAddressInfoResult.getData();
        if (po != null && po.isNrc20() && ContractUtil.isTransferMethod(methodName)) {
            byte[] txHashBytes = tx.getHash().serialize();
            byte[] infoKey = ArraysTool.concatenate(senderBytes, txHashBytes, new VarInt(0).encode());
            ContractTokenTransferInfoPo tokenTransferInfoPo = new ContractTokenTransferInfoPo();
            if (ContractConstant.NRC20_METHOD_TRANSFER.equals(methodName)) {
                String to = args[0][0];
                String tokenValue = args[1][0];
                BigInteger token = new BigInteger(tokenValue);
                Result result = contractBalanceManager.subtractContractToken(sender, contractAddress, token);
                if (result.isFailed()) {
                    return result;
                }
                contractBalanceManager.addContractToken(to, contractAddress, token);
                tokenTransferInfoPo.setFrom(senderBytes);
                tokenTransferInfoPo.setTo(AddressTool.getAddress(to));
                tokenTransferInfoPo.setValue(token);
            } else {
                String from = args[0][0];
                // 转出的不是自己的代币(代币授权逻辑),则不保存token待确认交易,因为有调用合约的待确认交易
                if (!sender.equals(from)) {
                    return Result.getSuccess();
                }
                String to = args[1][0];
                String tokenValue = args[2][0];
                BigInteger token = new BigInteger(tokenValue);
                Result result = contractBalanceManager.subtractContractToken(from, contractAddress, token);
                if (result.isFailed()) {
                    return result;
                }
                contractBalanceManager.addContractToken(to, contractAddress, token);
                tokenTransferInfoPo.setFrom(AddressTool.getAddress(from));
                tokenTransferInfoPo.setTo(AddressTool.getAddress(to));
                tokenTransferInfoPo.setValue(token);
            }
            tokenTransferInfoPo.setName(po.getNrc20TokenName());
            tokenTransferInfoPo.setSymbol(po.getNrc20TokenSymbol());
            tokenTransferInfoPo.setDecimals(po.getDecimals());
            tokenTransferInfoPo.setTime(tx.getTime());
            tokenTransferInfoPo.setContractAddress(contractAddress);
            tokenTransferInfoPo.setBlockHeight(tx.getBlockHeight());
            tokenTransferInfoPo.setTxHash(txHashBytes);
            tokenTransferInfoPo.setStatus((byte) 0);
            Result result = contractTokenTransferStorageService.saveTokenTransferInfo(infoKey, tokenTransferInfoPo);
            if (result.isFailed()) {
                return result;
            }
            return Result.getSuccess().setData(infoKey);
        }
        return Result.getSuccess();
    } catch (Exception e) {
        Log.error(e);
        Result result = Result.getFailed(ContractErrorCode.CONTRACT_TX_CREATE_ERROR);
        result.setMsg(e.getMessage());
        return result;
    }
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) VarInt(io.nuls.kernel.utils.VarInt) BigInteger(java.math.BigInteger) ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo) NulsException(io.nuls.kernel.exception.NulsException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) ContractResult(io.nuls.contract.dto.ContractResult) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult)

Example 13 with ContractTokenTransferInfoPo

use of io.nuls.contract.dto.ContractTokenTransferInfoPo in project nuls by nuls-io.

the class ContractServiceImpl method getTokenTransferInfoList.

@Override
public Result<List<ContractTokenTransferInfoPo>> getTokenTransferInfoList(String address) {
    try {
        Result accountResult = accountService.getAccount(address);
        if (accountResult.isFailed()) {
            return accountResult;
        }
        byte[] addressBytes = AddressTool.getAddress(address);
        List<ContractTokenTransferInfoPo> tokenTransferInfoListByAddress = contractTokenTransferStorageService.getTokenTransferInfoListByAddress(addressBytes);
        return Result.getSuccess().setData(tokenTransferInfoListByAddress);
    } catch (Exception e) {
        Log.error(e);
        return Result.getFailed();
    }
}
Also used : ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo) NulsException(io.nuls.kernel.exception.NulsException) IOException(java.io.IOException) ContractResult(io.nuls.contract.dto.ContractResult) ValidateResult(io.nuls.kernel.validate.ValidateResult) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult)

Aggregations

ContractTokenTransferInfoPo (io.nuls.contract.dto.ContractTokenTransferInfoPo)13 IOException (java.io.IOException)8 ContractResult (io.nuls.contract.dto.ContractResult)7 NulsException (io.nuls.kernel.exception.NulsException)7 ContractAddressInfoPo (io.nuls.contract.storage.po.ContractAddressInfoPo)6 VarInt (io.nuls.kernel.utils.VarInt)6 ValidateResult (io.nuls.kernel.validate.ValidateResult)5 CoinDataResult (io.nuls.account.ledger.model.CoinDataResult)4 BigInteger (java.math.BigInteger)3 ContractTransferTransaction (io.nuls.contract.entity.tx.ContractTransferTransaction)2 CreateContractTransaction (io.nuls.contract.entity.tx.CreateContractTransaction)2 CallContractData (io.nuls.contract.entity.txdata.CallContractData)2 ContractData (io.nuls.contract.entity.txdata.ContractData)2 CreateContractData (io.nuls.contract.entity.txdata.CreateContractData)2 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 ArrayList (java.util.ArrayList)2 AccountErrorCode (io.nuls.account.constant.AccountErrorCode)1 LocalUtxoService (io.nuls.account.ledger.base.service.LocalUtxoService)1 AccountLegerUtils (io.nuls.account.ledger.base.util.AccountLegerUtils)1