Search in sources :

Example 1 with ContractAddressInfoPo

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

the class ContractResource method filterRealTokenTransfers.

private List<ContractTokenTransferDto> filterRealTokenTransfers(List<ContractTokenTransferDto> tokenTransfers) {
    if (tokenTransfers == null || tokenTransfers.isEmpty()) {
        return tokenTransfers;
    }
    List<ContractTokenTransferDto> resultDto = new ArrayList<>();
    Map<String, ContractAddressInfoPo> cache = MapUtil.createHashMap(tokenTransfers.size());
    for (ContractTokenTransferDto tokenTransfer : tokenTransfers) {
        try {
            if (StringUtils.isBlank(tokenTransfer.getName())) {
                String contractAddress = tokenTransfer.getContractAddress();
                ContractAddressInfoPo po = cache.get(contractAddress);
                if (po == null) {
                    po = contractAddressStorageService.getContractAddressInfo(AddressTool.getAddress(contractAddress)).getData();
                    cache.put(contractAddress, po);
                }
                if (po == null || !po.isNrc20()) {
                    continue;
                }
                tokenTransfer.setNrc20Info(po);
                resultDto.add(tokenTransfer);
            }
        } catch (Exception e) {
            Log.error(e);
        }
    }
    return resultDto;
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) NulsException(io.nuls.kernel.exception.NulsException) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException)

Example 2 with ContractAddressInfoPo

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

the class ContractResource method tokenTransfer.

@POST
@Path("/token/transfer")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "token转账")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success") })
public RpcClientResult tokenTransfer(@ApiParam(name = "tokenTransferForm", value = "token转账", required = true) ContractTokenTransfer transfer) {
    if (transfer == null || transfer.getAmount() == null || !StringUtils.isNumeric(transfer.getAmount()) || new BigInteger(transfer.getAmount()).compareTo(BigInteger.ZERO) < 0 || transfer.getGasLimit() < 0 || transfer.getPrice() < 0) {
        return Result.getFailed(ContractErrorCode.PARAMETER_ERROR).toRpcClientResult();
    }
    String from = transfer.getAddress();
    String to = transfer.getToAddress();
    if (!AddressTool.validAddress(from)) {
        return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
    }
    if (!AddressTool.validAddress(to)) {
        return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
    }
    String contractAddress = transfer.getContractAddress();
    if (!AddressTool.validAddress(contractAddress)) {
        return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
    }
    byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
    Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
    ContractAddressInfoPo po = contractAddressInfoResult.getData();
    if (po == null) {
        return Result.getFailed(ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST).toRpcClientResult();
    }
    if (!po.isNrc20()) {
        return Result.getFailed(ContractErrorCode.CONTRACT_NOT_NRC20).toRpcClientResult();
    }
    Object[] argsObj = new Object[] { to, transfer.getAmount() };
    return contractTxService.contractCallTx(transfer.getAddress(), Na.ZERO, transfer.getGasLimit(), transfer.getPrice(), contractAddress, ContractConstant.NRC20_METHOD_TRANSFER, null, ContractUtil.twoDimensionalArray(argsObj), transfer.getPassword(), transfer.getRemark()).toRpcClientResult();
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) BigInteger(java.math.BigInteger)

Example 3 with ContractAddressInfoPo

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

the class ContractResource method export.

