use of io.nuls.contract.vm.program.ProgramTransfer in project nuls by nuls-io.
the class NativeAddress method transfer.
/**
* native
*
* @see Address#transfer(BigInteger)
*/
private static Result transfer(MethodCode methodCode, MethodArgs methodArgs, Frame frame) {
ObjectRef addressRef = methodArgs.objectRef;
ObjectRef valueRef = (ObjectRef) methodArgs.invokeArgs[0];
String address = frame.heap.runToString(addressRef);
BigInteger value = frame.heap.toBigInteger(valueRef);
byte[] from = frame.vm.getProgramInvoke().getContractAddress();
byte[] to = NativeAddress.toBytes(address);
if (Arrays.equals(from, to)) {
throw new ErrorException(String.format("Cannot transfer from %s to %s", NativeAddress.toString(from), address), frame.vm.getGasUsed(), null);
}
checkBalance(from, value, frame);
frame.vm.addGasUsed(GasCost.TRANSFER);
if (frame.heap.existContract(to)) {
// String address;
String methodName = "_payable";
String methodDesc = "()V";
String[][] args = null;
// BigInteger value;
call(address, methodName, methodDesc, args, value, frame);
} else {
frame.vm.getProgramExecutor().getAccount(from).addBalance(value.negate());
ProgramTransfer programTransfer = new ProgramTransfer(from, to, value);
frame.vm.getTransfers().add(programTransfer);
}
Result result = NativeMethod.result(methodCode, null, frame);
return result;
}
use of io.nuls.contract.vm.program.ProgramTransfer 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