上一期我們介紹了本體 Python 智能合約的合約執(zhí)行 API,本期我們將討論如何通過 Native API 來進行本體原生合約調(diào)用。原生合約調(diào)用最典型的功
上一期我們介紹了本體 Python 智能合約的合約執(zhí)行 API,本期我們將討論如何通過 Native API 來進行本體原生合約調(diào)用。原生合約調(diào)用最典型的功能就是合約轉(zhuǎn)賬,這也是整個智能合約最核心的部分。Native API 只有1個 API。用法如下:
同時,使用 Invoke 函數(shù)需要內(nèi)建的 state 函數(shù)輔助來封裝參數(shù),用法如下:
下面我們具體講述一下這兩個 API 的使用方法。在這之前,小伙伴們可以在本體智能合約開發(fā)工具 SmartX 中新建一個合約,跟著我們進行操作。跟以前的API講解一樣,在文章最后我們將給出這次講解的所有源代碼以及視頻講解。
02 Native API 使用方法
同樣,使用這兩個函數(shù)前需要引入。下面兩條語句分別引入了這兩個函數(shù)。
from ontology.interop.Ontology.Native import Invoke
from ontology.builtins import state
2.1 本體原生合約列表
目前,本體可供使用的原生合約有六個。以下就是可以使用 Native API 調(diào)用的原生合約列表:
在合約中,將合約地址轉(zhuǎn)成 bytearray 形式傳入 Invoke 即可。例如,需要調(diào)用 ONT Token 合約時,可以先將 ONT Token 合約對應的地址轉(zhuǎn)成相應的 bytearray 形式,再進行相應的 Invoke 函數(shù)調(diào)用。在進行 Invoke 函數(shù)調(diào)用時,傳入的參數(shù)分別為版本號,合約地址,調(diào)用的合約方法以及 state 函數(shù)封裝的轉(zhuǎn)賬相關(guān)參數(shù)。
這里特別要注意的一點是,在進行 ONG 的合約轉(zhuǎn)賬時,所填數(shù)量是實際數(shù)量的10^9倍。 即,如果需要轉(zhuǎn)10個 ONG,那么數(shù)量需要填為10^10。而在采用 ONTO 或者 Cyano 等錢包轉(zhuǎn)賬時,所填數(shù)量即為轉(zhuǎn)賬數(shù)量。
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) # 參數(shù)為轉(zhuǎn)出地址,轉(zhuǎn)入地址, 轉(zhuǎn)賬金額
res = Invoke(1, contract_address_ONT, 'transfer', [param])
2.2 轉(zhuǎn)賬合約代碼
下面我們給出一個完整的示例,演示如何使用 Python 語言來實現(xiàn) ONT 以及 ONG 的轉(zhuǎn)賬功能。下述代碼以傳入的轉(zhuǎn)出賬戶和轉(zhuǎn)入地址參數(shù)類型為string為例實現(xiàn)該合約。另外,也可以以address為類型的賬戶參數(shù)進行傳遞,從而達到節(jié)省調(diào)用Gas費用的目的。該合約代碼流程如下:
1. 定義合約地址變量 contract_address_ONT,contract_address_ONG;
2. 將轉(zhuǎn)出地址和轉(zhuǎn)入地址從 base58 格式轉(zhuǎn)成 bytearray 格式;
3. 驗簽,確認轉(zhuǎn)出地址與合約調(diào)用地址為同一地址;
4. state 函數(shù)封裝轉(zhuǎn)賬相關(guān)參數(shù);
5. Invoke 函數(shù)調(diào)用 ONT Token 和 ONG Token 原生合約轉(zhuǎn)賬;
6. 通過返回 res 判斷轉(zhuǎn)賬是否成功。返回值 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地址轉(zhuǎn)換成 bytearray格式地址
from_acct=Base58ToAddress(from_acct)
to_acct=Base58ToAddress(to_acct)
# 驗簽,調(diào)用方必須與轉(zhuǎn)出地址為同一地址
if CheckWitness(from_acct):
# ONT轉(zhuǎn)賬
if ont_amount > 0:
param = state(from_acct, to_acct, ont_amount) # state函數(shù)用于封裝轉(zhuǎn)賬相關(guān)參數(shù)
res = Invoke(1, contract_address_ONT, 'transfer', [param]) # invoke調(diào)用ONT token原生合約轉(zhuǎn)賬
if res and res == b'\x01':
Notify('transfer succeeded')
else:
Notify('transfer failed')
# ONG轉(zhuǎn)賬,流程同上
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。部署結(jié)果示意如下:
3. 執(zhí)行轉(zhuǎn)賬。執(zhí)行 transfer 函數(shù)進行轉(zhuǎn)賬前需要進行相關(guān)參數(shù)設置。在該示例中,需要填入發(fā)送地址、接收地址、代轉(zhuǎn)賬的 ONT 數(shù)量以及 ONG 數(shù)量:
4. 轉(zhuǎn)賬成功。當轉(zhuǎn)帳參數(shù)設置正確時,執(zhí)行 transfer 函數(shù)將轉(zhuǎn)賬成功。上面所填的接收地址中將顯示出收到的代幣:
04 總結(jié)
本次技術(shù)視點中我們介紹了本體區(qū)塊鏈的 Native API,開發(fā)者可以使用 Native API 來進行本體原生合約調(diào)用。原生合約調(diào)用最典型的功能就是合約轉(zhuǎn)賬,這也是整個智能合約最核心的部分。在下一期技術(shù)視點中,我們將介紹 Upgrade API,探討如何在本體智能合約中進行合約升級。(Sheldon)