// CREATE AND/OR EXECUTE CONTRACT
long gasUsed = 0;
if (isContractCreation || code != null) {
// START TRACKING FOR REVERT CHANGES OPTION
Repository trackRepository = repository.getTrack();
trackRepository.startTracking();
try {
// CREATE NEW CONTRACT ADDRESS AND ADD TX VALUE
if(isContractCreation) {
if (isValueTx) // adding to balance also creates the account
trackRepository.addBalance(receiverAddress, new BigInteger(1, tx.getValue()));
else
trackRepository.createAccount(receiverAddress);
if(stateLogger.isDebugEnabled())
stateLogger.debug("new contract created address={}",
Hex.toHexString(receiverAddress));
}
Block currBlock = (block == null) ? this.getBestBlock() : block;
ProgramInvoke programInvoke =
programInvokeFactory.createProgramInvoke(tx, currBlock, trackRepository);
VM vm = new VM();
Program program = new Program(code, programInvoke);
if (CONFIG.playVM())
vm.play(program);
program.saveProgramTraceToFile(Hex.toHexString(tx.getHash()));
ProgramResult result = program.getResult();
applyProgramResult(result, gasDebit, gasPrice, trackRepository,
senderAddress, receiverAddress, coinbase, isContractCreation);
gasUsed = result.getGasUsed();
} catch (RuntimeException e) {
trackRepository.rollback();
return new BigInteger(1, tx.getGasLimit()).longValue();
}
trackRepository.commit();
} else {
// REFUND GASDEBIT EXCEPT FOR FEE (500 + 5*TXDATA)
long dataCost = tx.getData() == null ? 0: tx.getData().length * GasCost.TXDATA;
gasUsed = GasCost.TRANSACTION + dataCost;