use of io.nuls.account.model.Account in project nuls by nuls-io.
the class ContractResource method contractCollection.
@POST
@Path("/collection")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "收藏智能合约地址/修改备注名称")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success") })
public RpcClientResult contractCollection(@ApiParam(name = "collection", value = "收藏智能合约地址/修改备注名称", required = true) ContractCollection collection) {
try {
if (collection == null) {
return Result.getFailed(ContractErrorCode.NULL_PARAMETER).toRpcClientResult();
}
// 钱包账户地址
String address = collection.getAccountAddress();
if (StringUtils.isBlank(address)) {
return Result.getFailed(LedgerErrorCode.NULL_PARAMETER).toRpcClientResult();
}
Result<Account> accountResult = accountService.getAccount(address);
if (accountResult.isFailed()) {
return accountResult.toRpcClientResult();
}
// 合约地址
String contractAddress = collection.getContractAddress();
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();
}
// 备注名称
String remarkName = collection.getRemarkName();
// 获取合约地址的基本信息, 用到两个信息 - 创建者、创建交易hash
Result<ContractAddressInfoPo> contractAddressInfoPoResult = contractAddressStorageService.getContractAddressInfo(contractAddressBytes);
ContractAddressInfoPo contractAddressInfoPo = contractAddressInfoPoResult.getData();
if (contractAddressInfoPo == null) {
return Result.getFailed(ContractErrorCode.DATA_NOT_FOUND).toRpcClientResult();
}
// 获取该合约的收藏数据
Result<ContractCollectionInfoPo> collectionInfoPoResult = contractCollectionStorageService.getContractAddress(contractAddressBytes);
ContractCollectionInfoPo po = collectionInfoPoResult.getData();
Map<String, String> collectorMap;
if (po != null) {
collectorMap = po.getCollectorMap();
if (collectorMap.containsKey(address)) {
String preRemarkName = collectorMap.get(address);
if (preRemarkName.equals(remarkName)) {
// 收藏者的信息没有变化,直接返回
return Result.getSuccess().toRpcClientResult();
}
} else {
collectorMap.put(address, EMPTY);
}
} else {
po = new ContractCollectionInfoPo();
po.setCreater(contractAddressInfoPo.getSender());
po.setContractAddress(contractAddress);
po.setBlockHeight(contractAddressInfoPo.getBlockHeight());
Transaction tx = ledgerService.getTx(contractAddressInfoPo.getCreateTxHash());
if (tx == null) {
return Result.getFailed(ContractErrorCode.TX_NOT_EXIST).toRpcClientResult();
}
po.setCreateTime(tx.getTime());
collectorMap = MapUtil.createHashMap(4);
collectorMap.put(address, EMPTY);
po.setCollectorMap(collectorMap);
}
// 备注名
if (StringUtils.isNotBlank(remarkName)) {
// if (!StringUtils.validAlias(remarkName)) {
// return Result.getFailed(ContractErrorCode.CONTRACT_NAME_FORMAT_INCORRECT).toRpcClientResult();
// }
collectorMap.put(address, remarkName);
}
Result result = contractCollectionStorageService.saveContractAddress(contractAddressBytes, po);
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 getTokenList.
@GET
@Path("/token/list/{address}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "获取NRC20合约的资产列表")
@ApiResponses(value = { @ApiResponse(code = 200, message = "success", response = ContractTokenInfoDto.class) })
public RpcClientResult getTokenList(@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();
}
Result<List<ContractTokenInfo>> tokenListResult = contractBalanceManager.getAllTokensByAccount(address);
if (tokenListResult.isFailed()) {
return tokenListResult.toRpcClientResult();
}
List<ContractTokenInfo> tokenInfoList = tokenListResult.getData();
Result result = Result.getSuccess();
List<ContractTokenInfoDto> tokenInfoDtoList = new ArrayList<>();
Page<ContractTokenInfoDto> page = new Page<>(pageNumber, pageSize, tokenInfoList.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 (tokenInfoList.size() > 0) {
for (int i = start; i < end; i++) {
ContractTokenInfo info = tokenInfoList.get(i);
tokenInfoDtoList.add(new ContractTokenInfoDto(info));
}
}
if (tokenInfoDtoList != null && tokenInfoDtoList.size() > 0) {
byte[] prevStateRoot = ContractUtil.getStateRoot(NulsContext.getInstance().getBestBlock().getHeader());
ProgramExecutor track = programExecutor.begin(prevStateRoot);
for (ContractTokenInfoDto tokenInfo : tokenInfoDtoList) {
tokenInfo.setStatus(track.status(AddressTool.getAddress(tokenInfo.getContractAddress())).ordinal());
}
}
page.setList(tokenInfoDtoList);
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();
}
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class AccountPo method toAccount.
public Account toAccount() {
Account account = new Account();
account.setCreateTime(this.getCreateTime());
try {
account.setAddress(Address.fromHashs(this.getAddress()));
} catch (Exception e) {
Log.error(e);
}
account.setAlias(this.getAlias());
account.setExtend(this.getExtend());
account.setPriKey(this.getPriKey());
account.setPubKey(this.getPubKey());
account.setEncryptedPriKey(this.getEncryptedPriKey());
if (this.getPriKey() != null && this.getPriKey().length > 1) {
account.setEcKey(ECKey.fromPrivate(new BigInteger(1, account.getPriKey())));
} else {
account.setEcKey(ECKey.fromEncrypted(new EncryptedData(this.getEncryptedPriKey()), this.getPubKey()));
}
account.setStatus(this.getStatus());
account.setRemark(this.remark);
account.setOk(this.ok);
return account;
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class ContractTxServiceImpl method validateContractCreateTx.
/**
* 验证创建生成智能合约的交易
*
* @param gasLimit 最大gas消耗
* @param price 执行合约单价
* @param contractCode 合约代码
* @param args 参数列表
* @return
*/
@Override
public Result validateContractCreateTx(Long gasLimit, Long price, byte[] contractCode, String[][] args) {
try {
AssertUtil.canNotEmpty(contractCode, "the contractCode can not be empty");
Na value = Na.ZERO;
if (!ContractUtil.checkPrice(price.longValue())) {
return Result.getFailed(ContractErrorCode.CONTRACT_MINIMUM_PRICE);
}
Account senderAccount = AccountTool.createAccount();
// 生成一个地址作为智能合约地址
Address contractAddress = AccountTool.createContractAddress();
byte[] contractAddressBytes = contractAddress.getAddressBytes();
byte[] senderBytes = senderAccount.getAddress().getAddressBytes();
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;
}
}
return Result.getSuccess();
} 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 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;
}
}
Aggregations