use of org.aion.types.InternalTransaction in project aion by aionnetwork.
the class InvokableTransactionTest method encodeDecodeContractCreateTest.
@Test
public void encodeDecodeContractCreateTest() {
Transaction tx = Transaction.contractCreateTransaction(new AionAddress(key.getAddress()), new byte[0], BigInteger.ZERO, BigInteger.ZERO, new byte[0], 1L, 1L);
AionAddress executor = AddressUtils.ZERO_ADDRESS;
byte[] invokable = InvokableTxUtil.encodeInvokableTransaction(key, tx.nonce, tx.destinationAddress, tx.value, tx.copyOfTransactionData(), executor);
InternalTransaction tx2 = InvokableTxUtil.decode(invokable, AddressUtils.ZERO_ADDRESS, 1L, 1L);
assertNotNull(tx2);
assertEquals(tx.destinationAddress, tx2.destination);
assertEquals(tx.nonce, tx2.senderNonce);
assertEquals(tx.value, tx2.value);
assertArrayEquals(tx.copyOfTransactionData(), tx2.copyOfData());
}
use of org.aion.types.InternalTransaction in project aion by aionnetwork.
the class TokenBridgeContract method transfer.
/**
* Performs a transfer of value from one account to another, using a method that mimics to the
* best of it's ability the {@code CALL} opcode. There are some assumptions that become
* important for any caller to know:
*
* @implNote this method will check that the recipient account has no code. This means that we
* <b>cannot</b> do a transfer to any contract account.
* @implNote assumes that the {@code fromValue} derived from the worldState will never be null.
* @param dest recipient address
* @param value to be sent (in base units)
* @return {@code true} if value was performed, {@code false} otherwise
*/
public PrecompiledTransactionResult transfer(@Nonnull final byte[] dest, @Nonnull final BigInteger value) {
// some initial checks, treat as failure
if (this.externalState.getBalance(this.contractAddress).compareTo(value) < 0)
return new PrecompiledTransactionResult(TransactionStatus.nonRevertedFailure("FAILURE"), 0);
// assemble an internal transaction
AionAddress sender = this.contractAddress;
AionAddress destination = new AionAddress(dest);
BigInteger nonce = this.externalState.getNonce(sender);
byte[] dataToSend = new byte[0];
InternalTransaction tx = InternalTransaction.contractCallTransaction(RejectedStatus.NOT_REJECTED, sender, destination, nonce, value, dataToSend, 0L, 1L);
// add transaction to result
this.context.addInternalTransaction(tx);
// increase the nonce and do the transfer without executing code
this.externalState.incrementNonce(sender);
this.externalState.addBalance(sender, value.negate());
this.externalState.addBalance(destination, value);
// construct result
return new PrecompiledTransactionResult(TransactionStatus.successful(), 0);
}
use of org.aion.types.InternalTransaction in project aion by aionnetwork.
the class AionTxInfo method decodeToTxInfo.
private static AionTxInfo decodeToTxInfo(SharedRLPList rlpTxInfo) {
Objects.requireNonNull(rlpTxInfo);
AionTxReceipt receipt = new AionTxReceipt((SharedRLPList) rlpTxInfo.get(INDEX_RECEIPT));
ByteArrayWrapper blockHash = ByteArrayWrapper.wrap(rlpTxInfo.get(INDEX_BLOCK_HASH).getRLPData());
int index;
byte[] txIndex = rlpTxInfo.get(INDEX_TX_INDEX).getRLPData();
if (txIndex == null) {
index = 0;
} else {
index = new BigInteger(1, txIndex).intValue();
}
boolean createdWithInternalTx;
List<InternalTransaction> internalTransactions;
switch(rlpTxInfo.size()) {
case SIZE_OF_OLD_ENCODING:
// old encodings are incomplete since internal tx were not stored
createdWithInternalTx = false;
internalTransactions = null;
break;
case SIZE_WITH_BASE_DATA:
// read the completeness flag from storage
createdWithInternalTx = rlpTxInfo.get(INDEX_CREATE_FLAG).getRLPData().length == 1;
internalTransactions = null;
break;
case SIZE_WITH_INTERNAL_TRANSACTIONS:
// read the completeness flag from storage
createdWithInternalTx = rlpTxInfo.get(INDEX_CREATE_FLAG).getRLPData().length == 1;
// decode the internal transactions
internalTransactions = new ArrayList<>();
SharedRLPList internalTxRlp = (SharedRLPList) rlpTxInfo.get(INDEX_INTERNAL_TX);
for (RLPElement item : internalTxRlp) {
internalTransactions.add(fromRlp((SharedRLPList) item));
}
break;
default:
// incorrect encoding
return null;
}
return new AionTxInfo(receipt, blockHash, index, internalTransactions, createdWithInternalTx);
}
use of org.aion.types.InternalTransaction in project aion by aionnetwork.
the class AionTxInfo method toString.
@Override
public String toString() {
StringBuilder toStringBuff = new StringBuilder();
toStringBuff.setLength(0);
toStringBuff.append(" ").append("index=").append(index).append("\n");
toStringBuff.append(" ").append(receipt.toString()).append("\n");
if (hasInternalTransactions()) {
toStringBuff.append("\n produced ").append(internalTransactions.size()).append(" internal transactions:\n");
for (InternalTransaction itx : internalTransactions) {
toStringBuff.append("\t- ").append(itx).append("\n");
}
} else {
toStringBuff.append(createdWithInternalTransactions ? "\n produced 0 internal transactions\n" : "\n internal transactions not stored\n");
}
toStringBuff.append(" ").append(Hex.toHexString(this.getEncoded()));
return toStringBuff.toString();
}
use of org.aion.types.InternalTransaction in project aion by aionnetwork.
the class Tx method internalTxsToJSON.
public static JSONObject internalTxsToJSON(List<InternalTransaction> internalTransactions, byte[] txHash, boolean isCreatedWithInternalTransactions) {
if (txHash == null)
return null;
JSONObject json = new JSONObject();
json.put("hash", StringUtils.toJsonHex(txHash));
if (isCreatedWithInternalTransactions) {
JSONArray tx = new JSONArray();
if (internalTransactions == null || internalTransactions.isEmpty()) {
// empty when no internal transactions were created
json.put("internal_transactions", tx);
} else {
for (int i = 0; i < internalTransactions.size(); i++) {
InternalTransaction itx = internalTransactions.get(i);
tx.put(internalTransactionToJSON(itx));
}
// populated with all the stored internal transactions
json.put("internal_transactions", tx);
}
} else {
// null when the internal transactions were not stored by the kernel
json.put("internal_transactions", JSONObject.NULL);
}
return json;
}
Aggregations