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