Search in sources :

Example 6 with NulsException

use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.

the class AccountLedgerResource method getLockUtxo.

@GET
@Path("/utxo/lock/{address}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "查询用户冻结列表", notes = "result.data: balanceJson 返回账户相关的冻结UTXO列表")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = Page.class) })
public RpcClientResult getLockUtxo(@ApiParam(name = "address", value = "地址") @PathParam("address") String address, @ApiParam(name = "pageNumber", value = "页码") @QueryParam("pageNumber") Integer pageNumber, @ApiParam(name = "pageSize", value = "每页条数") @QueryParam("pageSize") Integer pageSize) {
    if (null == pageNumber || pageNumber == 0) {
        pageNumber = 1;
    }
    if (null == pageSize || pageSize == 0) {
        pageSize = 10;
    }
    if (pageNumber < 0 || pageSize < 0 || pageSize > 100) {
        return Result.getFailed(KernelErrorCode.PARAMETER_ERROR).toRpcClientResult();
    }
    byte[] addressBytes = null;
    Result dtoResult = new Result<>();
    try {
        addressBytes = AddressTool.getAddress(address);
    } catch (Exception e) {
        return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
    }
    // 获取所有锁定的utxo
    Result<List<Coin>> result = accountLedgerService.getLockedUtxo(addressBytes);
    if (result.isFailed()) {
        dtoResult.setSuccess(false);
        dtoResult.setErrorCode(result.getErrorCode());
        return dtoResult.toRpcClientResult();
    }
    List<Coin> coinList = result.getData();
    Page<UtxoDto> page = new Page<>(pageNumber, pageSize, result.getData().size());
    int start = pageNumber * pageSize - pageSize;
    if (start >= coinList.size()) {
        dtoResult.setSuccess(true);
        dtoResult.setData(page);
        return dtoResult.toRpcClientResult();
    }
    List<UtxoDto> utxoDtoList = new ArrayList<>();
    byte[] txHash = new byte[NulsDigestData.HASH_LENGTH];
    for (Coin coin : coinList) {
        // 找到每一条uxto,对应的交易类型与时间
        System.arraycopy(coin.getOwner(), 0, txHash, 0, NulsDigestData.HASH_LENGTH);
        Transaction tx = ledgerService.getTx(txHash);
        if (tx == null) {
            NulsDigestData hash = new NulsDigestData();
            try {
                hash.parse(txHash, 0);
                tx = accountLedgerService.getUnconfirmedTransaction(hash).getData();
            } catch (NulsException e) {
                Log.error(e);
                return Result.getFailed(KernelErrorCode.DATA_PARSE_ERROR).toRpcClientResult();
            }
        }
        // 考虑到数据回滚,会出现找不到的情况
        if (tx == null) {
            continue;
        }
        utxoDtoList.add(new UtxoDto(coin, tx));
    }
    // 重新赋值page对象
    page = new Page<>(pageNumber, pageSize, utxoDtoList.size());
    if (start >= page.getTotal()) {
        dtoResult.setData(page);
        return dtoResult.toRpcClientResult();
    }
    Collections.sort(utxoDtoList, UtxoDtoComparator.getInstance());
    int end = start + pageSize;
    if (end > utxoDtoList.size()) {
        end = utxoDtoList.size();
    }
    page.setList(utxoDtoList.subList(start, end));
    dtoResult.setSuccess(true);
    dtoResult.setData(page);
    return dtoResult.toRpcClientResult();
}
Also used : Page(io.nuls.core.tools.page.Page) CryptoException(io.nuls.core.tools.crypto.Exception.CryptoException) NulsException(io.nuls.kernel.exception.NulsException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) NulsRuntimeException(io.nuls.kernel.exception.NulsRuntimeException) IOException(java.io.IOException) ValidateResult(io.nuls.kernel.validate.ValidateResult) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult) TransferTransaction(io.nuls.protocol.model.tx.TransferTransaction) NulsException(io.nuls.kernel.exception.NulsException)

Example 7 with NulsException

use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.

