diff --git a/hedera-mirror-rest-java/src/main/java/com/hedera/mirror/restjava/converter/StringToLongConverter.java b/hedera-mirror-rest-java/src/main/java/com/hedera/mirror/restjava/converter/StringToLongConverter.java index b7a9c994a52..5f28674861c 100644 --- a/hedera-mirror-rest-java/src/main/java/com/hedera/mirror/restjava/converter/StringToLongConverter.java +++ b/hedera-mirror-rest-java/src/main/java/com/hedera/mirror/restjava/converter/StringToLongConverter.java @@ -31,7 +31,6 @@ public Long convert(String source) { return null; } - var parts = source.split("\\."); if (parts.length == 3) { return EntityId.of(source).getId(); diff --git a/hedera-mirror-web3/src/main/java/com/hedera/hapi/node/state/token/Token.java b/hedera-mirror-web3/src/main/java/com/hedera/hapi/node/state/token/Token.java index 9099abb3f7a..63dd0498621 100644 --- a/hedera-mirror-web3/src/main/java/com/hedera/hapi/node/state/token/Token.java +++ b/hedera-mirror-web3/src/main/java/com/hedera/hapi/node/state/token/Token.java @@ -185,7 +185,7 @@ public Token( String name, String symbol, int decimals, - Long totalSupply, + long totalSupply, AccountID treasuryAccountId, Key adminKey, Key kycKey, diff --git a/hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java b/hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java index 6488128b5d1..5d8dc059c10 100644 --- a/hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java +++ b/hedera-mirror-web3/src/main/java/com/hedera/mirror/web3/service/TransactionExecutionService.java @@ -233,6 +233,7 @@ private TransactionBody buildContractCallTransactionBody( .build()) .functionParameters(com.hedera.pbj.runtime.io.buffer.Bytes.wrap( params.getCallData().toArrayUnsafe())) + .amount(params.getValue()) // tinybars sent to contract .gas(estimatedGas) .build()) .build(); diff --git a/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceOpcodeTracerTest.java b/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceOpcodeTracerTest.java index 846368caa75..dff68e529b3 100644 --- a/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceOpcodeTracerTest.java +++ b/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceOpcodeTracerTest.java @@ -25,6 +25,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.mockito.Mockito.doAnswer; +import com.hedera.mirror.common.domain.balance.AccountBalance; import com.hedera.mirror.common.domain.entity.Entity; import com.hedera.mirror.common.domain.entity.EntityId; import com.hedera.mirror.rest.model.OpcodesResponse; @@ -237,4 +238,18 @@ private Address entityAddress(Entity entity) { } return toAddress(entity.toEntityId()); } + + protected void accountBalanceRecordsPersist(Entity sender) { + domainBuilder + .accountBalance() + .customize(ab -> ab.id(new AccountBalance.Id(sender.getCreatedTimestamp(), sender.toEntityId())) + .balance(sender.getBalance())) + .persist(); + + domainBuilder + .accountBalance() + .customize(ab -> ab.id(new AccountBalance.Id(sender.getCreatedTimestamp(), treasuryEntity.toEntityId())) + .balance(treasuryEntity.getBalance())) + .persist(); + } } diff --git a/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceTest.java b/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceTest.java index 489536a4f30..f4aaf68abca 100644 --- a/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceTest.java +++ b/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/AbstractContractCallServiceTest.java @@ -247,7 +247,7 @@ protected Entity accountEntityPersist() { return domainBuilder .entity() .customize(e -> - e.type(EntityType.ACCOUNT).evmAddress(null).alias(null).balance(1_000_000_000_000L)) + e.type(EntityType.ACCOUNT).evmAddress(null).alias(null).balance(100_000_000_000_000_000L)) .persist(); } diff --git a/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/ContractCallServicePrecompileModificationTest.java b/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/ContractCallServicePrecompileModificationTest.java index 4813fac066b..8f6ac520ff5 100644 --- a/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/ContractCallServicePrecompileModificationTest.java +++ b/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/service/ContractCallServicePrecompileModificationTest.java @@ -60,7 +60,6 @@ import com.hedera.services.store.models.Id; import com.hedera.services.utils.EntityIdUtils; import com.hederahashgraph.api.proto.java.Key.KeyCase; -import com.swirlds.base.time.Time; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.time.Instant; @@ -665,26 +664,32 @@ void unpauseToken() throws Exception { @Test void createFungibleToken() throws Exception { // Given - var initialSupply = BigInteger.valueOf(10L); - var decimals = BigInteger.valueOf(10L); - var value = 10000L * 100_000_000L; + final var value = 10000L * 100_000_000_000L; + final var sender = accountEntityPersist(); + + accountBalanceRecordsPersist(sender); final var contract = testWeb3jService.deploy(ModificationPrecompileTestContract::deploy); - final var treasuryAccount = domainBuilder - .entity() - .customize(e -> e.type(EntityType.ACCOUNT).deleted(false).evmAddress(null)) - .persist(); + testWeb3jService.setValue(value); + + testWeb3jService.setSender(toAddress(sender.toEntityId()).toHexString()); + + final var treasuryAccount = accountEntityPersist(); + final var token = populateHederaToken( contract.getContractAddress(), TokenTypeEnum.FUNGIBLE_COMMON, treasuryAccount.toEntityId()); + final var initialTokenSupply = BigInteger.valueOf(10L); + final var decimalPlacesSupportedByToken = BigInteger.valueOf(10L); // e.g. 1.0123456789 // When - testWeb3jService.setValue(value); - final var functionCall = contract.call_createFungibleTokenExternal(token, initialSupply, decimals); + final var functionCall = + contract.call_createFungibleTokenExternal(token, initialTokenSupply, decimalPlacesSupportedByToken); final var result = functionCall.send(); final var contractFunctionProvider = ContractFunctionProviderRecord.builder() .contractAddress(Address.fromHexString(contract.getContractAddress())) + .sender(toAddress(sender.toEntityId())) .value(value) .build(); @@ -702,15 +707,22 @@ void createFungibleTokenWithCustomFees() throws Exception { var decimals = BigInteger.valueOf(10L); var value = 10000L * 100_000_000L; + final var sender = accountEntityPersist(); + + accountBalanceRecordsPersist(sender); + + final var treasuryAccount = accountEntityPersist(); + final var tokenForDenomination = persistFungibleToken(); final var feeCollector = accountEntityWithEvmAddressPersist(); + tokenAccountPersist(tokenForDenomination, feeCollector); + final var contract = testWeb3jService.deploy(ModificationPrecompileTestContract::deploy); - final var treasuryAccount = domainBuilder - .entity() - .customize(e -> e.type(EntityType.ACCOUNT).deleted(false).evmAddress(null)) - .persist(); + testWeb3jService.setSender(toAddress(sender.toEntityId()).toHexString()); + testWeb3jService.setValue(value); + final var token = populateHederaToken( contract.getContractAddress(), TokenTypeEnum.FUNGIBLE_COMMON, treasuryAccount.toEntityId()); @@ -729,13 +741,13 @@ void createFungibleTokenWithCustomFees() throws Exception { getAliasFromEntity(feeCollector)); // When - testWeb3jService.setValue(value); final var functionCall = contract.call_createFungibleTokenWithCustomFeesExternal( token, initialSupply, decimals, List.of(fixedFee), List.of(fractionalFee)); final var result = functionCall.send(); final var contractFunctionProvider = ContractFunctionProviderRecord.builder() .contractAddress(Address.fromHexString(contract.getContractAddress())) + .sender(toAddress(sender.toEntityId())) .value(value) .build(); @@ -750,9 +762,14 @@ void createFungibleTokenWithCustomFees() throws Exception { void createNonFungibleToken() throws Exception { // Given var value = 10000L * 100_000_000L; + final var sender = accountEntityPersist(); + + accountBalanceRecordsPersist(sender); final var contract = testWeb3jService.deploy(ModificationPrecompileTestContract::deploy); + testWeb3jService.setSender(toAddress(sender.toEntityId()).toHexString()); + final var treasuryAccount = domainBuilder .entity() .customize(e -> e.type(EntityType.ACCOUNT).deleted(false).evmAddress(null)) @@ -767,6 +784,7 @@ void createNonFungibleToken() throws Exception { final var contractFunctionProvider = ContractFunctionProviderRecord.builder() .contractAddress(Address.fromHexString(contract.getContractAddress())) + .sender(toAddress(sender.toEntityId())) .value(value) .build(); @@ -781,12 +799,20 @@ void createNonFungibleToken() throws Exception { void createNonFungibleTokenWithCustomFees() throws Exception { // Given var value = 10000L * 100_000_000L; + final var sender = accountEntityPersist(); + + accountBalanceRecordsPersist(sender); final var tokenForDenomination = persistFungibleToken(); final var feeCollector = accountEntityWithEvmAddressPersist(); + tokenAccountPersist(tokenForDenomination, feeCollector); + final var contract = testWeb3jService.deploy(ModificationPrecompileTestContract::deploy); + testWeb3jService.setSender(toAddress(sender.toEntityId()).toHexString()); + testWeb3jService.setValue(value); + final var treasuryAccount = domainBuilder .entity() .customize(e -> e.type(EntityType.ACCOUNT).deleted(false).evmAddress(null)) @@ -816,6 +842,7 @@ void createNonFungibleTokenWithCustomFees() throws Exception { final var contractFunctionProvider = ContractFunctionProviderRecord.builder() .contractAddress(Address.fromHexString(contract.getContractAddress())) + .sender(toAddress(sender.toEntityId())) .value(value) .build(); // Then @@ -1409,7 +1436,9 @@ private void verifyEthCallAndEstimateGas( private HederaToken populateHederaToken( final String contractAddress, final TokenTypeEnum tokenType, final EntityId treasuryAccountId) { - final var autoRenewAccount = accountEntityWithEvmAddressPersist(); + final var autoRenewAccount = + accountEntityWithEvmAddressPersist(); // the account that is going to be charged for token renewal upon + // expiration final var tokenEntity = domainBuilder .entity() .customize(e -> e.type(EntityType.TOKEN).autoRenewAccountId(autoRenewAccount.getId())) @@ -1419,21 +1448,26 @@ private HederaToken populateHederaToken( .customize(t -> t.tokenId(tokenEntity.getId()).type(tokenType).treasuryAccountId(treasuryAccountId)) .persist(); - final var supplyKey = - new KeyValue(Boolean.FALSE, contractAddress, new byte[0], new byte[0], Address.ZERO.toHexString()); + final var supplyKey = new KeyValue( + Boolean.FALSE, + contractAddress, + new byte[0], + new byte[0], + Address.ZERO.toHexString()); // the key needed for token minting or burning final var keys = new ArrayList(); keys.add(new TokenKey(AbstractContractCallServiceTest.KeyType.SUPPLY_KEY.getKeyTypeNumeric(), supplyKey)); + return new HederaToken( token.getName(), token.getSymbol(), - getAddressFromEntityId(treasuryAccountId), - tokenEntity.getMemo(), + getAddressFromEntityId(treasuryAccountId), // id of the account holding the initial token supply + tokenEntity.getMemo(), // token description encoded in UTF-8 format true, BigInteger.valueOf(10_000L), false, keys, new Expiry( - BigInteger.valueOf(Time.getCurrent().currentTimeMillis() + 1_000_000_000), + BigInteger.valueOf(Instant.now().getEpochSecond() + 8_000_000L), getAliasFromEntity(autoRenewAccount), BigInteger.valueOf(8_000_000))); } diff --git a/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/web3j/TestWeb3jService.java b/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/web3j/TestWeb3jService.java index 2ebd200b35f..cb36f109e40 100644 --- a/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/web3j/TestWeb3jService.java +++ b/hedera-mirror-web3/src/test/java/com/hedera/mirror/web3/web3j/TestWeb3jService.java @@ -87,7 +87,7 @@ public class TestWeb3jService implements Web3jService { private boolean isEstimateGas = false; private String transactionResult; private Supplier estimatedGas; - private long value = 0L; + private long value = 0L; // the amount sent to the smart contract, if the contract function is payable. private boolean persistContract = true; private byte[] contractRuntime; private BlockType blockType = BlockType.LATEST;