日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 物聯(lián)網(wǎng) > 區(qū)塊鏈
[導(dǎo)讀] Ontology Wasm 自從上線測試網(wǎng)以來便受到了社區(qū)開發(fā)人員的極大關(guān)注。Ontology Wasm 的上線將使得業(yè)務(wù)邏輯復(fù)雜的 dApp 合約上鏈成本降低,極大豐富 dApp 生態(tài)。在進(jìn)行

Ontology Wasm 自從上線測試網(wǎng)以來便受到了社區(qū)開發(fā)人員的極大關(guān)注。Ontology Wasm 的上線將使得業(yè)務(wù)邏輯復(fù)雜的 dApp 合約上鏈成本降低,極大豐富 dApp 生態(tài)。在進(jìn)行 Ontology Wasm 合約開發(fā)時,開發(fā)者不僅可以使用 Rust,還可以使用 C++ 作為合約開發(fā)語言。


一、Hello World

按照慣例,我們還是從一個 Hello world 開始

#include《ontiolib/onTIo.hpp》#include《stdio.h》

using namespace onTIo;class hello:public contract {

public:

using contract::contract:

void sayHello(){

printf(“hello world!”);

}

};

ONTIO_DISPATCH(hello, (sayHello));

1.1 合約入口

Ontology Wasm CDT 編譯器已經(jīng)對入口和參數(shù)解析進(jìn)行了封裝,所以開發(fā)者不需要重新定義入口方法。接下來是定義合約的對外接口,這是智能合約對外提供服務(wù)的方法。

ONTIO_DISPATCH(hello, (sayHello));

在上面的例子中, 我們暫時只支持 sayHello 這個方法:

printf(“hello world!”);

這個“Hello world!”會在節(jié)點(diǎn)的日志中以調(diào)試信息打印出來。在實際的應(yīng)用中, printf 只能用作調(diào)試的目的, 一個實際的智能合約,需要實現(xiàn)更多更復(fù)雜的功能。

1.2 智能合約 API

Ontology Wasm 提供如下 API 與區(qū)塊鏈的底層進(jìn)行交互:

二、紅包合約

下面我們通過一個更加復(fù)雜的例子來演示如何通過這些 API 來開發(fā)一個完整的 Wasm 智能合約。

很多情況下我們都會通過各種 App,如微信等聊天工具發(fā)紅包。我們可以給朋友發(fā)送紅包,也可以搶其他人發(fā)送的紅包,收到的錢會記入到個人微信賬戶中。

類似于微信的流程,我們將嘗試創(chuàng)建一個智能合約。用戶使用該合約,可以發(fā)送 ONT,ONG 或者是標(biāo)準(zhǔn)的 OEP-4的 Token 資產(chǎn)紅包給他的朋友們,而朋友們搶到的紅包可以直接轉(zhuǎn)入到他們的錢包賬戶中。

2.1 創(chuàng)建合約

首先,我們需要新建合約的源文件,暫且命名為 redEnvelope.cpp。這個合約我們需要三個接口:

· createRedEnvelope: 創(chuàng)建紅包

· queryEnvelope: 查詢紅包信息

· claimEnvelope: 搶紅包

#include《ontiolib/ontio.hpp》

using namespace ontio;

class redEnvelope: public contract{

}

ONTIO_DISPATCH(redEnvelope, (createRedEnvelope)(queryEnvelope)(claimEnvelope));

我們需要在存儲中保存一些關(guān)鍵的數(shù)據(jù)。在智能合約中, 數(shù)據(jù)以 KV 的形式保存在該合約的上下文空間中,這些數(shù)據(jù)的 KEY 需要設(shè)置前綴以便于后面的查詢。下面定義了三個不同的前綴供使用:

std::string rePrefix = “RE_PREFIX_”;

std::string sentPrefix = “SENT_COUNT_”;

std::string claimPrefix = “CLAIM_PREFIX_”;