the class BalanceManager method getCoinListByAddress.

public List<Coin> getCoinListByAddress(byte[] address) {
    List<Coin> coinList = new ArrayList<>();
    Collection<Entry<byte[], byte[]>> rawList = localUtxoStorageService.loadAllCoinList();
    for (Entry<byte[], byte[]> coinEntry : rawList) {
        Coin coin = new Coin();
        try {
            coin.parse(coinEntry.getValue(), 0);
        } catch (NulsException e) {
            Log.info("parse coin form db error");
            continue;
        }
        if (Arrays.equals(coin.getAddress(), address)) {
            coin.setTempOwner(coin.getOwner());
            coin.setOwner(coinEntry.getKey());
            coinList.add(coin);
        }
    }
    return coinList;
}
Also used : Coin(io.nuls.kernel.model.Coin) Entry(io.nuls.db.model.Entry) NulsException(io.nuls.kernel.exception.NulsException)

Example 8 with NulsException

use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.

the class BalanceManager method getBalance.

/**
 * 获取账户余额
 */
public Result<Balance> getBalance(byte[] address) {
    lock.lock();
    try {
        if (address == null || address.length != Address.ADDRESS_LENGTH) {
            return Result.getFailed(AccountLedgerErrorCode.PARAMETER_ERROR);
        }
        String addressKey = AddressTool.getStringAddressByBytes(address);
        BalanceCacheEntity entity = balanceMap.get(addressKey);
        Balance balance = null;
        if (entity == null || (entity.getEarlistLockTime() > 0L && entity.getEarlistLockTime() <= TimeService.currentTimeMillis())) {
            try {
                balance = calBalanceByAddress(address);
            } catch (NulsException e) {
                Log.info("getbalance of address[" + AddressTool.getStringAddressByBytes(address) + "] error");
            }
        } else {
            balance = entity.getBalance();
        }
        return Result.getSuccess().setData(balance);
    } finally {
        lock.unlock();
    }
}
Also used : NulsException(io.nuls.kernel.exception.NulsException) Balance(io.nuls.account.model.Balance)

Example 9 with NulsException

use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.

the class ContractTxServiceImpl method contractCallTx.

/**
 * 创建调用智能合约的交易
 *
 * @param sender          交易创建者
 * @param value           交易附带的货币量
 * @param gasLimit        最大gas消耗
 * @param price           执行合约单价
 * @param contractAddress 合约地址
 * @param methodName      方法名
 * @param methodDesc      方法签名,如果方法名不重复,可以不传
 * @param args            参数列表
 * @param password        账户密码
 * @param remark          备注
 * @return
 */
