Search in sources :

Example 6 with ContractAddressInfoPo

use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.

the class VMHelper method dealEvents.

public void dealEvents(byte[] newestStateRoot, Transaction tx, ContractResult contractResult, ContractAddressInfoPo po) {
    if (po == null) {
        return;
    }
    try {
        List<String> events = contractResult.getEvents();
        int size = events.size();
        // 目前只处理Transfer事件, 为了刷新账户的token余额
        String event;
        ContractAddressInfoPo contractAddressInfo;
        if (events != null && size > 0) {
            for (int i = 0; i < size; i++) {
                event = events.get(i);
                // 按照NRC20标准,TransferEvent事件中第一个参数是转出地址-from,第二个参数是转入地址-to, 第三个参数是金额
                ContractTokenTransferInfoPo tokenTransferInfoPo = ContractUtil.convertJsonToTokenTransferInfoPo(event);
                if (tokenTransferInfoPo == null) {
                    continue;
                }
                String contractAddress = tokenTransferInfoPo.getContractAddress();
                if (StringUtils.isBlank(contractAddress)) {
                    continue;
                }
                if (!AddressTool.validAddress(contractAddress)) {
                    continue;
                }
                byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
                if (ArraysTool.arrayEquals(po.getContractAddress(), contractAddressBytes)) {
                    contractAddressInfo = po;
                } else {
                    Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
                    contractAddressInfo = contractAddressInfoResult.getData();
                }
                if (contractAddressInfo == null) {
                    continue;
                }
                // 事件不是NRC20合约的事件
                if (!contractAddressInfo.isNrc20()) {
                    continue;
                }
                byte[] txHashBytes;
                byte[] from = tokenTransferInfoPo.getFrom();
                byte[] to = tokenTransferInfoPo.getTo();
                tokenTransferInfoPo.setName(contractAddressInfo.getNrc20TokenName());
                tokenTransferInfoPo.setSymbol(contractAddressInfo.getNrc20TokenSymbol());
                tokenTransferInfoPo.setDecimals(contractAddressInfo.getDecimals());
                tokenTransferInfoPo.setTime(tx.getTime());
                tokenTransferInfoPo.setBlockHeight(tx.getBlockHeight());
                txHashBytes = tx.getHash().serialize();
                tokenTransferInfoPo.setTxHash(txHashBytes);
                tokenTransferInfoPo.setStatus((byte) (contractResult.isSuccess() ? 1 : 2));
                if (from != null) {
                    this.refreshTokenBalance(newestStateRoot, contractAddressInfo, AddressTool.getStringAddressByBytes(from), contractAddress);
                    this.saveTokenTransferInfo(from, txHashBytes, new VarInt(i).encode(), tokenTransferInfoPo);
                }
                if (to != null) {
                    this.refreshTokenBalance(newestStateRoot, contractAddressInfo, AddressTool.getStringAddressByBytes(to), contractAddress);
                    this.saveTokenTransferInfo(to, txHashBytes, new VarInt(i).encode(), tokenTransferInfoPo);
                }
            }
        }
    } catch (Exception e) {
        Log.warn("contract event parse error.", e);
    }
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) VarInt(io.nuls.kernel.utils.VarInt) ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo) NulsException(io.nuls.kernel.exception.NulsException)

Example 7 with ContractAddressInfoPo

use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.

the class CallContractTxProcessor method onRollback.