因為我們的合約支持 ONT 和 ONG 這兩種 Ontology 的原生資產(chǎn), 我們可以預(yù)先定義好這兩種資產(chǎn)的合約地址。不同于標(biāo)準(zhǔn)的智能合約, Ontology 原生合約(native contract)的合約地址是固定的,而不是根據(jù)合約代碼的 hash 計算而來的。

address ONTAddress = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};

address ONGAddress = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2};

我們需要在合約中保存紅包的信息, 如紅包的資產(chǎn)信息(token 的合約地址, 紅包的總金額, 紅包的個數(shù)等等)。

struct receiveRecord{

address account; //用戶地址

asset amount; //搶到的金額

ONTLIB_SERIALIZE(receiveRecord,(account)(amount))

};

struct EnvelopeStruct{

address tokenAddress; //資產(chǎn)token的地址

asset totalAmount; //紅包總金額

asset totalPackageCount; //紅包總數(shù)

asset remainAmount; //當(dāng)前剩余的金額

asset remainPackageCount; //當(dāng)前剩余的紅包數(shù)

std::vector《struct receiveRecord》 records; //已經(jīng)搶完的記錄

ONTLIB_SERIALIZE( EnvelopeStruct, (tokenAddress)(totalAmount)(totalPackageCount)(remainAmount)(remainPackageCount)(records) )

};

其中,

ONTLIB_SERIALIZE(receiveRecord,(account)(amount))

是由 Ontology Wasm CDT 定義的宏操作,用于在將 struct 存儲前進(jìn)行序列化的操作。

2.2 創(chuàng)建紅包

準(zhǔn)備工作差不多了,下面我們開始開發(fā)具體的接口邏輯。

1. 創(chuàng)建紅包需要指定創(chuàng)建者地址, 紅包數(shù)量, 紅包金額和資產(chǎn)的合約地址:

bool createRedEnvelope(address owner,asset packcount, asset amount,address tokenAddr ){

return true;

}

2. 檢查是否有創(chuàng)建者的簽名, 否則交易回滾退出:

ontio_assert(check_witness(owner),“checkwitness failed”);

NOTE: ontio_assert(expr, errormsg):當(dāng) expr 為 false 時, 拋出異常并退出。

3. 如果紅包資產(chǎn)是 ONT,由于 ONT 的不可分割性(最小為1個 ONT), 紅包的金額要大于或等于紅包的數(shù)量,保證每個紅包最少有1個 ONT:

if (isONTToken(tokenAddr)){

ontio_assert(amount 》= packcount,“ont amount should greater than packcount”);

}

4. 對于每個紅包的創(chuàng)建者,我們需要記錄一下他發(fā)送紅包的總數(shù)量:

key sentkey = make_key(sentPrefix,owner.tohexstring());

asset sentcount = 0;

storage_get(sentkey,sentcount);

sentcount += 1;

storage_put(sentkey,sentcount);

5. 生成紅包 hash, 這個 hash 就是之后標(biāo)識這個紅包的唯一 ID:

H256 hash ;

hash256(make_key(owner,sentcount),hash) ;

key rekey = make_key(rePrefix,hash256ToHexstring(hash));

6. 根據(jù) token 資產(chǎn)的類型,將資產(chǎn)轉(zhuǎn)入合約中,self_address()可以取得當(dāng)前執(zhí)行的合約地址, 我們根據(jù)用戶輸入的 token 類型,將指定數(shù)量的 token 轉(zhuǎn)入合約:

address selfaddr = self_address();

if (isONTToken(tokenAddr)){

bool result = ont::transfer(owner,selfaddr ,amount);

ontio_assert(result,“transfer native token failed!”);

}else if (isONGToken(tokenAddr)){

bool result = ong::transfer(owner,selfaddr ,amount);

ontio_assert(result,“transfer native token failed!”);

}else{

std::vector《char》 params = pack(std::string(“transfer”),owner,selfaddr,amount);

bool res;

call_contract(tokenAddr,params, res );

ontio_assert(res,“transfer oep4 token failed!”);

}

