More common than not, blockchain based systems and solutions are more than just the deployed smart contracts. There usually is a client application, and sometimes, there are additional backend components, which in some cases, listen to events raised by those deployed contracts.
One of the concepts available today when developing a system’s backend is serverless architecture. This article shows how to create an Azure Function, Microsoft’s serverless implementation, that is triggered when an event happens on an Ethereum based deployed smart contract.
The entire source code for this article, including a test application, is available here:
As the Azure Function custom trigger will be written in C#, we will be needing an suitable editor. I chose to use Visual Studio 2019, which you can find its community edition here.
Now, because we will be needing to interact with a deployed contract, we can use the local docker based Parity deployment I described in this article, including the available wallet:
And compile the contract used in this article:
Once compiled, just use your favorite wallet to deploy the contract (such as MyCrypto).
Implementing a Trigger
To create a custom C# trigger we will need to implement the following:
- An attribute that will be used to decorate the parameter which will be receiving the data from the trigger.
- A listener that will be the actual component that polls the contract for events
- And 3 more interfaces used for configuring and wiring the attribute and the listener.
We will start by writing the attribute. As far as the attribute goes, there is nothing special that needs to be added to. We will just define 4 fields that we will use to gather the information required for connecting to a specific event: the Ethereum client URL (with a default of a local address of http://localhost:8545/), the contract’s ABI, the contract’s address and the event we want to poll:
Next we will write the listener. As we are using C#, we can use Nethereum’s library to interact with Ethereum based blockchains. We will need to create a new instance of
Web3 with the URL of the client we are connecting, get the contract we want to interact with by calling
Eth.GetContract on the
Web3 instance with the contract’s ABI and address and finally, get the event by calling
GetEvent on the
The listener itself needs to be based on the
IListener interface, which requires us to implement the
StopAsync methods. We will use the
StartAsync to do our initial setup of the connection to the contract:
And then the methods that actually do the interaction work:
- execute a loop that polls the contract for changes:
- Process the list of new events:
- Extract the information of each event:
The complete listener should be similar to this:
Configuration & Wiring
Now that we are done with the attribute and the listener, we move on to the interfaces required for configuring and wiring our previous classes:
- An implementation of
ITriggerBindingthat creates an instance of the listener.
- An implementation of
ITriggerBindingProviderthat creates an instance of the implementation of
- And an implementation of
IExtensionConfigProviderwhich we use to configure a rule that wires our attribute with the implementation of
Testing The Trigger
To test our trigger, we will create a new empty Azure Function app project, add one function class (make sure you set the
EventName constants to the values of your deployed environment):
And a startup class that initializes the app with our custom trigger:
Note that an
assembly directive indicating the startup type that needs to be used when activating the function app must be added (preferably in the
Startup.cs file just after the
As this is only an example implementation, it is not “production” grade code. It’s missing things such as contract configuration information validation, extensive logging, failure recovery and more. Additionally, packaging the trigger in a Nuget package makes a lot more sense then adding a project reference.