AWS Database Blog

Deploy smart contracts to your private Ethereum blockchain network on AWS

The team that supports the GUI wallet referenced in this blog have decided to sunset their “Ethereum Wallet” application. In the process they have introduced a breaking change that prevents successful implementation of the steps outlined below.

You can use blockchain for use cases where multiple parties need to transact and share data in a decentralized manner without a centralized, trusted authority. In this blog post, we discuss using blockchain to deploy smart contracts.

Blockchain networks can be public, where anyone can join, or permissioned, where the network is limited to a known set of participants. An example of a public network is the public Ethereum network. In this network, anyone can transact, view the history of transactions, or create and join a peer node to the network to help maintain it.

An example of a permissioned network is a known consortium of banks and export houses looking to perform cross-boundary transfer of assets (for example, letters of credit) with each other. This example network works without a centralized authority acting as a liaison. For more information about blockchain, see the Blockchain on AWS webpage.

Blockchain technologies consist of three main components: an immutable ledger database, a consensus mechanism, and a smart-contract execution environment. Every member in a blockchain network owns a copy of the ledger database, allowing the transaction history to be independently verifiable. The ledger database contains two components: a journal that holds the cryptographically immutable history of all transactions and the world state that shows the current state of the data derived from these transactions.

The “blockchain” refers to the data structure of the journal. This data structure batches transactions into “blocks” and creates a “chain” of these blocks. It does so by storing the cryptographic hash of the previous block in each new block. This approach gives the ledger an immutable property.

Smart contracts are self-executing applications in a blockchain network. One major use case for these is exchanging money, property, shares, or anything of value in a transparent, conflict-free way while avoiding the services of a central authority. For example, if a contract says that ownership of an item transfers to whoever pays for it, you simply send the asking price to that contract. The ledger then automatically updates by using a transaction in the next block to reflect you as the new owner.

You might also use a smart contract to program conditions for financial instruments such as mortgages, bonds, and securities. Or you might facilitate tracking, payment of goods through a supply chain. You can use a smart contract with anything that requires a contract.

In November, AWS launched a new service, Amazon Managed Blockchain, to make it easy to create and manage scalable blockchain networks using the open-source frameworks Ethereum and Hyperledger Fabric. The service is in preview, and currently has support for Hyperledger Fabric and Ethereum is coming soon. For more information about Amazon Managed Blockchain, see the Amazon Managed Blockchain product page.

In this blog post, we explore how to build and deploy a smart contract for Ethereum. In advance of Ethereum support in the Amazon Managed Blockchain preview, we use the AWS Blockchain Templates to create a private Ethereum network. Private Ethereum networks are useful for testing smart contracts before deploying them to a public Ethereum network, or for building a network with a set of known members. In a future post, we plan to show how to run this example on an Ethereum network in Amazon Managed Blockchain.

In this blog post, we demonstrate how to install and configure the Ethereum Wallet GUI to interact with your private Ethereum network so you can deploy and test smart contracts. To do so, you deploy a new node on a Microsoft Windows Bastion Host, then connect and synchronize this node to the private Ethereum blockchain network hosted on Amazon ECS. Think of it like adding a new member to your consortium so multiple actors or companies can read from and write to the same distributed ledger.

The following diagram shows AWS Blockchain Templates with a Windows Bastion Host.

Prerequisites

This post assumes that you are familiar with AWS Blockchain Templates, Ethereum, Solidity, and smart contracts.

AWS Blockchain Templates provide a fast and easy way to create and deploy blockchain networks using popular open-source frameworks. Solidity is a contract-oriented, high-level language for implementing smart contracts. It was influenced by C++, Python and JavaScript and is designed to target the Ethereum Virtual Machine (EVM).

The following documentation provides background reading to help you perform the steps described in this post:

Build an Ethereum network using AWS Blockchain Templates

To build the environment shown in the diagram preceding, you can deploy the following AWS CloudFormation template. Doing this builds out a private Ethereum blockchain network on Amazon ECS with the following web services exposed by an internal Application Load Balancer:

  • Ethereum Network Status – a web-based application to monitor the health of your Ethereum network.
  • Ethereum Explorer – a block explorer for Ethereum.
  • Ethereum JSON-RPC – a stateless, lightweight remote procedure call (RPC) protocol.