@Override
public Result contractCallTx(String sender, Na value, Long gasLimit, Long price, String contractAddress, String methodName, String methodDesc, String[][] args, String password, String remark) {
    try {
        AssertUtil.canNotEmpty(sender, "the sender address can not be empty");
        AssertUtil.canNotEmpty(contractAddress, "the contractAddress can not be empty");
        AssertUtil.canNotEmpty(methodName, "the methodName can not be empty");
        if (value == null) {
            value = Na.ZERO;
        }
        if (!ContractUtil.checkPrice(price.longValue())) {
            return Result.getFailed(ContractErrorCode.CONTRACT_MINIMUM_PRICE);
        }
        Result<Account> accountResult = accountService.getAccount(sender);
        if (accountResult.isFailed()) {
            return accountResult;
        }
        Account account = accountResult.getData();
        // 验证账户密码
        if (account.isEncrypted() && account.isLocked()) {
            AssertUtil.canNotEmpty(password, "the password can not be empty");
            if (!account.validatePassword(password)) {
                return Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG);
            }
        }
        if (!account.isOk()) {
            return Result.getFailed(AccountErrorCode.IMPORTING_ACCOUNT);
        }
        byte[] senderBytes = AddressTool.getAddress(sender);
        byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
        BlockHeader blockHeader = NulsContext.getInstance().getBestBlock().getHeader();
        // 当前区块高度
        long blockHeight = blockHeader.getHeight();
        // 当前区块状态根
        byte[] prevStateRoot = ContractUtil.getStateRoot(blockHeader);
        AssertUtil.canNotEmpty(prevStateRoot, "All features of the smart contract are locked.");
        // 组装VM执行数据
        ProgramCall programCall = new ProgramCall();
        programCall.setContractAddress(contractAddressBytes);
        programCall.setSender(senderBytes);
        programCall.setNumber(blockHeight);
        programCall.setMethodName(methodName);
        programCall.setMethodDesc(methodDesc);
        programCall.setArgs(args);
        // 如果方法是不上链的合约调用,同步执行合约代码,不改变状态根,并返回值
        ProgramMethod method;
        if ((method = vmHelper.getMethodInfoByContractAddress(methodName, methodDesc, contractAddressBytes)).isView()) {
            ProgramResult programResult = vmHelper.invokeCustomGasViewMethod(contractAddressBytes, methodName, methodDesc, ContractUtil.twoDimensionalArray(args, method.argsType2Array()));
            // programCall.setValue(BigInteger.ZERO);
            // programCall.setGasLimit(ContractConstant.CONTRACT_CONSTANT_GASLIMIT);
            // programCall.setPrice(ContractConstant.CONTRACT_CONSTANT_PRICE);
            // ProgramExecutor track = programExecutor.begin(prevStateRoot);
            // ProgramResult programResult = track.call(programCall);
            Result result;
            if (!programResult.isSuccess()) {
                Log.error(programResult.getStackTrace());
                result = Result.getFailed(ContractErrorCode.DATA_ERROR);
                result.setMsg(ContractUtil.simplifyErrorMsg(programResult.getErrorMessage()));
                result = checkVmResultAndReturn(programResult.getErrorMessage(), result);
            } else {
                result = Result.getSuccess();
                result.setData(programResult.getResult());
            }
            return result;
        }
        // 创建链上交易,包含智能合约
        programCall.setValue(BigInteger.valueOf(value.getValue()));
        programCall.setPrice(price.longValue());
        programCall.setGasLimit(gasLimit.longValue());
        CallContractTransaction tx = new CallContractTransaction();
        if (StringUtils.isNotBlank(remark)) {
            try {
                tx.setRemark(remark.getBytes(NulsConfig.DEFAULT_ENCODING));
            } catch (UnsupportedEncodingException e) {
                Log.error(e);
                throw new RuntimeException(e);
            }
        }
        tx.setTime(TimeService.currentTimeMillis());
        // 计算CoinData
        /*
             * 智能合约计算手续费以消耗的Gas*Price为根据,然而创建交易时并不执行智能合约,
             * 所以此时交易的CoinData是不固定的,比实际要多,
             * 打包时执行智能合约,真实的手续费已算出,然而tx的手续费已扣除,
             * 多扣除的费用会以CoinBase交易还给Sender
             */
        CoinData coinData = new CoinData();
        // 向智能合约账户转账
        if (!Na.ZERO.equals(value)) {
            Coin toCoin = new Coin(contractAddressBytes, value);
            coinData.getTo().add(toCoin);
        }
        // 执行VM验证合法性
        ProgramExecutor track = programExecutor.begin(prevStateRoot);
        // 验证合约时跳过Gas验证
        long realGasLimit = programCall.getGasLimit();
        programCall.setGasLimit(MAX_GASLIMIT);
        ProgramResult programResult = track.call(programCall);
        // 执行结果失败时,交易直接返回错误,不上链,不消耗Gas
        if (!programResult.isSuccess()) {
            Log.error(programResult.getStackTrace());
            Result result = Result.getFailed(ContractErrorCode.DATA_ERROR);
            result.setMsg(ContractUtil.simplifyErrorMsg(programResult.getErrorMessage()));
            result = checkVmResultAndReturn(programResult.getErrorMessage(), result);
            return result;
        } else {
            // 其他合法性都通过后,再验证Gas
            track = programExecutor.begin(prevStateRoot);
            programCall.setGasLimit(realGasLimit);
            programResult = track.call(programCall);
            if (!programResult.isSuccess()) {
                Log.error(programResult.getStackTrace());
                Result result = Result.getFailed(ContractErrorCode.DATA_ERROR);
                result.setMsg(ContractUtil.simplifyErrorMsg(programResult.getErrorMessage()));
                return result;
            }
        }
        long gasUsed = gasLimit.longValue();
        Na imputedNa = Na.valueOf(LongUtils.mul(gasUsed, price));
        // 总花费
        Na totalNa = imputedNa.add(value);
        // 组装txData
        CallContractData callContractData = new CallContractData();
        callContractData.setContractAddress(contractAddressBytes);
        callContractData.setSender(senderBytes);
        callContractData.setValue(value.getValue());
        callContractData.setPrice(price.longValue());
        callContractData.setGasLimit(gasLimit.longValue());
        callContractData.setMethodName(methodName);
        callContractData.setMethodDesc(methodDesc);
        if (args != null) {
            callContractData.setArgsCount((byte) args.length);
            callContractData.setArgs(args);
        }
        tx.setTxData(callContractData);
        CoinDataResult coinDataResult = accountLedgerService.getCoinData(senderBytes, totalNa, tx.size() + coinData.size(), TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES);
        if (!coinDataResult.isEnough()) {
            return Result.getFailed(TransactionErrorCode.INSUFFICIENT_BALANCE);
        }
        coinData.setFrom(coinDataResult.getCoinList());
        // 找零的UTXO
        if (coinDataResult.getChange() != null) {
            coinData.getTo().add(coinDataResult.getChange());
        }
        tx.setCoinData(coinData);
        tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
        // 生成签名
        List<ECKey> signEckeys = new ArrayList<>();
        List<ECKey> scriptEckeys = new ArrayList<>();
        ECKey eckey = account.getEcKey(password);
        // 如果最后一位为1则表示该交易包含普通签名
        if ((coinDataResult.getSignType() & 0x01) == 0x01) {
            signEckeys.add(eckey);
        }
        // 如果倒数第二位位为1则表示该交易包含脚本签名
        if ((coinDataResult.getSignType() & 0x02) == 0x02) {
            scriptEckeys.add(eckey);
        }
        SignatureUtil.createTransactionSignture(tx, scriptEckeys, signEckeys);
        // 保存未确认Token转账
        Result<byte[]> unConfirmedTokenTransferResult = this.saveUnConfirmedTokenTransfer(tx, sender, contractAddress, methodName, args);
        if (unConfirmedTokenTransferResult.isFailed()) {
            return unConfirmedTokenTransferResult;
        }
        byte[] infoKey = unConfirmedTokenTransferResult.getData();
        // 保存未确认交易到本地账本
        Result saveResult = accountLedgerService.verifyAndSaveUnconfirmedTransaction(tx);
        if (saveResult.isFailed()) {
            if (infoKey != null) {
                contractTokenTransferStorageService.deleteTokenTransferInfo(infoKey);
            }
            if (KernelErrorCode.DATA_SIZE_ERROR.getCode().equals(saveResult.getErrorCode().getCode())) {
                // 重新算一次交易(不超出最大交易数据大小下)的最大金额
                Result rs = accountLedgerService.getMaxAmountOfOnce(senderBytes, tx, TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES);
                if (rs.isSuccess()) {
                    Na maxAmount = (Na) rs.getData();
                    rs = Result.getFailed(KernelErrorCode.DATA_SIZE_ERROR_EXTEND);
                    rs.setMsg(rs.getMsg() + maxAmount.toDouble());
                }
                return rs;
            }
            return saveResult;
        }
        // 广播
        Result sendResult = transactionService.broadcastTx(tx);
        if (sendResult.isFailed()) {
            // 失败则回滚
            accountLedgerService.deleteTransaction(tx);
            if (infoKey != null) {
                contractTokenTransferStorageService.deleteTokenTransferInfo(infoKey);
            }
            return sendResult;
        }
        return Result.getSuccess().setData(tx.getHash().getDigestHex());
    } catch (IOException e) {
        Log.error(e);
        Result result = Result.getFailed(ContractErrorCode.CONTRACT_EXECUTE_ERROR);
        result.setMsg(e.getMessage());
        return result;
    } catch (NulsException e) {
        Log.error(e);
        return Result.getFailed(e.getErrorCode());
    } catch (Exception e) {
        Log.error(e);
        Result result = Result.getFailed(ContractErrorCode.CONTRACT_EXECUTE_ERROR);
        result.setMsg(e.getMessage());
        return result;
    }
}
Also used : Account(io.nuls.account.model.Account) ECKey(io.nuls.core.tools.crypto.ECKey) ContractResult(io.nuls.contract.dto.ContractResult) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult) NulsException(io.nuls.kernel.exception.NulsException) CallContractTransaction(io.nuls.contract.entity.tx.CallContractTransaction) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) CallContractData(io.nuls.contract.entity.txdata.CallContractData) NulsException(io.nuls.kernel.exception.NulsException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException)