NOTE 1:對于 ONT 和 ONG 這兩種原生資產(chǎn), Ontology Wasm CDT 提供了ont::transfer API 進(jìn)行轉(zhuǎn)賬操作;而 OEP-4類的資產(chǎn),需要按照普通的跨合約調(diào)用方法來轉(zhuǎn)賬。

NOTE 2:和普通的錢包地址一樣, 合約地址也可以接受任意類型的資產(chǎn)。但是合約地址是由合約編譯后的二進(jìn)制代碼 hash 產(chǎn)生的,所以沒有對應(yīng)的私鑰,也就無法隨意操作合約中的資產(chǎn),如果你沒有在合約中設(shè)置對資產(chǎn)的操作,就意味著你將無法控制這部分資產(chǎn)。

7. 將合約的信息保存在存儲中:

struct EnvelopeStruct es ;

es.tokenAddress = tokenAddr;

es.totalAmount = amount;

es.totalPackageCount = packcount;

es.remainAmount = amount;

es.remainPackageCount = packcount;

es.records = {};

storage_put(rekey, es);

8. 發(fā)送創(chuàng)建紅包的事件。對于智能合約的調(diào)用是一個異步的過程,合約會在執(zhí)行成功后發(fā)送一個事件來通知客戶端執(zhí)行結(jié)果,這個事件的格式可以由合約的編寫者來指定。

char buffer [100];

sprintf(buffer, “{”states“:[”%s“, ”%s“, ”%s“]}”,“createEnvelope”,owner.tohexstring().c_str(),hash256ToHexstring(hash).c_str());

notify(buffer);

return true;

一個簡單的紅包就創(chuàng)建完成了, 下一步我們需要實現(xiàn)如何查詢這個紅包的信息。

2.3 查詢紅包

查詢紅包的邏輯非常簡單, 只需要將存儲中的紅包信息取出并格式化返回即可:

std::string queryEnvelope(std::string hash){

key rekey = make_key(rePrefix, hash);

struct EnvelopeStruct es;

storage_get(rekey, es);

return formatEnvelope(es);

}

NOTE:對于智能合約的只讀操作(例如查詢), 可以通過預(yù)執(zhí)行(pre-exec)來讀取結(jié)果。不同于普通的合約調(diào)用,預(yù)執(zhí)行不需要錢包的簽名,同時也就無需花費(fèi) ONG。最后,其他用戶可以根據(jù) hash(紅包的 ID)來領(lǐng)?。〒專┻@個紅包了。

2.4 領(lǐng)取紅包

我們已經(jīng)把資產(chǎn)成功地轉(zhuǎn)入到智能合約中了, 接下來就可以把這個紅包的 ID 發(fā)送給你的朋友們讓他們?nèi)尲t包了。

1. 領(lǐng)取紅包需要輸入領(lǐng)取人的賬戶和紅包的hash:

bool claimEnvelope(address account, std::string hash){

return true;

}

2. 同樣, 我們需要驗證領(lǐng)取賬戶的簽名, 不允許替其他人搶紅包, 而且每個賬戶每個紅包只能搶一次:

ontio_assert(check_witness(account),“checkwitness failed”);

key claimkey = make_key(claimPrefix,hash,account);

asset claimed = 0 ;

storage_get(claimkey,claimed);

ontio_assert(claimed == 0,“you have claimed this Envelope!”);

3. 按照 hash 從存儲中取出紅包的信息, 判斷這個紅包是否沒有被搶完:

key rekey = make_key(rePrefix,hash);

struct EnvelopeStruct es;

storage_get(rekey,es);

ontio_assert(es.remainAmount 》 0, “the Envelope has been claimed over!”);

ontio_assert(es.remainPackageCount 》 0, “the Envelope has been claimed over!”);

4. 新建一條領(lǐng)取的記錄:

struct receiveRecord record ;

record.account = account;

asset claimAmount = 0;

