Start a conversation

Blockchain development the easy way

Posted by Henk van Ramshorst on July 31 2019

Introduction

In this tutorial we will demonstrate how you can use The Blockchain Gateway to interact with Ethereum. After finishing this tutorial you know how to:

  • create accounts
  • call smart contract functions
  • create transactions
  • deploy your own contracts

Good luck!

Create an account

Before we can start using the Blockchain Gateway, you need to create an Unchain.io account. You can register on https://connect.unchain.io/#/sign-up, the free tier offers sufficient features to follow this tutorial.

Create your first pipeline

We can use The Blockchain Gateway to easily integrate any application with any blockchain network. This is achieved by composing pipelines from existing components, that connect applications and blockchain networks. In this tutorial we will build a REST API that connects to an Ethereum network.

Our pipeline will have an http-trigger component to serve the API, and an Ethereum-action component to interact with an Ethereum network. Follow the steps below to create your first pipeline:

  1. log into your Unchain account
  2. on the pipelines page click create new
  3. give your pipeline a name and description and click create

We have a pipeline now, so we can proceed with adding components. There are two types of components: trigger components and action components. Each pipeline has one trigger, and can have any number of actions. Let's add the http-trigger and an Ethereum-action to our pipeline:

  1. click add trigger to display available trigger components
  2. in the http-trigger block click details
  3. on the right select the latest version of the component and click add
  4. now click add action to display available action components
  5. in the ethereum-action block click details
  6. on the right select the latest version of the component and click add

The execution of a pipeline is always started by the trigger. From there, messages will flow through the pipeline, invoking all action components in sequential order.

Each action component performs a certain task. Examples are data conversions, requests to external API's, and creating transactions on a blockchain. The result of a task is outputted by the component, and made available to other components in the pipeline.   This allows for adding complex business logic to a pipeline by reusing existing components.

Configuration of components

We have a pipeline with a trigger and an action, but we're not there yet. For our pipeline to function properly, we need to configure the components. We will start by configuring the http-trigger, because that one is easy. The ethereum-action will require some more effort, as we will see later on.

There are three types of configurations

  • initialisation configuration
  • input configuration
  • response configuration

The initialisation configuration, as it's name suggests, is only used for initialisation of a component. Examples are specifying access tokens, and providing the address of a blockchain node. Both a trigger and action component have an initialisation configuration. An action component also has an input configuration, which is used for each message that flows through the pipeline. It specifies the input of the action component, which is composed from outputs of other components. And a trigger component has a response configuration, which is used to specify the response of the pipeline.

The initialisation configuration of an http-trigger has the following fields:

  1. apiKeys

The http-trigger uses Bearer authentication, for more information see: https://swagger.io/docs/specification/authentication/bearer-authentication/

The bearer tokens can be specified as follows:

apiKeys = ["mySecretKey", "someOtherKey"]

If you don't configure any tokens, the API will be public. This API will be used to create Ethereum transactions using your wallets, so you probably want to restrict access to the API!

You can leave the response configuration empty for now, we will get back to that part later on. Click on save as draft to save the configuration.

Before we can proceed with the configuration of the Ethereum-action component, we have to arrange a couple of things first.

Ethereum network and node

We want to interact with an Ethereum network, so we need to have access to an Ethereum node. In this tutorial we will use the Rinkeby network, which is one of the test networks for Ethereum. But you can use any other Ethereum network, both public and private.

To interact with Rinkeby, we can use the nodes from Infura. Register on the following website to get access to Rinkeby and other public Ethereum networks:

https://infura.io/

After registration you will receive an email with access URL's. Now go to the configuration of the Ethereum-action, and add the URL of the Rinkeby node to the initialisation configuration as follows:

[ethereum]
host = "https://rinkeby.infura.io/YOUR_ACCESS_TOKEN"

Don't forget to save the configuration by clicking on save as draft.

Creating an account

If you want to create transactions on an Ethereum blockchain, you need an account. An account consists of an address, and a private key. The account address identifies you on the Ethereum network, just like an IBAN does for a banking account [TP4] . The private key is required to create transactions for that account. Anyone who holds the private key of an account, controls that account. So it's important to keep your private keys secret!

We can generate an Ethereum address and private key using the following website:

https://vanity-eth.tk/

This is not the most safe way to create an account. Since we use the Rinkeby testnet for this tutorial, we don't mind. But for other purposes, a safer way for generating accounts may be required.

We can now add the account to the init configuration of the ethereum-action as follows:

[[accounts]]
    address = "0xfdfa8d41f986c80904bf4825402e788f3121e7af"
    privateKey = "0x5b3a720780cdf4288877eff96b5e4be01f5bddf4fb77f304e12f5a00f17220cc"

As you can see accounts is between double square brackets, which means that accounts is a list. You can configure as many accounts as you want, [TP5] by repeating the above like this:

[[accounts]]
address = "0xfdfa8d41f986c80904bf4825402e788f3121e7af"
privateKey = "0x5b3a720780cdf4288877eff96b5e4be01f5bddf4fb77f304e12f5a00f17220cc"

[[accounts]]
address = "0x69091d42c8307d9a24a47b2d92d4506604ae44b9"
privateKey = "0x95206d4239e755291d12b7bbc778b388fb765317cd115f8a72e27827629edc72"

The language we use to configure the components is TOML. See https://github.com/toml-lang/toml for more information about the TOML language.

Don't forget to click save as draft before you continue! [TP7]

Get some Ether

Your account needs to hold some Ether, the native currency on the Ethereum network, before you can create transactions. Ether is used as gas on the network. Each time you create a transaction, a small fee is paid to the miners.

Since Rinkeby is a test network, we can get some Ether for free. Follow these instructions for receiving some Ether on the account we've created during the previous step: https://faucet.rinkeby.io.

You can check if you received the Ether successfully by using a block explorer: https://rinkeby.etherscan.io. Just enter the address of your account and you can see the balance.

Configuring a contract

Our goal is to interact with Ethereum smart contracts by sending JSON messages to an API. In order to do that, we have to configure the smart contracts we want to interact with. We will start with the configuration of an existing smart contract, which has the following source code:

pragma solidity ^0.5.9;
contract SimpleStorage {
    uint storedData;
    function set(uint x) public {
        storedData = x;
    }
    function get() public view returns (uint) {
        return storedData;
    }
}

The contract has two functions: A set() function that takes a string as an input, and doesn't return anything. And a get() function that has no input, and returns the string (set by the set() function).

Now add the following to the initialisation configuration of your Ethereum component:

[[contracts]]
    address = "0xb3622a6ad922f8f82690f31a8da358fc55100bc4"
    abi = '[{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]'

As you can see the contract is defined by it's address on the Ethereum network, and something called an Application Binary Interface (ABI). The ABI is a specification of all the functions of the smart contract.

If you study the ABI, you can see how it exactly defines the names, inputs and returns of all the functions of the contract. Also note the constant attribute which is true for the set() function, and false for the get() function. It means that the set() function results in a transaction on the Ethereum blockchain. This also implies that you need to sign it with your private key, and you have to pay some gas for committing the transaction to the ledger. The get() function is a contract call, it is not required to be signed with a private key, and you don't have to pay for it.

Make sure to click on save as draft before continuing. 

Input configuration

To complete the configuration for the Ethereum-action component, we need to specify the input configuration. The inputs are the fields that are required by an action component to perform a task. When you want to call a function on a contract for example, you need to provide which account to use, and which function of a contract you want to call.

The values for these fields can come from anywhere. They can be constants, environment variables, or they can be taken from the output of other components. In our case, the user provides the values by sending a request to the API, which is served by the http-trigger component. So we need to feed the output values from the http-trigger back into the ethereum-action component. We can achieve this by taking the input configuration from below:


Key
Value
constructorParams
$.http-trigger.body.constructorParams
from
$.http-trigger.body.from  
function
$.http-trigger.body.function
params
$.http-trigger.body.params
solidity
$.http-trigger.body.solidity
to
$.http-trigger.body.to
type
$.http-trigger.body.type


Click on save as draft before continuing.

Response configuration

We still have to complete the configuration of the http-trigger component, by adding the response configuration. This configuration specifies what to return to the user. So what do we want to return? Well obviously, when we call a smart contract function, we want to send the results of that back to the user. So what we need to do, is take the output from the Ethereum-action and feed it back into the http-trigger, which is quite similar to what we did when we configured the input of the Ethereum-action.