@Override
public Result onRollback(CallContractTransaction tx, Object secondaryData) {
    try {
        // 回滚代币转账交易
        byte[] txHashBytes = null;
        try {
            txHashBytes = tx.getHash().serialize();
        } catch (IOException e) {
            Log.error(e);
        }
        ContractResult contractResult = tx.getContractResult();
        if (contractResult == null) {
            contractResult = contractService.getContractExecuteResult(tx.getHash());
        }
        CallContractData txData = tx.getTxData();
        byte[] senderContractAddressBytes = txData.getContractAddress();
        Result<ContractAddressInfoPo> senderContractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(senderContractAddressBytes);
        ContractAddressInfoPo po = senderContractAddressInfoResult.getData();
        if (po != null) {
            if (contractResult != null) {
                // 处理合约执行失败 - 没有transferEvent的情况, 直接从数据库中删除
                if (!contractResult.isSuccess()) {
                    if (ContractUtil.isTransferMethod(txData.getMethodName())) {
                        contractTokenTransferStorageService.deleteTokenTransferInfo(ArraysTool.concatenate(txData.getSender(), txHashBytes, new VarInt(0).encode()));
                    }
                }
                List<String> events = contractResult.getEvents();
                int size = events.size();
                // 目前只处理Transfer事件
                String event;
                ContractAddressInfoPo contractAddressInfo;
                if (events != null && size > 0) {
                    for (int i = 0; i < size; i++) {
                        event = events.get(i);
                        // 按照NRC20标准,TransferEvent事件中第一个参数是转出地址-from,第二个参数是转入地址-to, 第三个参数是金额
                        ContractTokenTransferInfoPo tokenTransferInfoPo = ContractUtil.convertJsonToTokenTransferInfoPo(event);
                        if (tokenTransferInfoPo == null) {
                            continue;
                        }
                        String contractAddress = tokenTransferInfoPo.getContractAddress();
                        if (StringUtils.isBlank(contractAddress)) {
                            continue;
                        }
                        if (!AddressTool.validAddress(contractAddress)) {
                            continue;
                        }
                        byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
                        if (ArraysTool.arrayEquals(senderContractAddressBytes, contractAddressBytes)) {
                            contractAddressInfo = po;
                        } else {
                            Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
                            contractAddressInfo = contractAddressInfoResult.getData();
                        }
                        if (contractAddressInfo == null) {
                            continue;
                        }
                        // 事件不是NRC20合约的事件
                        if (!contractAddressInfo.isNrc20()) {
                            continue;
                        }
                        // 回滚token余额
                        this.rollbackContractToken(tokenTransferInfoPo);
                        contractTokenTransferStorageService.deleteTokenTransferInfo(ArraysTool.concatenate(tokenTransferInfoPo.getFrom(), txHashBytes, new VarInt(i).encode()));
                        contractTokenTransferStorageService.deleteTokenTransferInfo(ArraysTool.concatenate(tokenTransferInfoPo.getTo(), txHashBytes, new VarInt(i).encode()));
                    }
                }
            }
        }
        // 删除子交易从全网账本
        // 删除子交易从合约账本
        // 删除子交易从本地账本
        List<ContractTransferTransaction> contractTransferTxList = this.extractContractTransferTxs(contractResult);
        if (contractTransferTxList != null && !contractTransferTxList.isEmpty()) {
            // 用于回滚本地账本
            List<Transaction> txList = new ArrayList<>();
            for (ContractTransferTransaction transferTx : contractTransferTxList) {
                try {
                    txList.add(transferTx);
                    Result result = ledgerService.rollbackTx(transferTx);
                    if (result.isFailed()) {
                        Log.error("rollback contract transfer tx from ledger error. msg: {}", result.getMsg());
                        return result;
                    }
                    result = contractService.rollbackContractTransferTx(transferTx);
                    if (result.isFailed()) {
                        Log.error("rollback contract transfer tx from contract ledger error. msg: {}", result.getMsg());
                        return Result.getFailed();
                    }
                } catch (Exception e) {
                    Log.error("rollback contract transfer tx error. msg: {}", e.getMessage());
                    return Result.getFailed();
                }
            }
            Result result = accountLedgerService.rollbackTransactions(txList);
            if (result.isFailed()) {
                Log.error("rollback contract transfer tx from account ledger error. msg: {}", result.getMsg());
                return Result.getFailed();
            }
        }
        // 删除合约调用交易的UTXO
        contractUtxoService.deleteUtxoOfTransaction(tx);
        // 删除合约执行结果
        contractService.deleteContractExecuteResult(tx.getHash());
    } catch (Exception e) {
        Log.error("rollback 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) ArrayList(java.util.ArrayList) IOException(java.io.IOException) 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) CallContractTransaction(io.nuls.contract.entity.tx.CallContractTransaction) Transaction(io.nuls.kernel.model.Transaction) ContractTransferTransaction(io.nuls.contract.entity.tx.ContractTransferTransaction) ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo)

Example 8 with ContractAddressInfoPo

use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.

the class ContractAddressStorageServiceImpl method getAllContractInfoList.

@Override
public Result<List<ContractAddressInfoPo>> getAllContractInfoList() {
    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();
        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 9 with ContractAddressInfoPo

use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.

the class ContractAddressStorageServiceImpl method getAllNrc20ContractInfoList.

@Override
public Result<List<ContractAddressInfoPo>> getAllNrc20ContractInfoList() {
    Result<List<ContractAddressInfoPo>> allContractInfoListResult = getAllContractInfoList();
    if (allContractInfoListResult.isFailed()) {
        return allContractInfoListResult;
    }
    List<ContractAddressInfoPo> resultList = new ArrayList<>();
    List<ContractAddressInfoPo> contractAddressInfoPoList = allContractInfoListResult.getData();
    for (ContractAddressInfoPo po : contractAddressInfoPoList) {
        if (po.isNrc20()) {
            resultList.add(po);
        }
    }
    return Result.getSuccess().setData(resultList);
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList)

Example 10 with ContractAddressInfoPo

use of io.nuls.contract.storage.po.ContractAddressInfoPo in project nuls by nuls-io.

the class ContractResource method getContractTxResult.

@GET
@Path("/result/{hash}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "获取智能合约执行结果")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = ContractResultDto.class) })
public RpcClientResult getContractTxResult(@ApiParam(name = "hash", value = "交易hash", required = true) @PathParam("hash") String hash) {
    if (StringUtils.isBlank(hash)) {
        return Result.getFailed(LedgerErrorCode.NULL_PARAMETER).toRpcClientResult();
    }
    if (!NulsDigestData.validHash(hash)) {
        return Result.getFailed(LedgerErrorCode.PARAMETER_ERROR).toRpcClientResult();
    }
    try {
        ContractResultDto contractResultDto = null;
        ContractResult contractExecuteResult;
        boolean flag = true;
        String msg = EMPTY;
        // long confirmCount = 0L;
        do {
            NulsDigestData txHash = NulsDigestData.fromDigestHex(hash);
            Transaction tx = ledgerService.getTx(txHash);
            if (tx == null) {
                flag = false;
                msg = TransactionErrorCode.TX_NOT_EXIST.getMsg();
                break;
            } else {
                if (!ContractUtil.isContractTransaction(tx)) {
                    flag = false;
                    msg = ContractErrorCode.NON_CONTRACTUAL_TRANSACTION.getMsg();
                    break;
                }
            }
            contractExecuteResult = contractService.getContractExecuteResult(txHash);
            if (contractExecuteResult != null) {
                // long bestBlockHeight = NulsContext.getInstance().getBestHeight();
                // confirmCount = bestBlockHeight - tx.getBlockHeight() + 1;
                Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractExecuteResult.getContractAddress());
                ContractAddressInfoPo po = contractAddressInfoResult.getData();
                if (po != null && po.isNrc20()) {
                    contractExecuteResult.setNrc20(true);
                    if (contractExecuteResult.isSuccess()) {
                        contractResultDto = new ContractResultDto(contractExecuteResult, tx, po);
                    } else {
                        ContractData contractData = (ContractData) tx.getTxData();
                        byte[] sender = contractData.getSender();
                        byte[] infoKey = ArraysTool.concatenate(sender, tx.getHash().serialize(), new VarInt(0).encode());
                        Result<ContractTokenTransferInfoPo> tokenTransferResult = contractTokenTransferStorageService.getTokenTransferInfo(infoKey);
                        ContractTokenTransferInfoPo transferInfoPo = tokenTransferResult.getData();
                        contractResultDto = new ContractResultDto(contractExecuteResult, tx, po, transferInfoPo);
                    }
                } else {
                    contractResultDto = new ContractResultDto(contractExecuteResult, tx);
                }
                break;
            } else {
                flag = false;
                msg = TransactionErrorCode.DATA_NOT_FOUND.getMsg();
                break;
            }
        } while (false);
        Map<String, Object> resultMap = MapUtil.createLinkedHashMap(2);
        resultMap.put("flag", flag);
        if (!flag && StringUtils.isNotBlank(msg)) {
            resultMap.put("msg", msg);
        }
        if (flag && contractResultDto != null) {
            List<ContractTokenTransferDto> tokenTransfers = contractResultDto.getTokenTransfers();
            List<ContractTokenTransferDto> realTokenTransfers = this.filterRealTokenTransfers(tokenTransfers);
            contractResultDto.setTokenTransfers(realTokenTransfers);
            resultMap.put("data", contractResultDto);
        }
        return Result.getSuccess().setData(resultMap).toRpcClientResult();
    } catch (Exception e) {
        Log.error(e);
        return Result.getFailed().setMsg(e.getMessage()).toRpcClientResult();
    }
}
Also used : ContractResult(io.nuls.contract.dto.ContractResult) VarInt(io.nuls.kernel.utils.VarInt) NulsException(io.nuls.kernel.exception.NulsException) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) CreateContractData(io.nuls.contract.entity.txdata.CreateContractData) ContractData(io.nuls.contract.entity.txdata.ContractData) CreateContractTransaction(io.nuls.contract.entity.tx.CreateContractTransaction) ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo)

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