Search in sources :

Example 1 with DeleteContractData

use of io.nuls.contract.entity.txdata.DeleteContractData in project nuls by nuls-io.

the class ContractSdkResource method deleteContractTx.

@POST
@Path("/sdk/delete")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "delete smart contract transaction")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success") })
public RpcClientResult deleteContractTx(@ApiParam(name = "deleteForm", value = "delete smart contract transaction", required = true) DeleteContractTx deleteContractTx) {
    if (!AddressTool.validAddress(deleteContractTx.getSender())) {
        return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
    }
    String contractAddress = deleteContractTx.getContractAddress();
    if (!AddressTool.validAddress(contractAddress)) {
        return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
    }
    if (deleteContractTx.getUtxos().isEmpty()) {
        // utxo not null and size not zero.
        return Result.getFailed(AccountErrorCode.DATA_PARSE_ERROR).toRpcClientResult();
    }
    DeleteContractTransaction tx = new DeleteContractTransaction();
    if (StringUtils.isNotBlank(deleteContractTx.getRemark())) {
        try {
            tx.setRemark(deleteContractTx.getRemark().getBytes(NulsConfig.DEFAULT_ENCODING));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
    tx.setTime(TimeService.currentTimeMillis());
    byte[] senderBytes = AddressTool.getAddress(deleteContractTx.getSender());
    byte[] contractAddressBytes = AddressTool.getAddress(deleteContractTx.getContractAddress());
    /**
     * build tx data
     */
    DeleteContractData deleteContractData = new DeleteContractData();
    deleteContractData.setContractAddress(contractAddressBytes);
    deleteContractData.setSender(senderBytes);
    tx.setTxData(deleteContractData);
    List<Coin> coinList = ConvertCoinTool.convertCoinList(deleteContractTx.getUtxos());
    CoinDataResult coinDataResult = CoinDataTool.getCoinData(senderBytes, Na.ZERO, tx.size(), TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES, coinList);
    if (!coinDataResult.isEnough()) {
        return RpcClientResult.getFailed(TransactionErrorCode.INSUFFICIENT_BALANCE);
    }
    /**
     * build coin data
     */
    CoinData coinData = new CoinData();
    coinData.setFrom(coinDataResult.getCoinList());
    if (coinDataResult.getChange() != null) {
        coinData.getTo().add(coinDataResult.getChange());
    }
    tx.setCoinData(coinData);
    // 重置为0,重新计算交易对象的size
    tx.setSize(0);
    if (tx.getSize() > TxMaxSizeValidator.MAX_TX_SIZE) {
        return Result.getFailed(TransactionErrorCode.DATA_SIZE_ERROR).toRpcClientResult();
    }
    return this.buildReturnInfo(tx, contractAddress);
}
Also used : UnsupportedEncodingException(java.io.UnsupportedEncodingException) DeleteContractData(io.nuls.contract.entity.txdata.DeleteContractData) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult) DeleteContractTransaction(io.nuls.contract.entity.tx.DeleteContractTransaction) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces)

Example 2 with DeleteContractData

use of io.nuls.contract.entity.txdata.DeleteContractData 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 3 with DeleteContractData

use of io.nuls.contract.entity.txdata.DeleteContractData in project nuls by nuls-io.

the class ContractTransactionDto method makeTxData.

private Map<String, Object> makeTxData(Transaction tx) {
    Map<String, Object> result = new HashMap<>();
    TransactionLogicData txData = tx.getTxData();
    if (type == ContractConstant.TX_TYPE_CREATE_CONTRACT) {
        CreateContractData create = (CreateContractData) txData;
        result.put("data", new CreateContractDataDto(create));
    } else if (type == ContractConstant.TX_TYPE_CALL_CONTRACT) {
        CallContractData call = (CallContractData) txData;
        result.put("data", new CallContractDataDto(call));
    } else if (type == ContractConstant.TX_TYPE_DELETE_CONTRACT) {
        DeleteContractData delete = (DeleteContractData) txData;
        result.put("data", new DeleteContractDataDto(delete));
    } else if (type == ContractConstant.TX_TYPE_CONTRACT_TRANSFER) {
        ContractTransferData transfer = (ContractTransferData) txData;
        result.put("data", new ContractTransferDataDto(transfer));
    } else if (type == NulsConstant.TX_TYPE_COINBASE) {
        Map<String, String> map = MapUtil.createLinkedHashMap(1);
        map.put("sender", EMPTY);
        result.put("data", map);
    }
    return result;
}
Also used : HashMap(java.util.HashMap) CallContractData(io.nuls.contract.entity.txdata.CallContractData) ContractTransferData(io.nuls.contract.entity.txdata.ContractTransferData) CreateContractData(io.nuls.contract.entity.txdata.CreateContractData) DeleteContractData(io.nuls.contract.entity.txdata.DeleteContractData) TransactionLogicData(io.nuls.kernel.model.TransactionLogicData)

Example 4 with DeleteContractData

use of io.nuls.contract.entity.txdata.DeleteContractData in project nuls by nuls-io.

the class ContractTxServiceImpl method contractDeleteTx.

/**
 * 创建删除智能合约的交易
 *
 * @param sender          交易创建者
 * @param contractAddress 合约地址
 * @param password        账户密码
 * @param remark          备注
 * @return
 */
@Override
public Result contractDeleteTx(String sender, String contractAddress, String password, String remark) {
    try {
        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);
        }
        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);
        }
        DeleteContractTransaction tx = new DeleteContractTransaction();
        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());
        // 组装txData
        DeleteContractData deleteContractData = new DeleteContractData();
        deleteContractData.setContractAddress(contractAddressBytes);
        deleteContractData.setSender(senderBytes);
        tx.setTxData(deleteContractData);
        // 计算CoinData
        /*
             * 没有Gas消耗,在终止智能合约里
             */
        CoinData coinData = new CoinData();
        // 总花费 终止智能合约的交易手续费按普通交易计算手续费
        CoinDataResult coinDataResult = accountLedgerService.getCoinData(senderBytes, Na.ZERO, 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;
        }
        return Result.getSuccess().setData(tx.getHash().getDigestHex());
    } 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) ContractBalance(io.nuls.contract.ledger.module.ContractBalance) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ECKey(io.nuls.core.tools.crypto.ECKey) IOException(java.io.IOException) DeleteContractTransaction(io.nuls.contract.entity.tx.DeleteContractTransaction) 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) ContractAddressInfoPo(io.nuls.contract.storage.po.ContractAddressInfoPo) NulsException(io.nuls.kernel.exception.NulsException) DeleteContractData(io.nuls.contract.entity.txdata.DeleteContractData) CoinDataResult(io.nuls.account.ledger.model.CoinDataResult)

Aggregations

DeleteContractData (io.nuls.contract.entity.txdata.DeleteContractData)4 CoinDataResult (io.nuls.account.ledger.model.CoinDataResult)2 DeleteContractTransaction (io.nuls.contract.entity.tx.DeleteContractTransaction)2 ContractBalance (io.nuls.contract.ledger.module.ContractBalance)2 ContractAddressInfoPo (io.nuls.contract.storage.po.ContractAddressInfoPo)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 Account (io.nuls.account.model.Account)1 ContractResult (io.nuls.contract.dto.ContractResult)1 CallContractData (io.nuls.contract.entity.txdata.CallContractData)1 ContractTransferData (io.nuls.contract.entity.txdata.ContractTransferData)1 CreateContractData (io.nuls.contract.entity.txdata.CreateContractData)1 ECKey (io.nuls.core.tools.crypto.ECKey)1 NulsException (io.nuls.kernel.exception.NulsException)1 Na (io.nuls.kernel.model.Na)1 TransactionLogicData (io.nuls.kernel.model.TransactionLogicData)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 POST (javax.ws.rs.POST)1 Path (javax.ws.rs.Path)1 Produces (javax.ws.rs.Produces)1