Add the response configuration below to the http-trigger component:

Key
Value
contractCallOutput
$.ethereum-action.contractCallOutput
contractTransactionOutput
$.ethereum-action.contractTransactionOutput
deployContractOutput
$.ethereum-action.deployContractOutput

As you can see, the Ethereum-action component can produce different outputs, depending on the what input you provide. We just specify all of them, and put them in the response. Only keys that actually contain a value will be send back to the user.

Click on save as draft before continuing.

Deploying our pipeline

Now it's finally time to deploy our pipeline! First we need to release a new version of the pipeline. You can do this on the configuration page by clicking on save as new version. This will take us to the environments page.

You will find a development and production environment. We are on the development tab now, which is good since we want to deploy there first. You can select version 1 from the dropdown and click deploy to deploy the pipeline. This will build a docker image from your pipeline and deploy on a Kubernetes cluster. The deployment process should take less than a minute, it will take a bit longer before the logs are picked up.

You can test your pipeline by opening the URL under Runtime Management in your browser. It should display "http api is up".

Calling a contract function

Finally it's time to call a smart contract function!  In this tutorial we will use curl to make http requests. We will start by calling the get() function of the contract that we configured. Open your terminal and execute the following command:

curl -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" -X POST -d '{"type": "callContractFunction", "function": "get"}' YOUR_PIPELINE_URL

If everything goes well you should get a response like this, where the value for contractCallOutput can be different of course:

{"contractCallOutput": 20}

So what happened exactly? Well we gave an instruction of the type callContractFunction, which means that we want to call a function of our smart contract. There is also a deployContract type, which we will explore in the next section. Furthermore, we instructed to call the get() function. The response we received, is contractCallOutput which we specified in the Response  configuration section.

We did not specify which account to use, nor what contract to interact with. This works because we have only have one account, and one contract. If you have more than one account, you can set the from field to specify which account to use, where from refers to the account address. If you have more than one contract, you can set the to field that refers to the contract address.

As we explained in the section Configuring a contract, there is a difference between contract calls and transactions. The above example was a contract call. Now we are going to create a transaction on Ethereum, which will change the state of a contract. Execute the following command to call the set() function:

curl -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" -X POST -d '{"type": "callContractFunction", "function": "set", "params": {"x": 100}}' YOUR_PIPELINE_URL

The response is a transaction receipt that looks like this:

{ 
   "contractTransactionOutput":{ 
      "nonce":"0x1f",
      "gasPrice":"0x3b9aca00",
      "gas":"0x6807",
      "to":"0xb3622a6ad922f8f82690f31a8da358fc55100bc4",
      "value":"0x0",
      "input": "0x60fe47b10000000000000000000000000000000000000000000000000000000000000064",
      "v":"0x1b",
      "r":"0x1d149bda879fd7d33f2922dd8dddabe5b45e3909d5ba17e3c7ffc7c31f7bae93",
      "s":"0x6448c6f7af6179b0218155f3f57aaeaea6bdd2b24d863567f18c8601b739ecef",
      "hash":"0xd92ee46b7c0529a3cd512c12057ca0edd35847a68a32b3b9ad1428e54d85577a"
   }
}

You can use the block explorer to look up your transaction by searching on the transaction hash: https://rinkeby.etherscan.io.

To check the result of the transaction, you can call the get() function again. Keep in mind that it can take a while before blockchain transactions are committed to the ledger.

Deploying a contract

Since we actually want to build something on Ethereum, we are going to deploy our own contract. You can use the contract below to deploy your own ERC20 token on Ethereum!

pragma solidity ^0.5.9;
contract ERC20Token {
    string  public name;
    string  public symbol;
    uint256 public totalSupply;
    event Transfer(
        address indexed _from,
        address indexed _to,
        uint256 _value
    );
    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _value
    );
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    constructor(string memory _name, string memory _symbol, uint256 _initialSupply) public {
        name = _name;
        symbol = _symbol;
        balanceOf[msg.sender] = _initialSupply;
        totalSupply = _initialSupply;
    }
    function transfer(address _to, uint256 _value) public returns (bool success) {
        require(balanceOf[msg.sender] >= _value, "insufficient balance");
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        emit Transfer(msg.sender, _to, _value);
        return true;
    }
    function approve(address _spender, uint256 _value) public returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
        require(_value <= balanceOf[_from], "insufficient balance");
        require(_value <= allowance[_from][msg.sender], "transfer not allowed");
        balanceOf[_from] -= _value;
        balanceOf[_to] += _value;
        allowance[_from][msg.sender] -= _value;
        emit Transfer(_from, _to, _value);
        return true;
    }
}

