HomeDeveloper MaterialsEnterprise App Gateway via KafkaConfiguring Event Streams

Configuring Event Streams

Use the Event Streams service within the REST API Gateway to consume and log events emitted from your deployed smart contracts and send them to a target of your choice.  In order to leverage the Kaleido Event Streams Service, your smart contract requires an event interface which is used to specify contract parameters for indexing.  The indexed arguments of an event will be stored on-chain in the transaction’s log when a function with the applied event is invoked, and the event payload can then be consumed by a client side app or streaming service that is subscribed to the contract.  Kaleido simplifies events by allowing you to specify your own custom event destination URL along with an organizational-controlled API bearer token for added security protections.

Creating an AWS Lambda Function

We will use AWS Lambda to build a function and create a target URL, however alternative cloud compute services such as Azure Functions can be leveraged as well.

  • Login to the AWS console and navigate to the Lambda service within the Compute category
  • Click the Create a Function button at the top of the screen
  • Remain on the Author from Scratch tab and supply a name for your function in the Function Name field.  For example, ethConnectSync
  • You can alter the runtime language for your function if you wish.  For this example, we will leave the default configuration of Node.js 10.x
  • Set your permissions by leveraging an existing role within your IAM service or allowing Lambda to create a new role for this function.  For this example, we will let Lambda create a new role and API key
  • Click Create Function to finish.  When complete, you will be redirected to a new page for your newly created function
  • Scroll down to the Function Code section to the see the code for your function.
  • Alter the code and add a console.log statement to print out the returned event.  For example:
exports.handler = async (event) => {
    console.log(JSON.stringify(event.body, null, "  "))
    const response = {
        statusCode: 200,
    };
    return response;
};
  • Click Save in the top right of the screen to persist your new function
  • Next, click the API Gateway tab in the lefthand navigation to set up your target URL
  • In the API dropdown select Create a New API
  • In the Security section select Open with API Key
  • Click ADD to apply the configurations.
  • Click Save in the top right of the screen to build the API Gateway objects
  • You should now see your target URL (API Endpoint) and API Key at the bottom of the screen.  For example:

Configuring an Event Stream on Kaleido 

With your target URL in hand, you can proceed to create an event stream on Kaleido and subscribe smart contract events to it.

  • Navigate to an environment with a running node and access the REST API Gateway
  • This can be done by clicking the Connect option on the node dropdown or by clicking a node and selecting the + CONNECT button in the top right of the node details screen.
  • Choose the REST API Gateway
  • Input existing application credentials or click Regenerate to access the console.
  • Switch to the Event Streams tab in the lefthand navigation of the REST API Gateway console
  • Click ADD NEW STREAM 
  • Input your API Endpoint into the Webhook URL field
  • Add x-api-key to the Header field if you are using an API Key to secure access to your stream
  • Input the API Gateway API Key from your AWS Lambda function to the Value field

  • Click ADD NEW STREAM to create the configuration
  • This will generate your Event Stream Resource ID and a status on Subscriptions.
  • For new event streams there will be no subscriptions by default.  Subscriptions are created when you subscribe an event within your smart contract to an event stream ID

About Events

We will use the SimpleEvent.sol smart contract to expose the event interface and demonstrate a subscription to an event via the Smart Contract API service.  The example solidity code is as follows:

pragma solidity >=0.5.2 <0.6.0;
/**
  * @title Simple Storage with events
  * @dev Read and write values to the chain
  */
contract SimpleEvents {
  int64 public storedI;
  string public storedS;

  event Changed (
    address indexed from,
    int64 indexed i,
    string indexed s,
    bytes32 h,
    string m
  );

  /**
    * @dev Constructor sets the default value
    * @param i The initial value integer
    * @param s The initial value string
    */
  constructor(int64 i, string memory s) public {
    set(i,s);
  }

  /**
    * @dev Set the value
    * @param i The new value integer
    * @param s The new value string
    */
  function set(int64 i, string memory s) public {
    storedI = i;
    storedS = s;
    emit Changed(msg.sender, i, s, keccak256(bytes(s)), s);
  }

  /**
    * @dev Get the value
    */
  function get() public view returns (int64 i, string memory s) {
    return (storedI, storedS);
  }

}

The contract itself should be fairly straightforward.  There are two public global variables – storedI as type int64 and storedS as type string.  The constructor takes an argument for each of the these variables upon deployment and they can be subsequently changed by invoking the set function in the smart contract.

More interestingly is the usage of the event interface defined in this contract as Changed.  We see that the Changed event offers an indexed attribute which has been applied to the message sender, string argument and integer argument.  “Indexing” parameters allows for them to be searched for.  The Changed event also logs a keccak256 hash of the string and the argument for the string in memory; these are defined as “h” and “m” in the event payload.

The Changed event is emitted every time the set function is invoked, therefore an app or streaming service simply needs to subscribe to the event in order to consume state changes to this contract.  The Kaleido Smart Contract API Service will expose a subscribe endpoint to which you can pass your event streams service ID.  Save this sample contract locally on your machine or develop your own solidity code with the event interface implemented.

Deploy the Smart Contract & Subscribe to the Event

The final step is to instantiate the smart contract and “subscribe” to the defined event within the contract.

  • Switch to the Smart Contracts tab within the REST API Gateway console
  • Upload the sample SimpleEvent.sol contract or your own custom contract
  • Expand the contract dropdown and click View to access the swagger interface

  • Expand the first POST method
  • Supply arguments for the integer and string to be passed to the constructor on deployment.  For example, “12345” and “hello world”
  • Click Try to deploy the contract

  • When the block is mined the transaction receipt will be returned in the response
  • Close the Swagger interface and return to your Smart Contracts console in the REST Gateway
  • Click Refresh next to your smart contract and you should see the Deployments change from 0 to 1
  • You should also see the smart contract address displayed

 

  • Click the View button next to the smart contract address to open the Swagger interface for the deployed contract
  • Expand the CHANGED class to call the subscribe API
  • Input your Event Streams ID as an argument to this call
  • The ID can be retrieved by switching to the Event Streams tab in the REST Gateway console and expanding the dropdown

  • Copy the ID and paste it as an argument to the “stream” parameter in the body of the call
  • The payload should look similar to the following

  • Click TRY to create the subscription
  • Note that this is not an on-chain transaction and will return a response immediately

Trigger the Event and Check Logs

In the sample smart contract code we see that the Changed event will be emitted every time the set function is invoked:

function set(int64 i, string memory s) public {
    storedI = i;
    storedS = s;
    emit Changed(msg.sender, i, s, keccak256(bytes(s)), s);
  }
  • In the Swagger interface for your smart contract expand the SET method and update the state variables
  • For example, “6789” & “my first event stream”
  • Click TRY to send the transaction

  • Now return to your Lambda Function in AWS
  • Click the Monitoring tab at the top left of the screen
  • Click the View Logs in CloudWatch button
  • You should see the most recent transaction updating the integer and string logged with a timestamp
  • Click the log and expand the line with the INFO parameter.  This will show the event payload defined in your smart contract.  For example: