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();
}
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;
}
}
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();
}
}
Aggregations