上一期我們介紹了本體 Python 智能合約的合約執(zhí)行 API,本期我們將討論如何通過 Native API 來進(jìn)行本體原生合約調(diào)用。原生合約調(diào)用最典型的功
上一期我們介紹了本體 Python 智能合約的合約執(zhí)行 API,本期我們將討論如何通過 Native API 來進(jìn)行本體原生合約調(diào)用。原生合約調(diào)用最典型的功能就是合約轉(zhuǎn)賬,這也是整個(gè)智能合約最核心的部分。Native API 只有1個(gè) API。用法如下:
同時(shí),使用 Invoke 函數(shù)需要內(nèi)建的 state 函數(shù)輔助來封裝參數(shù),用法如下:
下面我們具體講述一下這兩個(gè) API 的使用方法。在這之前,小伙伴們可以在本體智能合約開發(fā)工具 SmartX 中新建一個(gè)合約,跟著我們進(jìn)行操作。跟以前的API講解一樣,在文章最后我們將給出這次講解的所有源代碼以及視頻講解。
02 Native API 使用方法
同樣,使用這兩個(gè)函數(shù)前需要引入。下面兩條語句分別引入了這兩個(gè)函數(shù)。
from ontology.interop.Ontology.Native import Invoke
from ontology.builtins import state
2.1 本體原生合約列表
目前,本體可供使用的原生合約有六個(gè)。以下就是可以使用 Native API 調(diào)用的原生合約列表:
在合約中,將合約地址轉(zhuǎn)成 bytearray 形式傳入 Invoke 即可。例如,需要調(diào)用 ONT Token 合約時(shí),可以先將 ONT Token 合約對應(yīng)的地址轉(zhuǎn)成相應(yīng)的 bytearray 形式,再進(jìn)行相應(yīng)的 Invoke 函數(shù)調(diào)用。在進(jìn)行 Invoke 函數(shù)調(diào)用時(shí),傳入的參數(shù)分別為版本號,合約地址,調(diào)用的合約方法以及 state 函數(shù)封裝的轉(zhuǎn)賬相關(guān)參數(shù)。
這里特別要注意的一點(diǎn)是,在進(jìn)行 ONG 的合約轉(zhuǎn)賬時(shí),所填數(shù)量是實(shí)際數(shù)量的10^9倍。 即,如果需要轉(zhuǎn)10個(gè) ONG,那么數(shù)量需要填為10^10。而在采用 ONTO 或者 Cyano 等錢包轉(zhuǎn)賬時(shí),所填數(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)賬合約代碼
下面我們給出一個(gè)完整的示例,演示如何使用 Python 語言來實(shí)現(xiàn) ONT 以及 ONG 的轉(zhuǎn)賬功能。下述代碼以傳入的轉(zhuǎn)出賬戶和轉(zhuǎn)入地址參數(shù)類型為string為例實(shí)現(xiàn)該合約。另外,也可以以address為類型的賬戶參數(shù)進(jìn)行傳遞,從而達(dá)到節(jié)省調(diào)用Gas費(fèi)用的目的。該合約代碼流程如下:
1. 定義合約地址變量 contract_address_ONT,contract_address_ONG;
2. 將轉(zhuǎn)出地址和轉(zhuǎn)入地址從 base58 格式轉(zhuǎn)成 bytearray 格式;
3. 驗(yàn)簽,確認(rèn)轉(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)
# 驗(yàn)簽,調(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 實(shí)踐
接下來,小伙伴們可以在 SmartX 上進(jìn)行操作,動(dòng)手編譯和運(yùn)行上述提供的合約示例代碼。具體步驟如下:
1. 編譯合約。首先在 SmartX 中新建一個(gè)合約項(xiàng)目,并將代碼放入該項(xiàng)目中進(jìn)行編譯。
2. 部署合約。部署過程中如需申請測試幣,申請地址為https://developer.ont.io/applyOng。部署結(jié)果示意如下:
3. 執(zhí)行轉(zhuǎn)賬。執(zhí)行 transfer 函數(shù)進(jìn)行轉(zhuǎn)賬前需要進(jìn)行相關(guān)參數(shù)設(shè)置。在該示例中,需要填入發(fā)送地址、接收地址、代轉(zhuǎn)賬的 ONT 數(shù)量以及 ONG 數(shù)量:
4. 轉(zhuǎn)賬成功。當(dāng)轉(zhuǎn)帳參數(shù)設(shè)置正確時(shí),執(zhí)行 transfer 函數(shù)將轉(zhuǎn)賬成功。上面所填的接收地址中將顯示出收到的代幣:
04 總結(jié)
本次技術(shù)視點(diǎn)中我們介紹了本體區(qū)塊鏈的 Native API,開發(fā)者可以使用 Native API 來進(jìn)行本體原生合約調(diào)用。原生合約調(diào)用最典型的功能就是合約轉(zhuǎn)賬,這也是整個(gè)智能合約最核心的部分。在下一期技術(shù)視點(diǎn)中,我們將介紹 Upgrade API,探討如何在本體智能合約中進(jìn)行合約升級。(Sheldon)