My pattern for async transactions of smart contracts written in Ethereum’s Solidity

CaptainJS
Coinmonks
4 min readJan 4, 2019

--

Many developers who implemented Java, Go, Python… before developing Solidity feel like travelling back to the late 80’s with a DeLorean. Solidity is solid but very limited. Oracles grew up and stayed forever. Thus, asynchronous Solidity contracts are real. Here’s my pattern…

I’m using the captain’s NodeJS oracle called #ScriptIt for the following use case:

  • A new user gets 256 points
  • With every new call the user’s points will be reduced by log2
the captain will run your NodeJS calls directly from Solidity in a Docker container and return the result back to your contract

The Smart Contract

The asynchronous contact will derive from usingCaptainJS which includes asynchronous call and callback functionality.

To remember asynchronous calls whenever a callback happens you need a a JobCounter and a mapping of job IDs and the sender’s address:

The Events

In Ethereum a synchronous transactions are pending, then failed or success(ful). An asynchonous transaction will require Events to be emitted which inform a user if a transaction was pending, successful or if it failed.

Therefore you define three these events and every event should at least contain the sender’s address:

The Function

Ethereum’s default pattern is that every user calls a contract function and pays for the gas that is required to execute the code within one synchronous transaction context.

But now we have an asynchronous transaction context. And this means that additional gas will be required after the synchronous function call terminated.

Therefore your function must be payable and your first check must be to verify that the user transferred enough additional gas:

In this demo use case we will require the default gas units defined in usingCaptainJS multiplied by the current transaction gas price plus a transaction fee of 70 Szabo (which the captain needs to pay his container ship which executes your mathjs call).

Once it is clear that the user has transferred enough gas you can invoke the log2 function of mathjs according to the captain’s description at GitHub:

After the invocation of Run(...) you must emit the pending event. If the invocation of Run(...) fails the synchronous call will fail.

The Callbacks

Once the captain calculated the log2 value of the user’s points he’s going to send the result back to your contract by calling the CaptainsResult function. Make sure that only the captain is invoking this function by adding onlyCaptainsOrdersAllowed.

Make sure to emit the success event at the end of the function.

If the captain is not able to invoke the code you submitted (maybe you have a typo in your JavaScript code), he’s going to inform you by invoking the CaptainsError function of your contract.

Make sure to emit the failed event at the end of the function.

That’s it.

Here’s the complete code:

Get Best Software Deals Directly In Your Inbox

--

--