How to Write a Smart Contract on Ontology with Python - (Part 1)

The Ontology Team
OntologyNetwork
Published in
4 min readSep 22, 2019

Foreword

In the previous tech articles, we introduced the smart contract system supported by the Ontology MainNet and the smart contract development tool SmartX. We are sure many of you just can’t wait to try it on.

In this article, we will begin to introduce the smart contract API of Ontology. The Ontology’s smart contract API is divided into 7 modules, Blockchain & Block API, Runtime API, Storage API, Native API, Upgrade API, Execution Engine API, and Static & Dynamic Call API.

In this article, we will introduce the Blockchain & Block API, which is the most basic part of the Ontology smart contract system. The Blockchain API supports basic blockchain query operations, such as obtaining the current block height, whereas the Block API supports basic block query operations, such as querying the number of transactions for a given block.

Let’s get started!

First, create a new contract in SmartX and then follow the instructions below.

1 How to Use Blockchain API

References to smart contract functions are identical to Python’s references. Developers can introduce the appropriate functions as needed. For example, the following statement introduces GetHeight, the function to get the current block height, and GetHeader, the function to get the block header.

from ontology.interop.System.Blockchain import GetHeight, GetHeader

1.1 GetHeight

Developers can use GetHeight to get the latest block height, as shown in the following example. In the latter example, for convenience, we will omit the Main function, but you can add it if it’s needed.

from ontology.interop.System.Runtime import Notify
from ontology.interop.System.Blockchain import GetHeight
def Main(operation):
if operation == 'demo':
return demo()
return False

def demo():
height=GetHeight()
Notify(height) # print height
return height #return height after running the function

1.2 GetHeader

Developers can use GetHeader to get the block header, and the parameter is the block height of a block. Here’s an example:

from ontology.interop.System.Runtime import Notify
from ontology.interop.System.Blockchain import GetHeader
def demo():
block_height=10
header=GetHeader(block_height)
Notify(header)
return header

1.3 GetTransactionByHash

Developers can use the GetTransactionByHash function to get transactions through transaction hash. The transaction hash is sent to GetTransactionByHash as parameters in bytearray format. The key to this function is how to convert a transaction hash in hex format to a transaction hash in bytearray format. This is an important step. Otherwise, you would get an error which indicates that there is no block of this block hash.
Let’s take the transaction hash in hex format as an example to convert it to bytearray format. The example is as follows:

9f270aa3a4c13c46891ff0e1a2bdb3ea0525669d414994aadf2606734d0c89c1

First, reverse the transaction hash:

c1890c4d730626dfaa9449419d662505eab3bda2e1f01f89463cc1a4a30a279

Developers can implement this step with the conversion tool Hex Number(little endian)<--> Number provided by SmartX.

Then, convert it to bytearray format:

{0xc1,0x89,0x0c,0x4d,0x73,0x06,0x26,0xdf,0xaa,0x94,0x49,0x41,0x9d,0x66,0x25,0x05,0xea,0xb3,0xbd,0xa2,0xe1,0xf0,0x1f,0x89,0x46,0x3c,0xc1,0xa4,0xa3,0x0a,0x27,0x9f}

Developers can do this with the conversion tool String <-->Byte Array provided by SmartX. Finally, convert the resulting bytearray to the corresponding string:

\xc1\x89\x0c\x4d\x73\x06\x26\xdf\xaa\x94\x49\x41\x9d\x66\x25\x05\xea\xb3\xbd\xa2\xe1\xf0\x1f\x89\x46\x3c\xc1\xa4\xa3\x0a\x27\x9f

Below is an example of the GetTransactionByHash function that gets a transaction through a transaction hash:

from ontology.interop.System.Blockchain import GetTransactionByHash
def demo():
# tx_hash="9f270aa3a4c13c46891ff0e1a2bdb3ea0525669d414994aadf2606734d0c89c1"
tx_hash=bytearray(b"\xc1\x89\x0c\x4d\x73\x06\x26\xdf\xaa\x94\x49\x41\x9d\x66\x25\x05\xea\xb3\xbd\xa2\xe1\xf0\x1f\x89\x46\x3c\xc1\xa4\xa3\x0a\x27\x9f")
tx=GetTransactionByHash(tx_hash)
return tx

1.4 GetTransactionHeight

Developers can use the GetTransactionHeight function to get transaction height through transaction hash. Let’s take the hash in the above example:

from ontology.interop.System.Blockchain import  GetTransactionHeight
def demo():
# tx_hash="9f270aa3a4c13c46891ff0e1a2bdb3ea0525669d414994aadf2606734d0c89c1"
tx_hash=bytearray(b"\xc1\x89\x0c\x4d\x73\x06\x26\xdf\xaa\x94\x49\x41\x9d\x66\x25\x05\xea\xb3\xbd\xa2\xe1\xf0\x1f\x89\x46\x3c\xc1\xa4\xa3\x0a\x27\x9f")
height=GetTransactionHeight(tx_hash)
return height

1.5 GetContract

Developers can use the GetContract function to get a contract through contract hash. The conversion process of the contract hash is consistent with the transaction hash conversion process mentioned above.

from ontology.interop.System.Blockchain import GetContract
def demo():
# contract_hash="d81a75a5ff9b95effa91239ff0bb3232219698fa"
contract_hash=bytearray(b"\xfa\x98\x96\x21\x32\x32\xbb\xf0\x9f\x23\x91\xfa\xef\x95\x9b\xff\xa5\x75\x1a\xd8")
contract=GetContract(contract_hash)
return contract

1.6 GetBlock

Developers can use the GetBlock function to get the block. There are two ways to get a specific block:

  1. Get the block by block height:
from ontology.interop.System.Blockchain import GetBlock
def demo():
block=GetBlock(1408)
return block

2. Get the block by block hash:

from ontology.interop.System.Blockchain import GetBlock
def demo():
block_hash=bytearray(b'\x16\xe0\xc5\x40\x82\x79\x77\x30\x44\xea\x66\xc8\xc4\x5d\x17\xf7\x17\x73\x92\x33\x6d\x54\xe3\x48\x46\x0b\xc3\x2f\xe2\x15\x03\xe4')
block=GetBlock(block_hash)

2 How to Use Block API

There are three functions available in the Block API, which are GetTransactions, GetTransactionCount, and GetTransactionByIndex. We will introduce them one by one.

2.1 GetTransactionCount

Developers can use the GetTransactionCount function to get the number of transactions for a given block.

from ontology.interop.System.Blockchain import GetBlock
from ontology.interop.System.Block import GetTransactionCount
def demo():
block=GetBlock(1408)
count=GetTransactionCount(block)
return count

2.2 GetTransactions

Developers can use the GetTransactions function to get all the transactions in a given block.

from ontology.interop.System.Blockchain import GetBlock
from ontology.interop.System.Block import GetTransactions
def demo():
block=GetBlock(1408)
txs=GetTransactions(block)
return txs

2.3 GetTransactionByIndex

Developers can use the GetTransactionByIndex function to get specific transactions in a given block.

from ontology.interop.System.Blockchain import GetBlock
from ontology.interop.System.Block import GetTransactionByIndex
def demo():
block=GetBlock(1408)
tx=GetTransactionByIndex(block,0) # index starts from 0.
return tx

Find the complete tutorial on our GitHub here.

Afterword

The Blockchain & Block API is the most indispensable part of smart contracts since you can use them to query blockchain data and block data in smart contracts. In the next few articles, we will discuss how to use other APIs to explore their interaction with the Ontology blockchain.

Are you a developer? Make sure you have joined our tech community on Discord. Also, take a look at the Developer Center on our website, there you can find developer tools, documentation, and more.

--

--