今天咱們推出了一個全新的系列,Hacking the Blockchain!它適用於剛剛開始開發EOSIO的全部開發人員。它也適用於全部EOS Blockchain愛好者,他們不是徹底技術性的,但想要搞清楚該技術的工做原理。git
在每篇文章中,咱們將探討區塊鏈的特定部分。咱們從EOS通訊模型開始,但願能堅持下去!github
今天,咱們將探索EOS通訊模型。咱們將深刻探討不一樣類型的溝通模式和行動。對於dessert,咱們將看到如何在咱們的代碼中使用它,並在咱們要開發一個自動化的演示中使用它。編程
但首先,讓咱們從EOS智能合約的內容開始。這將奠基基礎。架構
每一個EOS智能合約都有一組操做和類型。action
表示單個操做。你能夠將其視爲JavaScript中的函數或C#中的方法。type
定義合約中使用的所需內容和結構。大多數時候咱們將它們用於咱們的表。函數
EOSIO中的合約能夠相互通訊。它是經過基於消息的通訊架構實現的。工具
EOS通訊模型就是他們溝通的方式。通訊模型有兩種類型:Inline Communication Model(內聯通訊模型)和Deferred Communication Model(延時通訊模型)。區塊鏈
內聯操做是內聯通訊模型的一部分。若是你瞭解它們,就能理解內聯通訊。this
咱們來看看下圖:翻譯
用戶從智能合約A執行操做(Action #1)。當操做開始執行時,它會觸發另外兩個操做:來自智能合約B的操做Action #1.1和來自智能合約C的操做Action #1.2。一切都在當前交易中完成。3d
在當前交易中執行並與其完成相關的操做,稱爲inline action
即內聯操做。
重要的是要記住內聯操做是做爲調用操做的一部分執行的。所以,它們與原始交易的範圍和權限相同。這是他們將被執行的保證。若是其中一個操做失敗,則整個交易將失敗。
因此,你應該已經知道內聯通訊是什麼意思了吧。
請求將執行操做做爲調用操做的一部分是inline communication
即內聯通訊的示例。
第二種類型是延時通訊模型。表示模型的延時操做很是有趣,由於它們不在同一交易中執行。咱們來看看下圖:
咱們有相同的交易工做流程。這裏惟一的區別是從智能合約C執行的第二個操做不是內聯而是延時。延時操做計劃在未來運行。
根據生產者的判斷,延時的操做最好能夠安排在稍後的時間運行。沒法保證延期操做將執行。
即便它們不屬於同一交易,它們也具備發送它們的合約的權限。
因此基本上,延時通訊在概念上採用發送給對等交易的操做通知的形式。
在繼續演示以前,讓咱們檢查一些有趣的東西。
在EOSIO中,交易和操做之間存在差別。操做表示單個操做,而交易是一個或多個操做的集合。
交易能夠包含N個操做。可是,每一個交易必須在30ms或更短
的時間內執行。若是交易包含多個操做,而且這些操做的總和大於30毫秒,則整個交易將失敗。
咱們要作個機器人。你能夠在咱們的GitHub中找到包含全部智能合約和代碼的項目。
做爲一家創造將來的機器人公司,咱們但願一切都是完美的。新建新的機器人時,應發送出售信息,並在終端上打印相關信息。爲了實現這三個操做,咱們將使用內聯操做。
看一下下面的代碼片斷。
void RobotFactory::create(account_name account, robot newRobot) { robotIndex robots(_self, _self); auto iterator = robots.find(newRobot.series_number); eosio_assert(iterator == robots.end(), "Robot with this series number already exists"); robots.emplace(account, [&](auto& robot) { robot.series_number = newRobot.series_number; robot.model = newRobot.model; robot.operating_system = newRobot.operating_system; robot.profession = newRobot.profession; robot.owner = name{account}.to_string(); robot.manufactured = now(); }); // Execute INLINE ACTION from another contract // action({permission_level}, {contract_deployer}, {contract_action}, {data_to_pass}).send(); action(permission_level(account, N(active)), N(market), N(forsale), make_tuple(account, newRobot.series_number, newRobot.model, newRobot.manufactured )).send(); // Execute INLINE ACTION from another contract // action({permission_level}, {contract_deployer}, {contract_action}, {data_to_pass}).send(); action(permission_level(account, N(active)), N(messenger), N(printmessage), make_tuple(newRobot.model)).send(); }
首先,咱們開始建立一個新的機器人。操做完成後,它將出現第一個內聯操做。咱們讓發送機器人一個出售信息,因此咱們要求RobotMarketplace
智能合約的forsale
。
請注意,當咱們要求智能合約A從智能合約B執行操做時,應首先添加適當的權限。咱們將在下一部分介紹,目前,請務必遵循README.md中的指南。
第一個內聯操做完成後,第二個內聯操做就會完成。此次咱們從Messenger
智能合約中請求printmessage
。 一樣應該添加適當的權限。
在這兩種狀況下,當咱們經過終端執行建立操做時,咱們已收到操做已完成(或失敗)的通知。
cleos push action weyland create '{"account":"weyland","newRobot":{"series_number":14441992,"model":"A330","operating_system":"DX42","profession":"engineer","owner":"","manufactured":0}}' -p weyland executed transaction: 9874a8a5f516ca540c44cafd8b9b371c856fe7958be1fc6268641cc7ab67fdaf 136 bytes 6000 us # weyland <= weyland::create {"account":"weyland","newRobot":{"series_number":14441992,"model":"A330","operating_system":"DX42",... # market <= market::forsale {"account":"weyland","robotForSale":{"series_number":14441992,"model":"A330","manufactured":0}} # messenger <= messenger::printmessage {"message":"A330"} >> ==== For sale | Robot model: A330
讓咱們將printmessage
操做從內聯更改成延時。爲此,咱們須要使用EOSIO的transaction.hpp
標頭。
void RobotFactory::create(account_name account, robot newRobot) { robotIndex robots(_self, _self); auto iterator = robots.find(newRobot.series_number); eosio_assert(iterator == robots.end(), "Robot with this series number already exists"); robots.emplace(account, [&](auto& robot) { robot.series_number = newRobot.series_number; robot.model = newRobot.model; robot.operating_system = newRobot.operating_system; robot.profession = newRobot.profession; robot.owner = name{account}.to_string(); robot.manufactured = now(); }); // Execute inline action from another contract // action({permission_level}, {contract_deployer}, {contract_action}, {data_to_pass}).send(); action(permission_level(account, N(active)), N(market), N(forsale), make_tuple(account, newRobot.series_number, newRobot.model, newRobot.manufactured )).send(); // Execute DEFERRED ACTION from another contract eosio::transaction tx; tx.actions.emplace_back(permission_level{account, N(active)}, N(messenger), N(printmessage), make_tuple(newRobot.model)); tx.delay_sec = 12; tx.send(N(newRobot.model), account); }
要建立延時交易,咱們首先從類型交易聲明一個變量tx
。而後咱們在其操做集合中添加一個新操做。咱們能夠選擇設置延時。若是它爲0,則延時交易將在調用以後當即進行。
設置完全部後,咱們只需調用send方法便可。
可是,不保證將執行延時交易。此外,咱們不會像在內聯操做中那樣收到有關其成功或失敗的任何通知。
cleos push action weyland1 create '{"account":"weyland1","newRobot":{"series_number":14441993,"model":"A330","operating_system":"DX42","profession":"engineer","owner":"","manufactured":0}}' -p weyland1 executed transaction: 5f45b48877aac9d03172616a2443b7a9079ee9f74a124a0976d2fcf0b756e985 176 bytes 2722 us # weyland1 <= weyland1::create {"account":"weyland1","newRobot":{"series_number":14441993,"model":"A330","operating_system":"DX42",... # market <= market::forsale {"account":"weyland1","robotForSale":{"series_number":14441993,"model":"A330","manufactured":0}} # No notification for printmessage action
正如你在12秒後看到的那樣,執行延時交易。
總結一下它們是EOS中的兩種通訊模型:內聯和延時。內聯通訊期間使用的操做稱爲內聯操做,在延時通訊中使用時稱爲延時操做。
分享一個EOS區塊鏈相關的交互式在線編程實戰教程:
EOS教程,本課程幫助你快速入門EOS區塊鏈去中心化應用的開發,內容涵蓋EOS工具鏈、帳戶與錢包、發行代幣、智能合約開發與部署、使用代碼與智能合約交互等核心知識點,最後綜合運用各知識點完成一個便籤DApp的開發。
匯智網原創翻譯,轉載請標明出處。這裏是原文EOS區塊鏈的通訊模型