You can use the Ethereum Network Status page to view the health and activity of your network and the Ethereum Explorer page to view produced blocks and their content. You can use the JSON-RPC URL to connect remotely to your blockchain network and issue remote procedure calls. In this blog post, rather than issuing remote calls, we add a node to the network and issuing commands against that node. You use the Windows Bastion Host  to run the new node, client software, connect to the blockchain and deploy a smart contract.

The following provided CloudFormation templates can assist you with getting your Private Ethereum Network deployed with preconfigured defaults and also the necessary software to interact with your private blockchain.

Note: These templates build out the full environment as reflected in the architecture diagram preceding. The base level Ethereum templates originally come from the AWS webpage Getting Started with AWS Blockchain Templates. If you’re interested in modifying any of the default blockchain parameters, see the original source templates.

Step 1: Deploy the CloudFormation template

To start, deploy the CloudFormation template from this Amazon S3 bucket, which installs a Private Ethereum Blockchain network with preconfigured defaults and associated software for you to use as we step through the blog post.

After the templates are deployed, log in to your Windows Bastion Host by using Remote Desktop Protocol (RDP). Because this instance sits within your VPC, you can use client tools to communicate with your private network.

Note: If you can’t connect to your bastion host, check the associated security group ingress rule to be sure that it matches your source IP address for RDP traffic.

The Windows Bastion Host has two client tools preinstalled that we use to connect to the blockchain:

  • Ethereum Wallet – the Ethereum GUI that enables you to hold and secure ether and other cryptoassets built on Ethereum, and also write, deploy, and use smart contracts.
  • geth – the command line interface for running a full Ethereum node implemented in Go. You can launch geth with an interactive console that provides a JavaScript runtime environment, exposing a JavaScript API to interact with your node. 

Running commands

For ease of reference, a complete list of commands to run has been provided for you at the following path: C:\Users\Administrator\EthereumPrivate\commands.txt

You can open the commands.txt file with the following PowerShell command:

PowerShell_ISE -file .\EthereumPrivate\commands.txt

The reason we use PowerShell_ISE to view and edit files is because Notepad.exe changes the formatting of the file contents.

Note: Don’t run geth commands within PowerShell_ISE but only within your standard PowerShell interface.

The following screenshot shows an example of accessing your commands.txt file.

Synchronizing your node

Although Ethereum Wallet and geth can connect to your remote nodes by using RPC, they are not designed to do this in a secure way. For example, when you unlock an account while connected over HTTP, geth sends your password in plain text over HTTP to the remote node. Therefore, we’re going to run a local geth node that joins the network.

Step 2: Review the genesis block

Every blockchain starts with the genesis block. When you run geth with default settings for the first time, the main net genesis block is committed to the database. For a private network, you usually want a different genesis block.

A folder called C:\Users\Administrator\EthereumPrivate has been created to store your private blockchain files. Inside this folder is a file called genesis.json. This file is used to create a genesis block that is compatible with the private network you’ve built using the AWS Blockchain Templates. Doing this enables you to synchronize your node with the private network hosted on Amazon ECS.

Open the file and review its contents. It should look similar to the following.

{
"config":{
"chainId":1234,
"homesteadBlock":0,
"eip155Block":0,
"eip158Block":0},
"nonce":"0x0000000000000001",
"mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty":"0x1",
"coinbase":"0x0000000000000000000000000000000000000000",
"timestamp":"0x00",
"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit":"0x7a1200",

"alloc":{
"0x0ADfCCa4B2a1132F82488546AcA086D7E24EA324":
{"balance":"1000000000000000000000"},

"0x0bd5EebDC3E53973dDF236D43906C776a5fE3784":
{"balance":"1000000000000000000000"},

"0x9537cb86f5a03C8CCB52c44b49757861eCA0004b":
{"balance":"1000000000000000000000"},

"0x1Fbc353788338F902630E5494aD7FaC7dF8dBb29":
{"balance":"1000000000000000000000"},

"0x5ccBe3B9B15eFB62bB2696051091Ee7C1Eb4c7E6":
{"balance":"1000000000000000000000"}

}
}

Note: If you changed default values during the CloudFormation deployment, for example to “Ethereum Network ID” or “Initial List of Accounts,” then ensure that you make the same changes in the genesis file.