@GET
@Path("/export/{address}")
@ApiOperation(value = "导出合约编译代码的jar包 ")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success") })
public void export(@ApiParam(name = "address", value = "账户地址", required = true) @PathParam("address") String address, @Context HttpServletResponse response) {
    try {
        if (StringUtils.isBlank(address)) {
            return;
        }
        if (!AddressTool.validAddress(address)) {
            return;
        }
        byte[] contractAddressBytes = AddressTool.getAddress(address);
        if (!ContractLedgerUtil.isExistContractAddress(contractAddressBytes)) {
            return;
        }
        byte[] addressBytes = AddressTool.getAddress(address);
        Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(addressBytes);
        ContractAddressInfoPo po = contractAddressInfoResult.getData();
        if (po == null) {
            return;
        }
        Transaction tx = ledgerService.getTx(po.getCreateTxHash());
        CreateContractTransaction create = (CreateContractTransaction) tx;
        CreateContractData createTxData = create.getTxData();
        byte[] code = createTxData.getCode();
        // 1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
        response.setContentType("application/octet-stream");
        // 2.设置文件头:最后一个参数是设置下载文件名
        response.addHeader("Content-Disposition", "attachment;filename=" + address + ".jar");
        response.getOutputStream().write(code);
        response.getOutputStream().flush();
    } catch (Exception e) {
        Log.error("Export Exception!");
    }
}
Also used : ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) CreateContractTransaction(io.nuls.contract.entity.tx.CreateContractTransaction) CreateContractData(io.nuls.contract.entity.txdata.CreateContractData) CreateContractTransaction(io.nuls.contract.entity.tx.CreateContractTransaction) NulsException(io.nuls.kernel.exception.NulsException) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException)

Example 4 with ContractAddressInfoPo

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

the class ContractResource method getContractTx.

