use of io.nuls.account.model.Account in project nuls by nuls-io.
the class ContractTxServiceImpl method contractPreCreateTx.
/**
* 预创建生成智能合约的交易
* 用于测试合约是否能正确创建
*
* @param sender 交易创建者
* @param gasLimit 最大gas消耗
* @param price 执行合约单价
* @param contractCode 合约代码
* @param args 参数列表
* @param password 账户密码
* @param remark 备注
* @return
*/
@Override
public Result contractPreCreateTx(String sender, Long gasLimit, Long price, byte[] contractCode, String[][] args, String password, String remark) {
try {
AssertUtil.canNotEmpty(sender, "the sender address can not be empty");
AssertUtil.canNotEmpty(contractCode, "the contractCode can not be empty");
Na value = Na.ZERO;
Result<Account> accountResult = accountService.getAccount(sender);
if (accountResult.isFailed()) {
return accountResult;
}
// 生成一个地址作为智能合约地址
Address contractAddress = AccountTool.createContractAddress();
byte[] contractAddressBytes = contractAddress.getAddressBytes();
byte[] senderBytes = AddressTool.getAddress(sender);
CreateContractTransaction tx = new CreateContractTransaction();
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());
// 计算CoinData
/*
* 智能合约计算手续费以消耗的Gas*Price为根据,然而创建交易时并不执行智能合约,
* 所以此时交易的CoinData是不固定的,比实际要多,
* 打包时执行智能合约,真实的手续费已算出,然而tx的手续费已扣除,
* 多扣除的费用会以CoinBase交易还给Sender
*/
CoinData coinData = new CoinData();
// 向智能合约账户转账
if (!Na.ZERO.equals(value)) {
Coin toCoin = new Coin(contractAddressBytes, value);
coinData.getTo().add(toCoin);
}
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;
}
}
long gasUsed = gasLimit.longValue();
Na imputedNa = Na.valueOf(LongUtils.mul(gasUsed, price));
// 总花费
Na totalNa = imputedNa.add(value);
// 组装txData
CreateContractData createContractData = new CreateContractData();
createContractData.setSender(senderBytes);
createContractData.setContractAddress(contractAddressBytes);
createContractData.setValue(value.getValue());
createContractData.setGasLimit(gasLimit);
createContractData.setPrice(price);
createContractData.setCodeLen(contractCode.length);
createContractData.setCode(contractCode);
if (args != null) {
createContractData.setArgsCount((byte) args.length);
if (args.length > 0) {
createContractData.setArgs(args);
}
}
tx.setTxData(createContractData);
CoinDataResult coinDataResult = accountLedgerService.getCoinData(senderBytes, totalNa, tx.size(), TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES);
if (!coinDataResult.isEnough()) {
return Result.getFailed(TransactionErrorCode.INSUFFICIENT_BALANCE);
}
return Result.getSuccess();
} 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;
}
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class ContractTxServiceImpl method transferFee.
@Override
public Result transferFee(String sender, Na value, Long gasLimit, Long price, String contractAddress, String methodName, String methodDesc, String[][] args, String remark) {
try {
AssertUtil.canNotEmpty(sender, "the sender address can not be empty");
AssertUtil.canNotEmpty(contractAddress, "the contractAddress can not be empty");
AssertUtil.canNotEmpty(methodName, "the methodName can not be empty");
if (value == null) {
value = Na.ZERO;
}
Result<Account> accountResult = accountService.getAccount(sender);
if (accountResult.isFailed()) {
return accountResult;
}
byte[] senderBytes = AddressTool.getAddress(sender);
byte[] contractAddressBytes = AddressTool.getAddress(contractAddress);
BlockHeader blockHeader = NulsContext.getInstance().getBestBlock().getHeader();
// 当前区块状态根
byte[] prevStateRoot = ContractUtil.getStateRoot(blockHeader);
AssertUtil.canNotEmpty(prevStateRoot, "All features of the smart contract are locked.");
CallContractTransaction tx = new CallContractTransaction();
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());
CoinData coinData = new CoinData();
// 向智能合约账户转账
if (!Na.ZERO.equals(value)) {
Coin toCoin = new Coin(contractAddressBytes, value);
coinData.getTo().add(toCoin);
}
long gasUsed = gasLimit.longValue();
Na imputedGasUsedNa = Na.valueOf(LongUtils.mul(gasUsed, price));
// 总花费
Na totalNa = imputedGasUsedNa.add(value);
// 组装txData
CallContractData callContractData = new CallContractData();
callContractData.setContractAddress(contractAddressBytes);
callContractData.setSender(senderBytes);
callContractData.setValue(value.getValue());
callContractData.setPrice(price.longValue());
callContractData.setGasLimit(gasLimit.longValue());
callContractData.setMethodName(methodName);
callContractData.setMethodDesc(methodDesc);
if (args != null) {
callContractData.setArgsCount((byte) args.length);
callContractData.setArgs(args);
}
tx.setTxData(callContractData);
Na fee = accountLedgerService.getTxFee(senderBytes, totalNa, tx.size() + coinData.size(), TransactionFeeCalculator.MIN_PRICE_PRE_1024_BYTES);
fee = fee.add(imputedGasUsedNa);
return Result.getSuccess().setData(new Object[] { fee, tx });
} catch (Exception e) {
Log.error(e);
Result result = Result.getFailed(ContractErrorCode.SYS_UNKOWN_EXCEPTION);
result.setMsg(e.getMessage());
return result;
}
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class PocRewardCacheService method initCache.
public void initCache() {
Collection<Account> accountList = accountService.getAccountList().getData();
if (null == accountList || accountList.isEmpty()) {
return;
}
long startTime = TimeService.currentTimeMillis() - 24 * 3600000L;
long startHeight = NulsContext.getInstance().getBestHeight() - (24 * 3600 / ProtocolConstant.BLOCK_TIME_INTERVAL_SECOND);
if (startHeight <= 0) {
startHeight = 1;
}
long index = startHeight;
while (true) {
Block block = blockService.getBlock(index++).getData();
if (null == block) {
break;
}
if (block.getHeader().getHeight() < 1) {
break;
}
if (block.getHeader().getTime() < startTime) {
continue;
}
this.addBlock(block);
}
// 本地账户的历史收益累计
for (Account account : accountList) {
List<TransactionInfo> list = accountLedgerService.getTxInfoList(account.getAddress().getAddressBytes()).getData();
if (list == null || list.isEmpty()) {
continue;
}
calcRewardHistory(account.getAddress().getBase58(), list, startHeight);
}
long totalValue = ledgerService.getWholeUTXO();
this.totalRewardHeight = NulsContext.getInstance().getBestHeight();
this.totalReward = Na.valueOf(totalValue - Na.MAX_NA_VALUE);
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class MeetingRound method calcLocalPacker.
public void calcLocalPacker(Collection<Account> accountList) {
for (Account account : accountList) {
if (account.isEncrypted()) {
continue;
}
MeetingMember member = getMember(account.getAddress().getAddressBytes());
if (null != member) {
this.localPacker = account;
myMember = member;
return;
}
}
}
use of io.nuls.account.model.Account in project nuls by nuls-io.
the class AliasService method saveAlias.
/**
* 保存别名(全网)
* 1.保存别名alias至数据库
* 2.从数据库取出对应的account账户,将别名设置进account然后保存至数据库
* 3.将修改后的account重新进行缓存
* saveAlias
* 1. Save the alias to the database.
* 2. Take the corresponding account from the database, set the alias to account and save it to the database.
* 3. Re-cache the modified account.
*/
public Result saveAlias(AliasPo aliaspo) throws NulsException {
try {
Result result = aliasStorageService.saveAlias(aliaspo);
if (result.isFailed()) {
this.rollbackAlias(aliaspo);
}
AccountPo po = accountStorageService.getAccount(aliaspo.getAddress()).getData();
if (null != po) {
po.setAlias(aliaspo.getAlias());
Result resultAcc = accountStorageService.updateAccount(po);
if (resultAcc.isFailed()) {
this.rollbackAlias(aliaspo);
}
Account account = po.toAccount();
accountCacheService.localAccountMaps.put(account.getAddress().getBase58(), account);
}
} catch (Exception e) {
this.rollbackAlias(aliaspo);
Log.error(e);
return Result.getFailed(AccountErrorCode.FAILED);
}
return Result.getSuccess().setData(true);
}
Aggregations