Example 10 with NulsException

use of io.nuls.kernel.exception.NulsException in project nuls by nuls-io.

the class ContractTxServiceImpl method contractCreateTx.

/**
 * 创建生成智能合约的交易
 * 如果是创建合约的交易,交易仅仅用于创建合约,合约内部不执行复杂逻辑
 *
 * @param sender       交易创建者
 * @param gasLimit     最大gas消耗
 * @param price        执行合约单价
 * @param contractCode 合约代码
 * @param args         参数列表
 * @param password     账户密码
 * @param remark       备注
 * @return
 */
@Override
public Result contractCreateTx(String sender, Long gasLimit, Long price, byte[] contractCode, String[][] args, String password, String remark) {
    try {
        AssertUtil.canNotEmpty(sender, "the sender address can not be empty");
        AssertUtil.canNotEmpty(contractCode, "the contractCode can not be empty");
        Na value = Na.ZERO;
        Result<Account> accountResult = accountService.getAccount(sender);
        if (accountResult.isFailed()) {
            return accountResult;
        }
        if (!accountResult.getData().isOk()) {
            return Result.getFailed(AccountErrorCode.IMPORTING_ACCOUNT);
        }
        if (!ContractUtil.checkPrice(price.longValue())) {
            return Result.getFailed(ContractErrorCode.CONTRACT_MINIMUM_PRICE);
        }
        Account account = accountResult.getData();
        // 验证账户密码
        if (account.isEncrypted() && account.isLocked()) {
            AssertUtil.canNotEmpty(password, "the password can not be empty");
            if (!account.validatePassword(password)) {
                return Result.getFailed(AccountErrorCode.PASSWORD_IS_WRONG);
            }
        }
        // 生成一个地址作为智能合约地址
        Address contractAddress = AccountTool.createContractAddress();
        byte[] contractAddressBytes = contractAddress.getAddressBytes();
        byte[] senderBytes = AddressTool.getAddress(sender);
        CreateContractTransaction tx = new CreateContractTransaction();
        if (StringUtils.isNotBlank(remark)) {
            try {
                tx.setRemark(remark.getBytes(NulsConfig.DEFAULT_ENCODING));
            } catch (UnsupportedEncodingException e) {
                Log.error(e);
                throw new RuntimeException(e);
            }
        }
        tx.setTime(TimeService.currentTimeMillis());
        // 计算CoinData
        /*
             * 智能合约计算手续费以消耗的Gas*Price为根据,然而创建交易时并不执行智能合约,
             * 所以此时交易的CoinData是不固定的,比实际要多,
             * 打包时执行智能合约,真实的手续费已算出,然而tx的手续费已扣除,
             * 多扣除的费用会以CoinBase交易还给Sender
             */
        CoinData coinData = new CoinData();
        BlockHeader blockHeader = NulsContext.getInstance().getBestBlock().getHeader();
        // 当前区块高度
        long blockHeight = blockHeader.getHeight();
        // 当前区块状态根
        byte[] prevStateRoot = ContractUtil.getStateRoot(blockHeader);
        AssertUtil.canNotEmpty(prevStateRoot, "All features of the smart contract are locked.");
        // 执行VM验证合法性
        ProgramCreate programCreate = new ProgramCreate();
        programCreate.setContractAddress(contractAddressBytes);
        programCreate.setSender(senderBytes);
        programCreate.setValue(BigInteger.valueOf(value.getValue()));
        programCreate.setPrice(price.longValue());
        programCreate.setGasLimit(gasLimit.longValue());
        programCreate.setNumber(blockHeight);
        programCreate.setContractCode(contractCode);
        if (args != null) {
            programCreate.setArgs(args);
        }
        ProgramExecutor track = programExecutor.begin(prevStateRoot);
        // 验证合约时跳过Gas验证
        long realGasLimit = programCreate.getGasLimit();
        programCreate.setGasLimit(MAX_GASLIMIT);
        ProgramResult programResult = track.create(programCreate);
        // 执行结果失败时,交易直接返回错误,不上链,不消耗Gas,
        if (!programResult.isSuccess()) {
            Log.error(programResult.getStackTrace());
            Result result = Result.getFailed(ContractErrorCode.DATA_ERROR);
            result.setMsg(ContractUtil.simplifyErrorMsg(programResult.getErrorMessage()));
            result = checkVmResultAndReturn(programResult.getErrorMessage(), result);
            return result;
        } else {
            // 其他合法性都通过后,再验证Gas
            track = programExecutor.begin(prevStateRoot);
            programCreate.setGasLimit(realGasLimit);
            programResult = track.create(programCreate);
            if (!programResult.isSuccess()) {
                Log.error(programResult.getStackTrace());
                Result result = Result.getFailed(ContractErrorCode.DATA_ERROR);
                result.setMsg(ContractUtil.simplifyErrorMsg(programResult.getErrorMessage()));
                return result;
            }
        }
        long gasUsed = gasLimit.longValue();
        Na imputedNa = Na.valueOf(LongUtils.mul(gasUsed, price));
        // 总花费
        Na totalNa = imputedNa.add(value);
        // 组装txData
        CreateContractData createContractData = new CreateContractData();
        createContractData.setSender(senderBytes);
        createContractData.setContractAddress(contractAddressBytes);
        createContractData.setValue(value.getValue());
        createContractData.setGasLimit(gasLimit);
        createContractData.setPrice(price);
        createContractData.setCodeLen(contractCode.length);
        createContractData.setCode(contractCode);
        if (args != null) {
            createContractData.setArgsCount((byte) args.length);
            if (args.length > 0) {
                createContractData.setArgs(args);
            }
        }
        tx.setTxData(createContractData);
        CoinDataResult coinDataResult = accountLedgerService.getCoinData(senderBytes, totalNa, tx.size() + coinData.size(), TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES);
        if (!coinDataResult.isEnough()) {
            return Result.getFailed(TransactionErrorCode.INSUFFICIENT_BALANCE);
        }
        coinData.setFrom(coinDataResult.getCoinList());
        // 找零的UTXO
        if (coinDataResult.getChange() != null) {
            coinData.getTo().add(coinDataResult.getChange());
        }
        tx.setCoinData(coinData);
        tx.setHash(NulsDigestData.calcDigestData(tx.serializeForHash()));
        // 生成签名
        List<ECKey> signEckeys = new ArrayList<>();
        List<ECKey> scriptEckeys = new ArrayList<>();
        ECKey eckey = account.getEcKey(password);
        // 如果最后一位为1则表示该交易包含普通签名
        if ((coinDataResult.getSignType() & 0x01) == 0x01) {
            signEckeys.add(eckey);
        }
        // 如果倒数第二位位为1则表示该交易包含脚本签名
        if ((coinDataResult.getSignType() & 0x02) == 0x02) {
            scriptEckeys.add(eckey);
        }
        SignatureUtil.createTransactionSignture(tx, scriptEckeys, signEckeys);
        // 保存未确认交易到本地账本
        Result saveResult = accountLedgerService.verifyAndSaveUnconfirmedTransaction(tx);
        if (saveResult.isFailed()) {
            if (KernelErrorCode.DATA_SIZE_ERROR.getCode().equals(saveResult.getErrorCode().getCode())) {
                // 重新算一次交易(不超出最大交易数据大小下)的最大金额
                Result rs = accountLedgerService.getMaxAmountOfOnce(senderBytes, tx, TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES);
                if (rs.isSuccess()) {
                    Na maxAmount = (Na) rs.getData();
                    rs = Result.getFailed(KernelErrorCode.DATA_SIZE_ERROR_EXTEND);
                    rs.setMsg(rs.getMsg() + maxAmount.toDouble());
                }
                return rs;
            }
            return saveResult;
        }
        // 广播交易
        Result sendResult = transactionService.broadcastTx(tx);
        if (sendResult.isFailed()) {
            accountLedgerService.deleteTransaction(tx);
            return sendResult;
        }
        Map<String, String> resultMap = MapUtil.createHashMap(2);
        String txHash = tx.getHash().getDigestHex();
        String contractAddressStr = AddressTool.getStringAddressByBytes(contractAddressBytes);
        resultMap.put("txHash", txHash);
        resultMap.put("contractAddress", contractAddressStr);
        // 保留未确认的创建合约交易到内存中
        this.saveLocalUnconfirmedCreateContractTransaction(sender, resultMap, tx.getTime());
        return Result.getSuccess().setData(resultMap);
    } catch (IOException e) {
        Log.error(e);
        Result result = Result.getFailed(ContractErrorCode.CONTRACT_TX_CREATE_ERROR);
        result.setMsg(e.getMessage());
        return result;
    } catch (NulsException e) {
        Log.error(e);
        return Result.getFailed(e.getErrorCode());
    } catch (Exception e) {
        Log.error(e);
        Result result = Result.getFailed(ContractErrorCode.CONTRACT_TX_CREATE_ERROR);
        result.setMsg(e.getMessage());
        return result;
    }
}
Also used : Account(io.nuls.account.model.Account) ECKey(io.nuls.core.tools.crypto.ECKey) ContractResult(io.nuls.contract.dto.ContractResult) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult) NulsException(io.nuls.kernel.exception.NulsException) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) CreateContractTransaction(io.nuls.contract.entity.tx.CreateContractTransaction) NulsException(io.nuls.kernel.exception.NulsException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) CreateContractData(io.nuls.contract.entity.txdata.CreateContractData)

