Author: Yongxin Xu

In my last blog, I introduced the model of my vending machine DApp, and a new smart contract (transaction protocol) I defined for this application, which is called “aggregate transaction”. Since then, I have kept working on programming my smart contract and building an off-chain simulator. Thus, in this post, I want to give you a brief overview of the coding steps for programming and deploying a new smart contract and some feedbacks of working with Arcblock's Forge Framework.

First, let's do a quick review of the aggregate transaction. In the previous blogs, I mentioned that my DApp works as a trustworthy ledger for vending machine business. The role of blockchain in my DApp is to ensure all data in the ledger are reliable, or say, immutable. Hence, the DApp only requires the blockchain to complete the recording of bill data. To achieve my needs, I need to program a new smart contract, or say, define a new type of transaction --“aggregate transaction”. Basically, whenever there is a bill, a vending machine’s wallet account will put all relevant information on the chain by sending an aggregate transaction. When the aggregate transaction is successfully sent, the profit amount of related parties will be automatically updated in their wallet accounts. Once everything is on the chain, nothing can be falsified, and therefore the ledger will be always trustworthy.

dapp model aggregate tx

Here are the coding steps for programming and deploying a new smart contract:

First, create a custom chain.

Forge CLI, a tool provided by the Forge Framework, makes it easy to create a custom chain. A node can be created and started locally by the command forge start.

Second, program a new smart contract.

To make a new smart contract, you need to program the following four files:

  • protocol.proto
    protocol.proto is to define the data structure of a transaction. In other words, it tells the chain what this type of transaction looks like and what information it includes. In the Forge Framework, a transaction is composed of two layers, (outer) transaction and inner transaction. To make it simple, the outer layer contains the common information of every type of transaction, such as sender and sending time, while the inner layer (inner transaction) has the information specific to each type of transaction. Therefore, protocol.proto is actually to define the structure and content of this inner layer.

tx structure proto

  • protocol.yml
    protocol.yml is to tell the chain the working process to handle this new smart contract by making a pipeline. Basically, Forge Nodes process every transaction by three steps.
  • Check. When a Forge Node receives a transaction, it will firstly skim through the whole transaction to see if there are any obvious issues, as some fields are not filled up, for example.
  • Verify. Compared to check, this is a more thorough inspection and a transaction that passes the verification is identified as completely valid to the chain.

    To better understand the difference between check and verify, just think about airport security! When we go through airport security, we usually have to go through two things: one is to check our ID and boarding pass to see any issues with our information, and the other is to go through a full-body scanner to detect any illegal item. Only after the security check could we board the planes.

  • Update. The last step is to update the state of the entire chain after a transaction has been verified.

    The Forge Framework provides a number of predefined “pipes” that allow developers to build their pipelines as easily as building blocks. Still, developers can program custom pipes themselves. For example, since different types of transactions will update different data on the chain, we usually need to customize a pipe for the last step, update.


  • protocol.ex
    protocol.ex is to program our custom pipes. Its programming language is Elixir. Although Elixir might be new to us, the logic behind the program is simple. For more information on how to program in Elixir, please go to our references.
  • config.yml
    config.yml contains the basic information about this whole smart contract as a reference to the chain. It specifies the three files we have talked about, and the current version number. Every time when we modify a smart contract, we need to update its version number. If we forget to update this number when we try to deploy a revised smart contract, the chain will not update anything for us.


Third, deploy the new smart contract.

Forge CLI provides an easy way for us to deploy a new smart contract. By following the instructions in our documentation, we can easily deploy our new smart contracts.

Fourth, test the new smart contract.

We can test our new smart contracts in Forge remote console by using Elixir SDK. Elixir SDK is very easy to use. But since Python is my favorite, I want to show how to use Python SDK to test our new smart contracts here. Mainly, there are three steps:

  • Compile the new smart contract. We may use the Protocol Buffer Compiler provided by Google to compile protocol.proto into a python-support file.
protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/protocol.proto
  • Create wallet accounts. As I mentioned in the last post, a wallet is the initiator or the recipient of all transactions on the chain. As long as we know the wallet address of another person, we can interact with them on the chain. Therefore, I want to create wallet accounts for vending machines --the initiator of the aggregate transaction, and the relevant parties --the recipients. Creating a wallet via Python-SDK can be done with the following commands. We can easily check the address and the balance of those wallets as well.
from forge_sdk import ForgeConn
f = ForgeConn('')
rpc = f.rpc
vm = rpc.create_wallet(moniker='vending_machine', passphrase='vm1234')
addr = vm.wallet.address
  • Finally, send the transaction. I can send an aggregate transaction with the following commands. After sending the transaction, the chain will return a hash value. Through this hash value, we may verify if the transaction is sent to the chain successfully.
itx =  protos.AggregateTx(sku=sku, value=value, time=time, operator=op.wallet.address, manufacturer=ma.wallet.address, supplier=su.wallet.address, location=lo.wallet.address)
itx2 = utils.encode_to_any(type_url="fg:t:aggregate", data=itx)
rpc.send_itx(tx=itx2, wallet=vm.wallet, token=vm.token, nonce=0)


Above are the coding steps for programming and deploying a new smart contract. If there are no problems, the on-chain part of my DApp is basically completed. Next, we can focus on the off-chain parts which we are most familiar with.

After deploying the smart contract through the Forge Framework, my biggest feeling is that using the forge framework to customize our own chain is really simple. Forge Framework solves the underlying complicated blockchain technology for us. That is to say, it blocks out the sophisticated knowledge we do not need to know when we just want to make a DApp, and greatly reduces the difficulty of building DApps and providing a template for us to follow. Next time, I plan to show my vending machine DApp to everyone and the process of how I finish up the off-chain parts. I am also very much looking forward to what my application will look like in the end. In addition, in the three weeks of study and practice, I also gained a lot of experience, and I have a deeper understanding of the blockchain technology and how it can change our lives. These will also be shared with you in the next post. See you soon!