Step 3: Create a static node mapping

A static node mapping tells your node what other nodes to communicate with in the network. A file for doing this has already been created for you, but you still need to edit it.

In our setup, we set the static nodes as the ones currently running as tasks in Amazon ECS. Doing this allows your local node to participate in the same network as the one hosted on AWS.

Browse to the following file directory on your Windows Bastion Server:

C:\Users\Administrator\EthereumPrivate\geth\

Now open the file called static-nodes.json in this directory and populate it with the following node information from your Amazon DynamoDB table.

Note: Refer to the DynamoDB table created by the AWS Blockchain Templates with a name containing “The name of your CloudFormation stack” for the IP info required for your environment.

The following screenshot shows an Ethereum node and IP information.

[
"enode://<id>@<ip address>:30303",
"enode://<id>@<ip address>:30303",
"enode://<id>@<ip address>:30303"
]

We assume that you are still logging in to Windows with your Administrator account. As a best practice, we recommend that you set up an alternate non-Administrator user after you are familiar with the steps outlined in this blog post.

To edit the file static-nodes.json, run the following PowerShell command:

PowerShell_ISE -file .\EthereumPrivate\geth\static-nodes.json

As part of the CloudFormation stack deployment, you look up your enode ID and accompanying IP address in the DynamoDB table created. In addition, make the necessary changes to your static-node.json file. Remember to save your changes before closing the file.

You should now have a file with corresponding configuration information relevant to your environment. Your file is located here:

C:\Users\Administrator\EthereumPrivate\geth\static-nodes.json

Note: Don’t use the configuration file following, which we provide only as an example.

An example static-nodes.json file is shown following.

[
"enode://18c1c4869d9e54b75ce968c1726b4ada18732ab5b577c2d0a35d85384e03def3e61a948dd0a1ba968d675c849df36e36cd5c9b15b66239974525551a40433406@10.0.40.135:30303",
"enode://681867148e14ee9c6f1fb839e9f0674651e3e27eb1f1e15d3b2ae7e3de1640e6af3441cc06ea686db7f75b07a2294d95c6e4555400f9a698ca1cbafdebde4d8e@10.0.30.154:30303",
"enode://8ac49be3a5da121ca7dffd74e613a2d490771d0328da05f8c686192d6dbf8f9055e5935101498451a48c13d7e0b94063e812e1f2e56b07a01a6035dfbda80234@10.0.40.52:30303"
]

Step 4: Initialize the Ethereum client

Now with your genesis.json and static-nodes.json files in place, it’s time to initialize the Ethereum client.

First, you need to initialize your geth client to use the genesis block defined in genesis.json. To do so, open PowerShell and run the following command:

geth --datadir C:\Users\Administrator\EthereumPrivate init C:\Users\Administrator\EthereumPrivate\genesis.json

Note: Don’t run geth commands within PowerShell_ISE but only within your standard PowerShell interface.


Step 5: Start geth

Now your genesis block and peer nodes are configured. It’s time to start the Ethereum client and configure it to communicate with your private network. You do so by running the following command.

geth --datadir C:\Users\Administrator\EthereumPrivate —networkid 1234

Note: Don’t run geth commands within PowerShell_ISE but only within your standard PowerShell interface.

Step 6: Interact with your network by using the Ethereum Wallet app

To interact with your network, you start by opening the Ethereum Wallet app.

A wallet is where you can store your keys and associated ether, contracts, and tokens. Your assets are not actually stored on your machine but rather on the blockchain.

Your public key can have assets assigned to it. Your private key is used to sign transactions that enable you to create and interact with contracts and send assets to others.

You should see an Ethereum Wallet icon on the desktop. Double-click this icon to open the app. Doing so connects to your private Ethereum network, and you see a screen like the following.

Private-Net indicates that you’re using a nonpublic network ID such as 1234.

Step 7: Add an account

To start testing transactions and smart contracts, you add an account. Accounts are password-protected keys that can hold ether, secure ethereum-based tokens or coins, and control contracts.

In the Ethereum Wallet, go to File, New Account, enter a password, and press Enter. Confirm your password, and press Enter. You have now created an account.

Step 8: Start mining

Mining is the process of confirming blocks to the network by solving a mathematical problem.

