本體技術視點 | Python智慧合約教程之原生合約呼叫

買賣虛擬貨幣
上一期我們介紹了本體 Python 智慧合約的合約執行 API,本期我們將討論如何透過 Native API 來進行本體原生合約呼叫。原生合約呼叫最典型的功能就是合約轉賬,這也是整個智慧合約最核心的部分。Native API 只有1個 API。用法如下:

同時,使用 Invoke 函式需要內建的 state 函式輔助來封裝引數,用法如下:

下面我們具體講述一下這兩個 API 的使用方法。在這之前,小夥伴們可以在本體智慧合約開發工具 SmartX 中新建一個合約,跟著我們進行操作。跟以前的API講解一樣,在文章最後我們將給出這次講解的所有原始碼以及影片講解。

02 Native API 使用方法

同樣,使用這兩個函式前需要引入。下面兩條語句分別引入了這兩個函式。

from ontology.interop.Ontology.Native import Invoke
from ontology.builtins import state

2.1 本體原生合約列表

目前,本體可供使用的原生合約有六個。以下就是可以使用 Native API 呼叫的原生合約列表:

在合約中,將合約地址轉成 bytearray 形式傳入 Invoke 即可。例如,需要呼叫 ONT Token 合約時,可以先將 ONT Token 合約對應的地址轉成相應的 bytearray 形式,再進行相應的 Invoke 函式呼叫。在進行 Invoke 函式呼叫時,傳入的引數分別為版本號,合約地址,呼叫的合約方法以及 state 函式封裝的轉賬相關引數。

這裡特別要注意的一點是,在進行 ONG 的合約轉賬時,所填數量是實際數量的10^9倍。 即,如果需要轉10個 ONG,那麼數量需要填為10^10。而在採用 ONTO 或者 Cyano 等錢包轉賬時,所填數量即為轉賬數量。

contract_address_ONT = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
param = state(from_acct, to_acct, ont_amount) # 引數為轉出地址,轉入地址, 轉賬金額
res = Invoke(1, contract_address_ONT, 'transfer', [param])

2.2 轉賬合約程式碼

下面我們給出一個完整的示例,演示如何使用 Python 語言來實現 ONT 以及 ONG 的轉賬功能。下述程式碼以傳入的轉出賬戶和轉入地址引數型別為string為例實現該合約。另外,也可以以address為型別的賬戶引數進行傳遞,從而達到節省呼叫Gas費用的目的。該合約程式碼流程如下:

1. 定義合約地址變數 contract_address_ONT,contract_address_ONG;
2. 將轉出地址和轉入地址從 base58 格式轉成 bytearray 格式;
3. 驗籤,確認轉出地址與合約呼叫地址為同一地址;
4. state 函式封裝轉賬相關引數;
5. Invoke 函式呼叫 ONT Token 和 ONG Token 原生合約轉賬;
6. 透過返回 res 判斷轉賬是否成功。返回值 b'\x01' 為成功,成功則推送事件“transfer succeed”。

from ontology.interop.System.Runtime import Notify, CheckWitness
from ontology.interop.Ontology.Runtime import Base58ToAddress
from ontology.interop.Ontology.Native import Invoke
from ontology.builtins import state

# contract address 
contract_address_ONT = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
contract_address_ONG = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')

def Main(operation, args):
    if operation == 'transfer':
        from_acct = args[0]
        to_acct = args[1]
        ont_amount = args[2]
        ong_amount = args[3]
        return transfer(from_acct,to_acct,ont_amount,ong_amount)

    return False


def transfer(from_acct, to_acct, ont_amount, ong_amount):
    # 將base58地址轉換成 bytearray格式地址 
    from_acct=Base58ToAddress(from_acct)
    to_acct=Base58ToAddress(to_acct)
    # 驗籤,呼叫方必須與轉出地址為同一地址
    if CheckWitness(from_acct):
        # ONT轉賬
        if ont_amount > 0:
            param = state(from_acct, to_acct, ont_amount) # state函式用於封裝轉賬相關引數
            res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke呼叫ONT token原生合約轉賬
            if res and res == b'\x01':
                Notify('transfer succeeded')
            else:
                Notify('transfer failed')
        # ONG轉賬,流程同上
        if ong_amount > 0:
            param = state(from_acct, to_acct, ong_amount)
            res = Invoke(1, contract_address_ONG, 'transfer', [param])
            if res and res == b'\x01':
                Notify('transfer succeeded')
            else:
                Notify('transfer failed')
    else:
        Notify('CheckWitness failed')

03 SmartX 實踐

接下來,小夥伴們可以在 SmartX 上進行操作,動手編譯和執行上述提供的合約示例程式碼。具體步驟如下:

1. 編譯合約。首先在 SmartX 中新建一個合約專案,並將程式碼放入該專案中進行編譯。

2. 部署合約。部署過程中如需申請測試幣,申請地址為https://developer.ont.io/applyOng。部署結果示意如下:

3. 執行轉賬。執行 transfer 函式進行轉賬前需要進行相關引數設定。在該示例中,需要填入傳送地址、接收地址、代轉賬的 ONT 數量以及 ONG 數量:

4. 轉賬成功。當轉帳引數設定正確時,執行 transfer 函式將轉賬成功。上面所填的接收地址中將顯示出收到的代幣:

04 總結

本次技術視點中我們介紹了本體區塊鏈的 Native API,開發者可以使用 Native API 來進行本體原生合約呼叫。原生合約呼叫最典型的功能就是合約轉賬,這也是整個智慧合約最核心的部分。在下一期技術視點中,我們將介紹 Upgrade API,探討如何在本體智慧合約中進行合約升級。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;