use of io.nuls.contract.vm.program.ProgramResult in project nuls by nuls-io.
the class CreateContractTxProcessor method onCommit.
@Override
public Result onCommit(CreateContractTransaction tx, Object secondaryData) {
ContractResult contractResult = tx.getContractResult();
contractService.saveContractExecuteResult(tx.getHash(), contractResult);
CreateContractData txData = tx.getTxData();
byte[] contractAddress = txData.getContractAddress();
byte[] sender = txData.getSender();
String senderStr = AddressTool.getStringAddressByBytes(sender);
String contractAddressStr = AddressTool.getStringAddressByBytes(contractAddress);
// 移除未确认的创建合约交易
contractTxService.removeLocalUnconfirmedCreateContractTransaction(senderStr, contractAddressStr, contractResult);
// 执行失败的合约直接返回
if (!contractResult.isSuccess()) {
return Result.getSuccess();
}
NulsDigestData hash = tx.getHash();
long blockHeight = tx.getBlockHeight();
long bestBlockHeight = NulsContext.getInstance().getBestHeight();
ContractAddressInfoPo info = new ContractAddressInfoPo();
info.setContractAddress(contractAddress);
info.setSender(sender);
try {
info.setCreateTxHash(hash.serialize());
} catch (IOException e) {
throw new NulsRuntimeException(e);
}
info.setCreateTime(tx.getTime());
info.setBlockHeight(blockHeight);
// byte[] stateRoot = contractResult.getStateRoot();
boolean isNrc20Contract = contractResult.isNrc20();
boolean acceptDirectTransfer = contractResult.isAcceptDirectTransfer();
info.setAcceptDirectTransfer(acceptDirectTransfer);
info.setNrc20(isNrc20Contract);
// 获取 token tracker
if (isNrc20Contract) {
BlockHeader blockHeader = tx.getBlockHeader();
byte[] newestStateRoot = blockHeader.getStateRoot();
// NRC20 token 标准方法获取名称数据
ProgramResult programResult = vmHelper.invokeViewMethod(newestStateRoot, bestBlockHeight, contractAddress, NRC20_METHOD_NAME, null, null);
if (programResult.isSuccess()) {
String tokenName = programResult.getResult();
info.setNrc20TokenName(tokenName);
}
programResult = vmHelper.invokeViewMethod(newestStateRoot, bestBlockHeight, contractAddress, NRC20_METHOD_SYMBOL, null, null);
if (programResult.isSuccess()) {
String symbol = programResult.getResult();
info.setNrc20TokenSymbol(symbol);
}
programResult = vmHelper.invokeViewMethod(newestStateRoot, bestBlockHeight, contractAddress, NRC20_METHOD_DECIMALS, null, null);
if (programResult.isSuccess()) {
String decimals = programResult.getResult();
if (StringUtils.isNotBlank(decimals)) {
try {
info.setDecimals(new BigInteger(decimals).longValue());
} catch (Exception e) {
Log.error("Get nrc20 decimals error.", e);
// skip it
}
}
}
programResult = vmHelper.invokeViewMethod(newestStateRoot, bestBlockHeight, contractAddress, NRC20_METHOD_TOTAL_SUPPLY, null, null);
if (programResult.isSuccess()) {
String totalSupply = programResult.getResult();
if (StringUtils.isNotBlank(totalSupply)) {
try {
info.setTotalSupply(new BigInteger(totalSupply));
} catch (Exception e) {
Log.error("Get nrc20 totalSupply error.", e);
// skip it
}
}
}
// 刷新创建者的token余额
vmHelper.refreshTokenBalance(newestStateRoot, info, senderStr, contractAddressStr);
// 处理合约事件
vmHelper.dealEvents(newestStateRoot, tx, contractResult, info);
}
Result result = contractAddressStorageService.saveContractAddress(contractAddress, info);
return result;
}
use of io.nuls.contract.vm.program.ProgramResult in project nuls by nuls-io.
the class NativeAddress method call.
private static String call(String address, String methodName, String methodDesc, String[][] args, BigInteger value, Frame frame) {
if (value.compareTo(BigInteger.ZERO) < 0) {
throw new ErrorException(String.format("amount less than zero, value=%s", value), frame.vm.getGasUsed(), null);
}
ProgramInvoke programInvoke = frame.vm.getProgramInvoke();
ProgramCall programCall = new ProgramCall();
programCall.setNumber(programInvoke.getNumber());
programCall.setSender(programInvoke.getContractAddress());
programCall.setValue(value != null ? value : BigInteger.ZERO);
programCall.setGasLimit(programInvoke.getGasLimit() - frame.vm.getGasUsed());
programCall.setPrice(programInvoke.getPrice());
programCall.setContractAddress(NativeAddress.toBytes(address));
programCall.setMethodName(methodName);
programCall.setMethodDesc(methodDesc);
programCall.setArgs(args);
programCall.setEstimateGas(programInvoke.isEstimateGas());
programCall.setViewMethod(programInvoke.isViewMethod());
programCall.setInternalCall(true);
if (programCall.getValue().compareTo(BigInteger.ZERO) > 0) {
checkBalance(programCall.getSender(), programCall.getValue(), frame);
frame.vm.getProgramExecutor().getAccount(programCall.getSender()).addBalance(programCall.getValue().negate());
ProgramTransfer programTransfer = new ProgramTransfer(programCall.getSender(), programCall.getContractAddress(), programCall.getValue());
frame.vm.getTransfers().add(programTransfer);
}
ProgramResult programResult = frame.vm.getProgramExecutor().callProgramExecutor().call(programCall);
frame.vm.addGasUsed(programResult.getGasUsed());
if (programResult.isSuccess()) {
frame.vm.getTransfers().addAll(programResult.getTransfers());
frame.vm.getEvents().addAll(programResult.getEvents());
return programResult.getResult();
} else if (programResult.isError()) {
// return null;
throw new ErrorException(programResult.getErrorMessage(), programResult.getGasUsed(), programResult.getStackTrace());
} else {
throw new RuntimeException("error contract status");
}
}
Aggregations