5. 計算本次領(lǐng)取紅包的資產(chǎn)數(shù)量。如果是最后一個紅包, 數(shù)量為剩余的金額, 否則根據(jù)當(dāng)前區(qū)塊 hash 計算隨機(jī)數(shù),確定本次領(lǐng)取的數(shù)量, 并更新紅包信息:

if (es.remainPackageCount == 1){

claimAmount = es.remainAmount;

record.amount = claimAmount;

}else{

H256 random = current_blockhash() ;

char part[8];

memcpy(part,&random,8);

uint64_t random_num = *(uint64_t*)part;

uint32_t percent = random_num % 100 + 1;

claimAmount = es.remainAmount * percent / 100;

//ont case

if (claimAmount == 0){

claimAmount = 1;

}else if(isONTToken(es.tokenAddress)){

if ( (es.remainAmount - claimAmount) 《 (es.remainPackageCount - 1)){

claimAmount = es.remainAmount - es.remainPackageCount + 1;

}

}

record.amount = claimAmount;

}

es.remainAmount -= claimAmount;

es.remainPackageCount -= 1;

es.records.push_back(record);

6. 根據(jù)計算結(jié)果, 將對應(yīng)資產(chǎn)從合約中轉(zhuǎn)到領(lǐng)取的賬戶:

address selfaddr = self_address();

if (isONTToken(es.tokenAddress)){

bool result = ont::transfer(selfaddr,account ,claimAmount);

ontio_assert(result,“transfer ont token failed!”);

} else if (isONGToken(es.tokenAddress)){

bool result = ong::transfer(selfaddr,account ,claimAmount);

ontio_assert(result,“transfer ong token failed!”);

} else{

std::vector《char》 params = pack(std::string(“transfer”),selfaddr,account,claimAmount);

bool res = false;

call_contract(es.tokenAddress,params, res );

ontio_assert(res,“transfer oep4 token failed!”);

}

7. 記錄領(lǐng)取的信息, 將更新后的紅包信息寫回存儲并發(fā)送通知事件:

storage_put(claimkey,claimAmount);

storage_put(rekey,es);

char buffer [100];

std::sprintf(buffer, “{”states“:[”%s“,”%s“,”%s“,”%lld“]}”,“claimEnvelope”,hash.c_str(),account.tohexstring().c_str(),claimAmount);

notify(buffer);

return true;

如前面所說,這個合約只能通過 claimEnvelope 這個接口將資產(chǎn)轉(zhuǎn)出合約。所以,合約中的資產(chǎn)是安全的,任何人都無法隨意的取走里面的資產(chǎn)。至此, 一個簡單的紅包合約邏輯完成, 完整的合約代碼如下: https://github.com/JasonZhouPW/pubdocs/blob/master/redEnvelope.cpp

2.5 合約測試

合約測試可以有兩種方法:

1. 使用 CLI

請參考:https://github.com/ontio/ontology-wasm-cdt-cpp/blob/master/How_To_Run_ontologywasm_node.md

2. 使用 Golang SDK

請參考:https://github.com/ontio/ontology-wasm-cdt-cpp/blob/master/example/other/main.go

三、總結(jié)

本示例只是為了展示如何編寫一個完整的 Ontology Wasm 智能合約, 如何通過調(diào)用 API 和底層的區(qū)塊鏈進(jìn)行交互。如果要作為正式的產(chǎn)品, 還需要解決紅包的隱私問題: 所有人都可以通過監(jiān)控合約的事件來取得紅包的 hash, 意味著每個人都可以搶這個紅包。一種比較簡單的解決方法,就是在創(chuàng)建紅包時指定哪些賬戶能夠領(lǐng)取。如果有興趣, 您也可以嘗試修改測試一下。

Ontology 作為領(lǐng)先公鏈,率先支持 Wasm 合約,為 Wasm 技術(shù)的成熟貢獻(xiàn)自己的一份力量。我們歡迎更多的 Wasm 技術(shù)愛好者加入本體開發(fā)社區(qū),共同打造技術(shù)生態(tài)。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