Creation of ContractTx (Java-SDK)

so now we can create a valid CreateContractTx but for some reason the transaction doesn’t get mined. what could be the reason for that, any suggestions?

the tx-hash looks like that:


@noandrea @hanssv do you have any ideas?

also two other questions:

  • how are or should the parameters gas and gasPrice be estimated and defined?
  • do or should they have any influence on the fee that is used?


  • also I faced this strange signature_check_failed error when I set TTL to zero. I always thought the tx will not expire when setting the TTL to zero. when providing a “valid” value for TTL the transaction gets accepted by the node without this signature_check_failed

Firstly, gasPrice is the price you pay for each gas. There is no estimate involved. The protocol defines 1M (1000000) to be the minimum gasPrice. Also the miners can demand a (higher!) minimum gasPrice, the default is 1G (1000000000).

The gas can be estimated by dry-running the call (or by program analysis or some other mechanism), this is the maximum amount of gas you are willing to pay. It should be enough to cover the execution (unless you want it to fail with an out of gas :slight_smile: )

Yes, a TTL value 0 means a transaction that is valid “forever”. It should not be a problem to use this in a transaction AFAIK. Perhaps there is an issue with the RLP encoding of 0? I have a vague memory of someone having issues with different encodings of 0 in some RLP-implementation… :thinking:

and this is totally independent from the “regular” fee of the transaction, right? or must that somehow be included in the fee calculation?

this is a good point. I will contact the developer of the library we are using for RLP encoding :smiley:

Yes, the fee is completely independent - the fee covers the base cost of the transaction (size of Tx, and startup cost for VM, etc) and the gas ( x gasPrice) covers the execution…

1 Like

hey folks, I am the maintainer of the lib you’re using for RLP encoding/decoding.
The tx signing of RLP bytes is well tested under the transaction tests of Ethereum, we use those to test the behaviors. Some of those tests are enforcing interesting behaviors such as representing zero with additional zero bytes.
To make sure we validate those transactions, we use a strict mode in our RLP reader which will report issues in superfluous zero bytes are reported.
We don’t use bigInteger to represent balance or gas prices in our transaction code. We use UInt256 so we can have safety.

The problem seems to arise specifically in the way we serialize one vs the other:
For a UInt256, we serialize with writeValue(value.toMinimalBytes());

For a BigInteger, we serialize with writeByteArray(byteArray);

So it looks like you may get additional zero bytes in there.

Hopefully this gives you a few ways to work around the issue. If you have time for a patch, the code is now at



thank you very much for your response!

@hanssv we have definitely an issue with the RLP encoding regarding BigInteger.ZERO which leads to the signature_check_failed error. but this only occurs when we have included a value with BigInteger.ZERO. when we fill the params with >0 the node seems to accept our transaction (as already mentioned above).

still there seems to be another issue (IMO). our nodes do not mine the ContractCreateTx. after submitting the transactions to the network and calling http://localhost/v2/transactions/th_q1YMnUXNMx9GmvQb1pWXXUtyDNpCMBAFaRS8duU8FRCkQ6MLT to see it I get the following response:


do you see any reason why this transaction doesn’t get mined on our local nodes???

the tx looks as follows and is (according to goggles) valid:


No, I don’t see anything that is obviously wrong, but it all depends on the local node you are talking to, it could be that the nonce is wrong, or that this local network is not yet at fortuna height, etc. Regardless it should be visible in the logs (why the transaction can’t be applied), you need debug loglevel for this.

  level: debug

in your .yaml configuration.

1 Like

We finally got it working and are currently working on dryRun for ContractCallTx in our java-sdk and still don’t understand how to use it or if we are doing something wrong.

We create a ContractCallTx and then call the debug endpoint, correct?

  • what do we have to specify as gas and gasPrice?
  • what data of the response do we need to use?

As we analyzed it for now, we need to take the gas from the answer and multiple it with 1,3333. I guess this isn’t the way to go?!

And what must be specified for the “top”-param if we want to execute the dryRun at a certain block height? The encoded hash from the keyblock or something else?

And just for the record:

  • do the official aeternity nodes have debug-mode enabled so that the dryRun can be performed there?
  • if not -> is there an alternative how to calculate gas and gasPrice correctly?

we need info here to finish the contract-feature in our SDK. can anyone of the team help out? :slight_smile:

The dry-run endpoint takes a list of transactions to be performed in sequence on top of top (top is optional and if left out it will default to current top of chain). top can be either a key-block hash or a micro-block hash - the hash should be properly encoded (kh_... or mh_...)

The gasPrice is not very interesting for a dry-run (but for the sake of simplicity the dry-run endpoint takes full transactions including this parameter). It must be larger than minimum gasPrice under consensus (1M) or else the transaction is invalid and won’t be accepted even by for dry-run :slight_smile:

As for the response, you don’t need to use it at all, so it is a strange question. But in general there are two interesting bits of information in the resulting call object - the result of the call (i.e. the result of calling the function in the contract), and the gas used by the call. There is no need to multiply anything, the gas used is the gas used.

Lastly, I am not familiar with how the aeternity nodes are setup, sorry.

1 Like

ok thank you for the detailed explanation :slight_smile: I think now we got everything to finish the feature.

@hanssv unfortunately we have 1 last topic here. it is still regarding the gas that is being used for the ContractCallTx.

we perform a dryRun against the debug api and get as answer the returnType ok the response object includes the values:

  • gasUsed = 192
  • gasPrice = 1000000000

we take exactly these values and create our “real” transaction. when we try to publish it we always encounter an error and the transaction is rejected.

if we increase the gas we are able to create a valid ContractCallTx. as you mentioned above we should be able to use exactly these values that are being returned from the dryRun.

any idea why this is not working?

The gas used “dry-running” the transaction should be the same as the gas used for the real transaction. (Unless there is something in the contract that depends on the chain, and there is a change between the dry-run and the actual execution.)

Why is the transaction rejected, what is the error message?

Hi @hanssv,
if we use exactly the “gas used” value of the dry run (192) the locale node logs the following error
“[error] CRASH REPORT Process <0.25103.7> with 0 neighbours crashed with reason: {illegal_field,gas,int,<<0,192>>,int,<<0,192>>} in aeserialization:decode_fields/2 line 91”

I’m wondering why “illegal_field” occurs… any ideas?

Thanks and greets,

Looks like you’ve got a broken serialization… It looks like there is an extra 0-byte in your serialized transaction, it says <<0, 192>> where it should say <<192>> if I remember correctly.

1 Like

Thanks for the hint, after changing the serialization from writing a byte array to writing a BigInteger the transaction is properly executed - thanks :slight_smile:

@hanssv finally we got it all working and wrote an integrationTest for our own contract using the java sdk.

I have one (hopefull last :rofl:) question regarding that topic:

  • is there a way to determine required gas for the init function in a ContractCreateTx? when performing a dryRun with the transaction I don’t receive the gas and gasPrice parameters. I only receive the parameters result and type:
    "results": [
            "result": "ok",
            "type": "contract_create"

Hmm, that looks like an oversight… And indeed when I look into the code it looks like we have considered it:

        contract_create_tx ->
            %% TODO: Maybe return the state?

So, at the moment there is no way (or well, you could always run the init-function in a contract-call in dry-run - it would not be 100% accurate but pretty close); but we should fix it. It is summer/vacation times so I won’t commit to a schedule.

1 Like