use of io.nuls.account.model.Account in project nuls by nuls-io.
the class AccountLedgerServiceImpl method getBalance.
@Override
public Result<Balance> getBalance(byte[] address) {
if (address == null || address.length != Address.ADDRESS_LENGTH) {
return Result.getFailed(AccountErrorCode.ADDRESS_ERROR);
}
Account account = AccountLegerUtils.isLocalAccount(address);
if (null == account) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST);
}
Balance balance;
if (account.isOk()) {
balance = balanceManager.getBalance(address).getData();
} else {
balance = new Balance();
Result<UtxoAccountsBalance> result = this.utxoAccountsBalanceService.getUtxoAccountsBalance(address);
if (!result.isFailed()) {
UtxoAccountsBalance uab = result.getData();
balance.setBalance(uab.getBalance());
balance.setLocked(uab.getHadLocked());
balance.setUsable(balance.getBalance().subtract(balance.getLocked()));
}
}
if (balance == null) {
return Result.getFailed(AccountErrorCode.ACCOUNT_NOT_EXIST);
}
return Result.getSuccess().setData(balance);
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class AccountLedgerServiceImpl method transfer.
@Override
public Result transfer(byte[] from, byte[] to, Na values, String password, byte[] remark, Na price) {
try {
if (NulsContext.WALLET_STATUS == NulsConstant.SYNCHING) {
return Result.getFailed(KernelErrorCode.WALLET_STATUS_SYNCHING);
} else if (NulsContext.WALLET_STATUS == NulsConstant.ROLLBACK) {
return Result.getFailed(KernelErrorCode.WALLET_STATUS_ROLLBACK);
}
Result<Account> accountResult = accountService.getAccount(from);
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);
}
// 检查to是否为合约地址,如果是合约地址,则返回错误
if (contractService.isContractAddress(to)) {
return Result.getFailed(ContractErrorCode.NON_CONTRACTUAL_TRANSACTION_NO_TRANSFER);
}
TransferTransaction tx = new TransferTransaction();
tx.setRemark(remark);
tx.setTime(TimeService.currentTimeMillis());
CoinData coinData = new CoinData();
// 如果为多签地址则以脚本方式存储
Coin toCoin;
if (to[2] == NulsContext.P2SH_ADDRESS_TYPE) {
Script scriptPubkey = SignatureUtil.createOutputScript(to);
toCoin = new Coin(scriptPubkey.getProgram(), values);
} else {
toCoin = new Coin(to, values);
}
coinData.getTo().add(toCoin);
if (price == null) {
price = TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES;
}
CoinDataResult coinDataResult = getCoinData(from, values, tx.size() + coinData.size(), price);
if (!coinDataResult.isEnough()) {
return Result.getFailed(AccountLedgerErrorCode.INSUFFICIENT_BALANCE);
}
coinData.setFrom(coinDataResult.getCoinList());
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 = verifyAndSaveUnconfirmedTransaction(tx);
if (saveResult.isFailed()) {
if (KernelErrorCode.DATA_SIZE_ERROR.getCode().equals(saveResult.getErrorCode().getCode())) {
// 重新算一次交易(不超出最大交易数据大小下)的最大金额
Result rs = getMaxAmountOfOnce(from, tx, price);
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;
}
// transactionService.newTx(tx);
Result sendResult = transactionService.broadcastTx(tx);
if (sendResult.isFailed()) {
this.deleteTransaction(tx);
return sendResult;
}
return Result.getSuccess().setData(tx.getHash().getDigestHex());
} catch (IOException e) {
Log.error(e);
return Result.getFailed(KernelErrorCode.IO_ERROR);
} catch (NulsException e) {
Log.error(e);
return Result.getFailed(e.getErrorCode());
}
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class BalanceManager method initAccountBalance.
/**
* 初始化缓存本地所有账户的余额信息
*/
public void initAccountBalance() {
balanceMap.clear();
Collection<Account> accounts = accountService.getAccountList().getData();
if (accounts == null) {
return;
}
for (Account account : accounts) {
try {
calBalanceByAddress(account.getAddress().getAddressBytes());
} catch (NulsException e) {
Log.info("getbalance of address[" + account.getAddress().getBase58() + "] error");
}
}
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class ContractResource method getContractCollectionList.
@GET
@Path("/wallet/list/{address}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "获取钱包账户的合约地址列表(账户创建的合约以及钱包收藏的合约)")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = ContractAddressDto.class) })
public RpcClientResult getContractCollectionList(@ApiParam(name = "address", value = "钱包账户地址", required = true) @PathParam("address") String address, @ApiParam(name = "pageNumber", value = "页码", required = true) @QueryParam("pageNumber") Integer pageNumber, @ApiParam(name = "pageSize", value = "每页条数", required = false) @QueryParam("pageSize") Integer pageSize) {
try {
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();
}
if (StringUtils.isBlank(address)) {
return Result.getFailed(LedgerErrorCode.NULL_PARAMETER).toRpcClientResult();
}
Result<Account> accountResult = accountService.getAccount(address);
if (accountResult.isFailed()) {
return accountResult.toRpcClientResult();
}
byte[] addressBytes = AddressTool.getAddress(address);
LinkedHashMap<String, ContractAddressDto> resultMap = new LinkedHashMap<>();
// 该账户创建的未确认的合约
LinkedList<Map<String, String>> list = contractTxService.getLocalUnconfirmedCreateContractTransaction(address);
if (list != null) {
String contractAddress;
Long time;
ContractAddressDto dto;
String success;
for (Map<String, String> map : list) {
contractAddress = map.get("contractAddress");
time = Long.valueOf(map.get("time"));
dto = new ContractAddressDto();
dto.setCreate(true);
dto.setContractAddress(contractAddress);
dto.setCreateTime(time);
success = map.get("success");
if (StringUtils.isNotBlank(success)) {
// 合约创建失败
dto.setStatus(3);
dto.setMsg(map.get("msg"));
} else {
dto.setStatus(0);
}
resultMap.put(contractAddress, dto);
}
}
byte[] prevStateRoot = ContractUtil.getStateRoot(NulsContext.getInstance().getBestBlock().getHeader());
ProgramExecutor track = programExecutor.begin(prevStateRoot);
byte[] contractAddressBytes;
String contractAddress;
// 获取该账户创建的合约地址
Result<List<ContractAddressInfoPo>> contractInfoListResult = contractAddressStorageService.getContractInfoList(addressBytes);
List<ContractAddressInfoPo> contractAddressInfoPoList = contractInfoListResult.getData();
if (contractAddressInfoPoList != null && contractAddressInfoPoList.size() > 0) {
contractAddressInfoPoList.sort(new Comparator<ContractAddressInfoPo>() {
@Override
public int compare(ContractAddressInfoPo o1, ContractAddressInfoPo o2) {
return o1.compareTo(o2.getCreateTime());
}
});
for (ContractAddressInfoPo po : contractAddressInfoPoList) {
contractAddressBytes = po.getContractAddress();
contractAddress = AddressTool.getStringAddressByBytes(contractAddressBytes);
Result<ContractCollectionInfoPo> contractCollectionInfoPoResult = contractCollectionStorageService.getContractAddress(contractAddressBytes);
ContractCollectionInfoPo infoPo = contractCollectionInfoPoResult.getData();
if (infoPo == null) {
resultMap.put(contractAddress, new ContractAddressDto(po, true, track.status(contractAddressBytes).ordinal()));
} else {
resultMap.put(contractAddress, new ContractAddressDto(infoPo, address, true, track.status(contractAddressBytes).ordinal()));
}
}
}
// 获取收藏的合约地址
List<ContractCollectionInfoPo> contractCollectionPos = getContractAddressCollection(addressBytes);
if (contractCollectionPos.size() > 0) {
contractCollectionPos.sort(new Comparator<ContractCollectionInfoPo>() {
@Override
public int compare(ContractCollectionInfoPo o1, ContractCollectionInfoPo o2) {
return o1.compareTo(o2.getCreateTime());
}
});
for (ContractCollectionInfoPo po : contractCollectionPos) {
contractAddress = po.getContractAddress();
if (resultMap.containsKey(contractAddress)) {
continue;
}
contractAddressBytes = AddressTool.getAddress(contractAddress);
resultMap.put(contractAddress, new ContractAddressDto(po, address, false, track.status(contractAddressBytes).ordinal()));
}
}
List<ContractAddressDto> infoList = new ArrayList<>(resultMap.values());
Result result = Result.getSuccess();
List<ContractAddressDto> contractAddressDtoList = new ArrayList<>();
Page<ContractAddressDto> page = new Page<>(pageNumber, pageSize, infoList.size());
int start = pageNumber * pageSize - pageSize;
if (start >= page.getTotal()) {
result.setData(page);
return result.toRpcClientResult();
}
int end = start + pageSize;
if (end > page.getTotal()) {
end = (int) page.getTotal();
}
if (infoList.size() > 0) {
for (int i = start; i < end; i++) {
contractAddressDtoList.add(infoList.get(i));
}
}
page.setList(contractAddressDtoList);
result.setSuccess(true);
result.setData(page);
return result.toRpcClientResult();
} catch (Exception e) {
Log.error(e);
return Result.getFailed(LedgerErrorCode.SYS_UNKOWN_EXCEPTION).toRpcClientResult();
}
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class ContractResource method getTxList.
@GET
@Path("/tx/list/{contractAddress}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "获取智能合约的交易列表")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = ContractTransactionInfoDto.class) })
public RpcClientResult getTxList(@ApiParam(name = "contractAddress", value = "智能合约地址", required = true) @PathParam("contractAddress") String contractAddress, @ApiParam(name = "pageNumber", value = "页码", required = true) @QueryParam("pageNumber") Integer pageNumber, @ApiParam(name = "pageSize", value = "每页条数", required = false) @QueryParam("pageSize") Integer pageSize, @ApiParam(name = "accountAddress", value = "钱包账户地址") @QueryParam("accountAddress") String accountAddress) {
try {
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();
}
if (StringUtils.isBlank(contractAddress)) {
return Result.getFailed(LedgerErrorCode.NULL_PARAMETER).toRpcClientResult();
}
boolean isFilterAccountAddress = false;
if (StringUtils.isNotBlank(accountAddress)) {
Result<Account> accountResult = accountService.getAccount(accountAddress);
if (accountResult.isFailed()) {
return accountResult.toRpcClientResult();
}
isFilterAccountAddress = true;
}
if (!AddressTool.validAddress(contractAddress)) {
return Result.getFailed(AccountErrorCode.ADDRESS_ERROR).toRpcClientResult();
}
byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
if (!ContractLedgerUtil.isExistContractAddress(contractAddressBytes)) {
return Result.getFailed(ContractErrorCode.CONTRACT_ADDRESS_NOT_EXIST).toRpcClientResult();
}
Result<List<TransactionInfoPo>> txInfoPoListResult = contractTransactionInfoService.getTxInfoList(contractAddressBytes);
List<TransactionInfoPo> orginTxInfoPoList = txInfoPoListResult.getData();
List<TransactionInfoPo> txInfoPoList = new ArrayList<>();
do {
if (orginTxInfoPoList == null || orginTxInfoPoList.size() == 0) {
break;
}
Stream<TransactionInfoPo> transactionInfoPoStream = orginTxInfoPoList.stream().filter(po -> po.getTxType() != ContractConstant.TX_TYPE_CONTRACT_TRANSFER);
// 筛选出和账户相关的合约交易
if (isFilterAccountAddress) {
byte[] accountAddressBytes = AddressTool.getAddress(accountAddress);
txInfoPoList = transactionInfoPoStream.filter(po -> checkEquals(po.getAddresses(), accountAddressBytes, 0)).collect(Collectors.toList());
} else {
txInfoPoList = transactionInfoPoStream.collect(Collectors.toList());
;
}
} while (false);
Result result = Result.getSuccess();
List<ContractTransactionDto> infoDtoList = new ArrayList<>();
Page<ContractTransactionDto> page = new Page<>(pageNumber, pageSize, txInfoPoList.size());
int start = pageNumber * pageSize - pageSize;
if (start >= page.getTotal()) {
result.setData(page);
return result.toRpcClientResult();
}
int end = start + pageSize;
if (end > page.getTotal()) {
end = (int) page.getTotal();
}
// List<ContractTransactionInfoDto> resultList = new ArrayList<>();
if (txInfoPoList.size() > 0) {
txInfoPoList.sort(new Comparator<TransactionInfoPo>() {
@Override
public int compare(TransactionInfoPo o1, TransactionInfoPo o2) {
return o1.compareTo(o2.getTime());
}
});
for (int i = start; i < end; i++) {
TransactionInfoPo info = txInfoPoList.get(i);
RpcClientResult txResult = this.getContractTx(info.getTxHash().getDigestHex());
if (txResult.isFailed()) {
continue;
}
infoDtoList.add((ContractTransactionDto) txResult.getData());
}
}
page.setList(infoDtoList);
result.setSuccess(true);
result.setData(page);
return result.toRpcClientResult();
} catch (Exception e) {
Log.error(e);
Result result = Result.getFailed(LedgerErrorCode.SYS_UNKOWN_EXCEPTION);
return result.toRpcClientResult();
}
}
Aggregations