@GET
@Path("/tx/{hash}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "获取智能合约交易详情")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = ContractTransactionDto.class) })
public RpcClientResult getContractTx(@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();
    }
    Result result;
    try {
        NulsDigestData txHashObj = NulsDigestData.fromDigestHex(hash);
        Transaction tx = ledgerService.getTx(txHashObj);
        if (tx == null) {
            result = Result.getFailed(TransactionErrorCode.TX_NOT_EXIST);
        } else {
            if (!ContractUtil.isContractTransaction(tx) && tx.getType() != NulsConstant.TX_TYPE_COINBASE) {
                return Result.getFailed(ContractErrorCode.NON_CONTRACTUAL_TRANSACTION).toRpcClientResult();
            }
            tx.setStatus(TxStatusEnum.CONFIRMED);
            ContractTransactionDto txDto = null;
            CoinData coinData = tx.getCoinData();
            byte[] txHashBytes = tx.getHash().serialize();
            if (coinData != null) {
                // 组装from数据
                List<Coin> froms = coinData.getFrom();
                if (froms != null && froms.size() > 0) {
                    byte[] fromHash, owner;
                    int fromIndex;
                    NulsDigestData fromHashObj;
                    Transaction fromTx;
                    Coin fromUtxo;
                    for (Coin from : froms) {
                        owner = from.getOwner();
                        // owner拆分出txHash和index
                        fromHash = LedgerUtil.getTxHashBytes(owner);
                        fromIndex = LedgerUtil.getIndex(owner);
                        // 查询from UTXO
                        fromHashObj = new NulsDigestData();
                        fromHashObj.parse(fromHash, 0);
                        fromTx = ledgerService.getTx(fromHashObj);
                        fromUtxo = fromTx.getCoinData().getTo().get(fromIndex);
                        from.setFrom(fromUtxo);
                    }
                }
                txDto = new ContractTransactionDto(tx);
                List<OutputDto> outputDtoList = new ArrayList<>();
                // 组装to数据
                List<Coin> tos = coinData.getTo();
                if (tos != null && tos.size() > 0) {
                    String txHash = hash;
                    OutputDto outputDto;
                    Coin to, temp;
                    long bestHeight = NulsContext.getInstance().getBestHeight();
                    long currentTime = TimeService.currentTimeMillis();
                    long lockTime;
                    for (int i = 0, length = tos.size(); i < length; i++) {
                        to = tos.get(i);
                        outputDto = new OutputDto(to);
                        outputDto.setTxHash(txHash);
                        outputDto.setIndex(i);
                        temp = ledgerService.getUtxo(org.spongycastle.util.Arrays.concatenate(txHashBytes, new VarInt(i).encode()));
                        if (temp == null) {
                            // 已花费
                            outputDto.setStatus(3);
                        } else {
                            lockTime = temp.getLockTime();
                            if (lockTime < 0) {
                                // 共识锁定
                                outputDto.setStatus(2);
                            } else if (lockTime == 0) {
                                // 正常未花费
                                outputDto.setStatus(0);
                            } else if (lockTime > NulsConstant.BlOCKHEIGHT_TIME_DIVIDE) {
                                // 判定是否时间高度锁定
                                if (lockTime > currentTime) {
                                    // 时间高度锁定
                                    outputDto.setStatus(1);
                                } else {
                                    // 正常未花费
                                    outputDto.setStatus(0);
                                }
                            } else {
                                // 判定是否区块高度锁定
                                if (lockTime > bestHeight) {
                                    // 区块高度锁定
                                    outputDto.setStatus(1);
                                } else {
                                    // 正常未花费
                                    outputDto.setStatus(0);
                                }
                            }
                        }
                        outputDtoList.add(outputDto);
                    }
                }
                txDto.setOutputs(outputDtoList);
                // 计算交易实际发生的金额
                calTransactionValue(txDto);
            }
            // 获取合约执行结果
            if (tx.getType() != ContractConstant.TX_TYPE_CONTRACT_TRANSFER) {
                ContractResult contractExecuteResult = contractService.getContractExecuteResult(txHashObj);
                if (contractExecuteResult != null) {
                    Result<ContractAddressInfoPo> contractAddressInfoResult = contractAddressStorageService.getContractAddressInfo(contractExecuteResult.getContractAddress());
                    ContractAddressInfoPo po = contractAddressInfoResult.getData();
                    if (po != null && po.isNrc20()) {
                        contractExecuteResult.setNrc20(true);
                        if (contractExecuteResult.isSuccess()) {
                            txDto.setContractResult(new ContractResultDto(contractExecuteResult, tx, po));
                        } else {
                            ContractData contractData = (ContractData) tx.getTxData();
                            byte[] sender = contractData.getSender();
                            byte[] infoKey = ArraysTool.concatenate(sender, txHashBytes, new VarInt(0).encode());
                            Result<ContractTokenTransferInfoPo> tokenTransferResult = contractTokenTransferStorageService.getTokenTransferInfo(infoKey);
                            ContractTokenTransferInfoPo transferInfoPo = tokenTransferResult.getData();
                            txDto.setContractResult(new ContractResultDto(contractExecuteResult, tx, po, transferInfoPo));
                        }
                    } else {
                        txDto.setContractResult(new ContractResultDto(contractExecuteResult, tx));
                    }
                    ContractResultDto contractResultDto = txDto.getContractResult();
                    List<ContractTokenTransferDto> tokenTransfers = contractResultDto.getTokenTransfers();
                    List<ContractTokenTransferDto> realTokenTransfers = this.filterRealTokenTransfers(tokenTransfers);
                    contractResultDto.setTokenTransfers(realTokenTransfers);
                }
            }
            result = Result.getSuccess();
            result.setData(txDto);
        }
    } catch (NulsRuntimeException e) {
        Log.error(e);
        result = Result.getFailed(e.getErrorCode());
    } catch (Exception e) {
        Log.error(e);
        result = Result.getFailed(LedgerErrorCode.SYS_UNKOWN_EXCEPTION);
    }
    return result.toRpcClientResult();
}
Also used : NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) ContractResult(io.nuls.contract.dto.ContractResult) ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) CreateContractData(io.nuls.contract.entity.txdata.CreateContractData) ContractData(io.nuls.contract.entity.txdata.ContractData) ContractTokenTransferInfoPo(io.nuls.contract.dto.ContractTokenTransferInfoPo) 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) CreateContractTransaction(io.nuls.contract.entity.tx.CreateContractTransaction)

Example 5 with ContractAddressInfoPo

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

the class ContractResource method getContractInfoWithLock.