Aggregations

NulsException (io.nuls.kernel.exception.NulsException)109 IOException (java.io.IOException)35 Account (io.nuls.account.model.Account)25 ValidateResult (io.nuls.kernel.validate.ValidateResult)23 ECKey (io.nuls.core.tools.crypto.ECKey)20 CoinDataResult (io.nuls.account.ledger.model.CoinDataResult)18 NulsRuntimeException (io.nuls.kernel.exception.NulsRuntimeException)16 UnsupportedEncodingException (java.io.UnsupportedEncodingException)14 TransferTransaction (io.nuls.protocol.model.tx.TransferTransaction)13 Coin (io.nuls.kernel.model.Coin)12 MultiSigAccount (io.nuls.account.model.MultiSigAccount)11 ContractResult (io.nuls.contract.dto.ContractResult)9 NulsByteBuffer (io.nuls.kernel.utils.NulsByteBuffer)9 ArrayList (java.util.ArrayList)9 TransactionSignature (io.nuls.kernel.script.TransactionSignature)8 BigInteger (java.math.BigInteger)8 TransactionDataResult (io.nuls.account.ledger.model.TransactionDataResult)7 AccountPo (io.nuls.account.storage.po.AccountPo)7 AliasPo (io.nuls.account.storage.po.AliasPo)7 CryptoException (io.nuls.core.tools.crypto.Exception.CryptoException)7