use of co.rsk.core.RskAddress in project rskj by rsksmart.
the class Program method send.
public void send(DataWord destAddress, Coin amount) {
RskAddress owner = new RskAddress(getOwnerAddress());
RskAddress dest = new RskAddress(destAddress);
Coin balance = getStorage().getBalance(owner);
if (isNotCovers(balance, amount)) {
// does not do anything.
return;
}
if (isLogEnabled) {
logger.info("Transfer to: [{}] amount: [{}]", dest, amount);
}
addInternalTx(null, null, owner, dest, amount, null, "send");
getStorage().transfer(owner, dest, amount);
}
use of co.rsk.core.RskAddress in project rskj by rsksmart.
the class Program method createContract.
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public void createContract(DataWord value, DataWord memStart, DataWord memSize) {
if (getCallDeep() == MAX_DEPTH) {
stackPushZero();
return;
}
RskAddress senderAddress = new RskAddress(getOwnerAddress());
Coin endowment = new Coin(value.getData());
if (isNotCovers(getStorage().getBalance(senderAddress), endowment)) {
stackPushZero();
return;
}
// [1] FETCH THE CODE FROM THE MEMORY
byte[] programCode = memoryChunk(memStart.intValue(), memSize.intValue());
if (isLogEnabled) {
logger.info("creating a new contract inside contract run: [{}]", senderAddress);
}
// actual gas subtract
long gasLimit = getRemainingGas();
spendGas(gasLimit, "internal call");
// [2] CREATE THE CONTRACT ADDRESS
byte[] nonce = getStorage().getNonce(senderAddress).toByteArray();
byte[] newAddressBytes = HashUtil.calcNewAddr(getOwnerAddress().getLast20Bytes(), nonce);
RskAddress newAddress = new RskAddress(newAddressBytes);
if (byTestingSuite()) {
// This keeps track of the contracts created for a test
getResult().addCallCreate(programCode, EMPTY_BYTE_ARRAY, gasLimit, value.getNoLeadZeroesData());
}
// (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION)
if (!byTestingSuite()) {
getStorage().increaseNonce(senderAddress);
}
Repository track = getStorage().startTracking();
// In case of hashing collisions, check for any balance before createAccount()
if (track.isExist(newAddress)) {
Coin oldBalance = track.getBalance(newAddress);
track.createAccount(newAddress);
track.addBalance(newAddress, oldBalance);
} else {
track.createAccount(newAddress);
}
// [4] TRANSFER THE BALANCE
track.addBalance(senderAddress, endowment.negate());
Coin newBalance = Coin.ZERO;
if (!byTestingSuite()) {
newBalance = track.addBalance(newAddress, endowment);
}
// [5] COOK THE INVOKE AND EXECUTE
InternalTransaction internalTx = addInternalTx(nonce, getGasLimit(), senderAddress, RskAddress.nullAddress(), endowment, programCode, "create");
ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(this, new DataWord(newAddressBytes), getOwnerAddress(), value, gasLimit, newBalance, null, track, this.invoke.getBlockStore(), byTestingSuite());
ProgramResult programResult = ProgramResult.empty();
// reset return buffer right before the call
returnDataBuffer = null;
if (isNotEmpty(programCode)) {
VM vm = new VM(config, precompiledContracts);
Program program = new Program(config, precompiledContracts, blockchainConfig, programCode, programInvoke, internalTx);
vm.play(program);
programResult = program.getResult();
}
if (programResult.getException() != null || programResult.isRevert()) {
if (isLogEnabled) {
logger.debug("contract run halted by Exception: contract: [{}], exception: [{}]", newAddress, programResult.getException());
}
if (internalTx == null) {
throw new NullPointerException();
}
internalTx.reject();
programResult.rejectInternalTransactions();
programResult.rejectLogInfos();
track.rollback();
stackPushZero();
if (programResult.getException() != null) {
return;
} else {
returnDataBuffer = result.getHReturn();
}
} else {
// 4. CREATE THE CONTRACT OUT OF RETURN
byte[] code = programResult.getHReturn();
int codeLength = getLength(code);
long storageCost = (long) codeLength * GasCost.CREATE_DATA;
long afterSpend = programInvoke.getGas() - storageCost - programResult.getGasUsed();
if (afterSpend < 0) {
programResult.setException(ExceptionHelper.notEnoughSpendingGas("No gas to return just created contract", storageCost, this));
} else if (codeLength > Constants.getMaxContractSize()) {
programResult.setException(ExceptionHelper.tooLargeContractSize(Constants.getMaxContractSize(), codeLength));
} else {
programResult.spendGas(storageCost);
track.saveCode(newAddress, code);
}
track.commit();
getResult().addDeleteAccounts(programResult.getDeleteAccounts());
getResult().addLogInfos(programResult.getLogInfoList());
// IN SUCCESS PUSH THE ADDRESS INTO THE STACK
stackPush(new DataWord(newAddressBytes));
}
// 5. REFUND THE REMAIN GAS
long refundGas = gasLimit - programResult.getGasUsed();
if (refundGas > 0) {
refundGas(refundGas, "remain gas from the internal call");
if (isGasLogEnabled) {
gasLogger.info("The remaining gas is refunded, account: [{}], gas: [{}] ", Hex.toHexString(getOwnerAddress().getLast20Bytes()), refundGas);
}
}
}
use of co.rsk.core.RskAddress in project rskj by rsksmart.
the class Program method storageSave.
public void storageSave(byte[] key, byte[] val) {
// DataWord constructor some times reference the passed byte[] instead
// of making a copy.
DataWord keyWord = new DataWord(key);
DataWord valWord = new DataWord(val);
// If DataWords will be reused, then we must clone them.
if (useDataWordPool) {
keyWord = keyWord.clone();
valWord = valWord.clone();
}
getStorage().addStorageRow(new RskAddress(getOwnerAddress()), keyWord, valWord);
}
use of co.rsk.core.RskAddress in project rskj by rsksmart.
the class ProgramTrace method getContractDetails.
private static ContractDetails getContractDetails(ProgramInvoke programInvoke) {
Repository repository = programInvoke.getRepository();
if (repository instanceof RepositoryTrack) {
repository = ((RepositoryTrack) repository).getOriginRepository();
}
RskAddress addr = new RskAddress(programInvoke.getOwnerAddress());
return repository.getContractDetails(addr);
}
use of co.rsk.core.RskAddress in project rskj by rsksmart.
the class Tx method create.
public static Transaction create(RskSystemProperties config, long value, long gaslimit, long gasprice, long nonce, long data, long sender) {
Random r = new Random(sender);
Transaction transaction = Mockito.mock(Transaction.class);
Mockito.when(transaction.getValue()).thenReturn(new Coin(BigInteger.valueOf(value)));
Mockito.when(transaction.getGasLimit()).thenReturn(BigInteger.valueOf(gaslimit).toByteArray());
Mockito.when(transaction.getGasLimitAsInteger()).thenReturn(BigInteger.valueOf(gaslimit));
Mockito.when(transaction.getGasPrice()).thenReturn(Coin.valueOf(gasprice));
Mockito.when(transaction.getNonce()).thenReturn(BigInteger.valueOf(nonce).toByteArray());
Mockito.when(transaction.getNonceAsInteger()).thenReturn(BigInteger.valueOf(nonce));
byte[] returnSenderBytes = new byte[20];
r.nextBytes(returnSenderBytes);
RskAddress returnSender = new RskAddress(returnSenderBytes);
byte[] returnReceiveAddressBytes = new byte[20];
r.nextBytes(returnReceiveAddressBytes);
RskAddress returnReceiveAddress = new RskAddress(returnReceiveAddressBytes);
Mockito.when(transaction.getSender()).thenReturn(returnSender);
Mockito.when(transaction.getHash()).thenReturn(new Keccak256(TestUtils.randomBytes(32)));
Mockito.when(transaction.acceptTransactionSignature(config.getBlockchainConfig().getCommonConstants().getChainId())).thenReturn(Boolean.TRUE);
Mockito.when(transaction.getReceiveAddress()).thenReturn(returnReceiveAddress);
ArrayList<Byte> bytes = new ArrayList();
long amount = 21000;
if (data != 0) {
data /= 2;
for (int i = 0; i < data / 4; i++) {
bytes.add((byte) 0);
amount += 4;
}
for (int i = 0; i < data / 68; i++) {
bytes.add((byte) 1);
amount += 68;
}
}
int n = bytes.size();
byte[] b = new byte[n];
for (int i = 0; i < n; i++) {
b[i] = bytes.get(i);
}
Mockito.when(transaction.getData()).thenReturn(b);
Mockito.when(transaction.transactionCost(eq(config), any(Block.class))).thenReturn(amount);
return transaction;
}
Aggregations