private RpcClientResult getContractInfoWithLock(String contractAddress, String accountAddress, boolean isNeedLock) {
    try {
        boolean hasAccountAddress = false;
        if (StringUtils.isNotBlank(accountAddress)) {
            Result<Account> accountResult = accountService.getAccount(accountAddress);
            if (accountResult.isFailed()) {
                return accountResult.toRpcClientResult();
            }
            hasAccountAddress = true;
        }
        if (contractAddress == null) {
            return Result.getFailed(ContractErrorCode.PARAMETER_ERROR).toRpcClientResult();
        }
        if (!AddressTool.validAddress(contractAddress)) {
            return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
        }
        byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
        Result<ContractAddressInfoPo> contractAddressInfoPoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
        if (contractAddressInfoPoResult.isFailed()) {
            return contractAddressInfoPoResult.toRpcClientResult();
        }
        ContractAddressInfoPo contractAddressInfoPo = contractAddressInfoPoResult.getData();
        if (contractAddressInfoPo == null) {
            return Result.getFailed(ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST).toRpcClientResult();
        }
        if (isNeedLock && contractAddressInfoPo.isLock()) {
            return Result.getFailed(ContractErrorCode.CONTRACT_LOCK).toRpcClientResult();
        }
        byte[] prevStateRoot = ContractUtil.getStateRoot(NulsContext.getInstance().getBestBlock().getHeader());
        ProgramExecutor track = programExecutor.begin(prevStateRoot);
        ProgramStatus status = track.status(contractAddressBytes);
        List<ProgramMethod> methods = track.method(contractAddressBytes);
        Map<String, Object> resultMap = MapUtil.createLinkedHashMap(8);
        try {
            byte[] createTxHash = contractAddressInfoPo.getCreateTxHash();
            NulsDigestData create = new NulsDigestData();
            create.parse(createTxHash, 0);
            resultMap.put("createTxHash", create.getDigestHex());
        } catch (Exception e) {
            Log.error("createTxHash parse error.", e);
        }
        if (hasAccountAddress) {
            // 所有收藏的合约列表
            boolean isCollect = false;
            Result<ContractCollectionInfoPo> collectionInfoPoResult = contractCollectionStorageService.getContractAddress(contractAddressBytes);
            ContractCollectionInfoPo contractCollectionPo = collectionInfoPoResult.getData();
            if (contractCollectionPo != null) {
                if (contractCollectionPo.getCollectorMap().containsKey(accountAddress)) {
                    isCollect = true;
                }
            }
            resultMap.put("isCollect", isCollect);
        }
        resultMap.put("address", contractAddress);
        resultMap.put("creater", AddressTool.getStringAddressByBytes(contractAddressInfoPo.getSender()));
        resultMap.put("createTime", contractAddressInfoPo.getCreateTime());
        resultMap.put("blockHeight", contractAddressInfoPo.getBlockHeight());
        resultMap.put("isNrc20", contractAddressInfoPo.isNrc20());
        if (contractAddressInfoPo.isNrc20()) {
            resultMap.put("nrc20TokenName", contractAddressInfoPo.getNrc20TokenName());
            resultMap.put("nrc20TokenSymbol", contractAddressInfoPo.getNrc20TokenSymbol());
            resultMap.put("decimals", contractAddressInfoPo.getDecimals());
            resultMap.put("totalSupply", ContractUtil.bigInteger2String(contractAddressInfoPo.getTotalSupply()));
        }
        resultMap.put("status", status.name());
        resultMap.put("method", methods);
        return Result.getSuccess().setData(resultMap).toRpcClientResult();
    } catch (Exception e) {
        Log.error(e);
        return Result.getFailed().setMsg(e.getMessage()).toRpcClientResult();
    }
}
Also used : Account(io.nuls.account.model.Account) ContractCollectionInfoPo(io.nuls.contract.storage.po.ContractCollectionInfoPo) NulsException(io.nuls.kernel.exception.NulsException) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo)

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