With proof of work, the aim is to take the combination of the previous block hash, timestamp, and transactions, and a nonce value to produce a hash with a certain number of leading zeros. All members of the network have the first three variables, so it’s essentially a race to find the nonce value that produces the desired result. The first node to find the answer broadcasts it to the network for confirmation. After the other nodes have verified the answer, the block is committed and ether is rewarded to the miner.

Mining on the public Ethereum network is a complex task because it’s only feasible using GPUs, requiring an OpenCL or CUDA enabled ethminer instance. In a private network setting, however, a single CPU miner instance is more than enough for practical purposes. A single instance can produce a stable stream of blocks at the correct intervals without needing heavy resources.

You need to start mining some ether so you have funds available for transactions such as creating smart contracts. To do this, you need to open another PowerShell window and attach to the geth instance with geth attach ipc:\\.\pipe\geth.ipc so you can run commands.

Step 9: See the accounts that you have registered

Type eth.accounts to see the accounts that you have registered.

You should see the same account you just created in Ethereum Wallet.

Step 10: Start mining with two threads

Type miner.start(2) to start mining with two threads.

You should now see your account within the Ethereum wallet start accumulating ether from the mining activities.

Step 11: Create, deploy, and test your smart contract

As a next step, create a smart contract.

Tokens in the Ethereum ecosystem can represent any fungible tradable good: coins, loyalty points, gold certificates, IOUs, in-game items, and so on. All tokens implement some basic features in a standard way. Because of this, your token is instantly compatible with the Ethereum wallet and any other client or contract that uses the same standards.

We’re now going to build a basic contract that deploys a token or coin. For a bit of fun, I’m going to create my own basic currency called MattCoin. Feel free to modify the name from MattCoin to whatever makes sense for you. You can have a bit of fun and tell your friends you now have your own cryptocurrency too!

To deploy this contract, click CONTRACTS in the Ethereum Wallet, then select DEPLOY NEW CONTRACT.

Following is the code for the contract we’re going to deploy to build MattCoin. Paste this code into the SOLIDITY CONTRACT SOURCE CODE section. Next, select the contract to deploy and also the initial number of tokens to create. Then, click DEPLOY and enter the password you created with the account.

This code creates a smart contract for a simple coin or token. First, it creates a mapping of all possible Ethereum addresses and gives them a balance. The variables allow any address to hold a value of MattCoin. Next, in the constructor we specify that the entire initial supply should go to the creator of the contract. Then finally, we define a function called transfer, which allows us to send MattCoin from one Ethereum address to another.

pragma solidity ^0.4.18;
contract MattCoin {
    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;

    /* Initializes contract with initial supply tokens to the creator of the contract */
    constructor(
        uint256 initialSupply
        ) public {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) public {
        require(balanceOf[msg.sender] >= _value);           // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]); // Check for overflows
        balanceOf[msg.sender] -= _value;                    // Subtract from the sender
        balanceOf[_to] += _value;                           // Add the same to the recipient
    }
}

You now see the contract being created. The process finishes after it’s been mined into the next block.

After the contract has been created, click it and enter your account address into the Balance of field. You should then see a balance equal to the amount you created with the contract.

If you want to test sending your tokens to another Ethereum account, first create a second account. Then select the transfer function, provide a to address and the number of tokens to transfer, and click EXECUTE.

You are again asked to enter your password to sign the transaction.

After the transaction is sent, enter the to address value into the Balance of field and you should see the amount of value you sent to this address.

Conclusion

You’ve now set up your own private Ethereum network and deployed your first smart contract. By using the AWS Blockchain Template for Ethereum, it was easy to get started with your blockchain project and start testing use cases. Next, you can consider what other members might be interested in participating in this network and using a GUI with your smart contracts like Ethereum Wallet.


About the Authors

Matt Taylor is an AWS Partner Solultions Architect with experience in IT infrastructure architecure and delivery. He helps enable consulting partners on AWS products and services so they can best solve problems for customers. In his spare time he enjoys learning about blockchain technology and speculating on where it will be most impactful in future applications and industries.

 

 

 

Pierre Liddle has a wide range of experience ranging from security operations and engineering to architecture and risk management. He now brings his knowledge to helping AWS customers. As an AWS Enterprise Solutions architect with a focus on security, Pierre helps AWS customers manage risks and design secure workloads to meet their security requirements.