We need to provide the following fields to the API in order to deploy the contract:

  • type
  • constructorParams
  • solidity

The type is easy, you can just use deployContract. The constructor parameters are a bit difficult. For each contract (identified by name) we have to specify a map of constructor parameters. In our case we have only one contract, which is called ERC20Token. From the contract code we can see that we need to provide _name, _symbol, and _initialSupply. The JSON for the constructorParams looks as follows:

{
        "constructorParams": {
            "ERC20Token": {
                "_name": "Unchains token",
                "_symbol": "UNCHAIN",
                "_initialSupply": 100000
            }
        }
}

Of course you can use your own name, symbol and supply for the new Ethereum token!

Providing the solidity code is also a bit difficult, because JSON does not allow to use multi-line strings. Fortunately, we can use our terminal to remove all the newlines and tabs from the source code, and we also have to escape double quotes:

echo 'SOLIDITY_CODE' | tr -s " " | tr -d "\n" | sed 's/"/\\"/g'

Don't forget the surrounding single quotes!

You should be able to construct the full curl command yourself, of course you can look at the examples from the previous section. Or you can use the curl request from below and replace the constructor parameters with your own:

curl -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" -X POST -d '{"type": "deployContract", "constructorParams": {"ERC20Token": {"_name": "Unchains token","_symbol": "UNCHAIN","_initialSupply": 100000}}, "solidity": "pragma solidity ^0.5.9;contract ERC20Token { string public name; string public symbol; uint256 public totalSupply; event Transfer( address indexed _from, address indexed _to, uint256 _value ); event Approval( address indexed _owner, address indexed _spender, uint256 _value ); mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; constructor(string memory _name, string memory _symbol, uint256 _initialSupply) public { name = _name; symbol = _symbol; balanceOf[msg.sender] = _initialSupply; totalSupply = _initialSupply; } function transfer(address _to, uint256 _value) public returns (bool success) { require(balanceOf[msg.sender] >= _value, \"insufficient balance\"); balanceOf[msg.sender] -= _value; balanceOf[_to] += _value; emit Transfer(msg.sender, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(_value <= balanceOf[_from], \"insufficient balance\"); require(_value <= allowance[_from][msg.sender], \"transfer not allowed\"); balanceOf[_from] -= _value; balanceOf[_to] += _value; allowance[_from][msg.sender] -= _value; emit Transfer(_from, _to, _value); return true; }}"}' YOUR_PIPELINE_URL

The result should be something like this:

{ 
   "deployContractOutput":{ 
      "0x8735589aadb773874d5d717096bc73b5faf913d7":{ 
         "Address":"0x8735589aadb773874d5d717096bc73b5faf913d7",
         "Tx":{ 
            "nonce":"0x22",
            "gasPrice":"0x3b9aca00",
            "gas":"0x8c2ad",
            "to":null,
            "value":"0x0",
            "input": "0x608060405234801561001057600080fd5b506040516107bc3803806107bc8339818101604052606081101561003357600080fd5b81019080805164010000000081111561004b57600080fd5b8201602081018481111561005e57600080fd5b815164010000000081118282018710171561007857600080fd5b5050929190602001805164010000000081111561009457600080fd5b820160208101848111156100a757600080fd5b81516401000000008111828201871017156100c157600080fd5b5050602091820151855191945092506100e09160009190860190610112565b5081516100f4906001906020850190610112565b50336000908152600360205260409020819055600255506101ad9050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061015357805160ff1916838001178555610180565b82800160010185558215610180579182015b82811115610180578251825591602001919060010190610165565b5061018c929150610190565b5090565b6101aa91905b8082111561018c5760008155600101610196565b90565b610600806101bc6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806370a082311161005b57806370a082311461019a57806395d89b41146101c0578063a9059cbb146101c8578063dd62ed3e146101f457610088565b806306fdde031461008d578063095ea7b31461010a57806318160ddd1461014a57806323b872dd14610164575b600080fd5b610095610222565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100cf5781810151838201526020016100b7565b50505050905090810190601f1680156100fc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101366004803603604081101561012057600080fd5b506001600160a01b0381351690602001356102b0565b604080519115158252519081900360200190f35b610152610316565b60408051918252519081900360200190f35b6101366004803603606081101561017a57600080fd5b506001600160a01b0381358116916020810135909116906040013561031c565b610152600480360360208110156101b057600080fd5b50356001600160a01b0316610479565b61009561048b565b610136600480360360408110156101de57600080fd5b506001600160a01b0381351690602001356104e5565b6101526004803603604081101561020a57600080fd5b506001600160a01b03813581169160200135166105ae565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156102a85780601f1061027d576101008083540402835291602001916102a8565b820191906000526020600020905b81548152906001019060200180831161028b57829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60025481565b6001600160a01b038316600090815260036020526040812054821115610380576040805162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b604482015290519081900360640190fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020548211156103ef576040805162461bcd60e51b81526020600482015260146024820152731d1c985b9cd9995c881b9bdd08185b1b1bddd95960621b604482015290519081900360640190fd5b6001600160a01b0380851660008181526003602090815260408083208054889003905593871680835284832080548801905583835260048252848320338452825291849020805487900390558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156102a85780601f1061027d576101008083540402835291602001916102a8565b33600090815260036020526040812054821115610540576040805162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b604482015290519081900360640190fd5b336000818152600360209081526040808320805487900390556001600160a01b03871680845292819020805487019055805186815290519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a350600192915050565b60046020908152600092835260408084209091529082529020548156fea265627a7a72305820d38c0fa38603d4f8edf3dd9d1a82d11d6bd70b62654c65c0af00d483d350649064736f6c63430005090032000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000e556e636861696e7320746f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007554e434841494e00000000000000000000000000000000000000000000000000",
            "v":"0x1b",
            "r":"0xdce44204f574a4bffb634f3cbaef521879c158efffb66df2e621bb849bb5df5d",
            "s":"0xe42ae2bdf5500f9081a2ac504ef4d57cb424e1a2054f4a3bf82498ea47b2188",
            "hash":"0x02cb2ecfaab36deefd986be5c47694b3242a044217491584171783c38df5745c"
         },
         "ABI":"[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_name\",\"type\":\"string\"},{\"name\":\"_symbol\",\"type\":\"string\"},{\"name\":\"_initialSupply\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}]"
      }
   }
}

Yes, that's quite a lot indeed!

The first key in the deployContractOutput is 0x8735589aadb773874d5d717096bc73b5faf913d7, which is the address of the contract we just deployed. One level deeper you'll find many other properties of the contract. Recall that you are allowed to deploy multiple contracts at, each of them will be identified by their address.

First we want to check if the contract was actually deployed to the Ethereum network, using the block explorer: https://rinkeby.etherscan.io. There are two ways to do this, either by searching on:

  • the contract address
  • the transaction hash

Please, try both approached to verify that your contract has been deployed on Ethereum.

Besides the address, we are also interested in the ABI, since we need both to configure the contract. Before we can add the ABI to our configuration, we need to get rid of the escape characters. You can use your terminal for this:

echo 'YOUR_ABI' | sed 's@\\@@g'

Now add your newly deployed contract to the configuration of the ethereum-action component. Put the ABI between single quotes, otherwise it will clash with the double quotes in the ABI specification. Now click save as new version, select the new version, and click deploy.

Try to interact with your contract, for instance by calling the name function. Make sure to add the to field to your request. You have two contracts configured by now, so you have to specify which contract you want to call. To make it really exciting, you can create a second account and transfer your token to that account. You can configure both accounts, so you can use The Blockchain Gateway to send your token back and forth. You can inspect the ABI to find out which parameters you have to provide for each contract function.

Good luck!

Choose files or drag and drop files
Was this article helpful?
Yes
No
  1. Support Engineer

  2. Posted
  3. Updated

Comments