EOS 智能合約案例解析(2)
詳解 EOS 智能合約的 cpp 文件
之前的文章介紹了 eosio.token 智能合約的 hpp 文件,這次向大家介紹 eosio.token.cpp 文件,cpp 文件即 C++ 代碼文件,智能合約所有的業務邏輯內容都是在 cpp 文件中實現的。
eosio.token.cpp 文件地址: https://github.com/EOSIO/eos/blob/master/contracts/eosio.token/eosio.token.cpp
了解 C/C++ 開發的同學肯定熟悉,cpp 文件的主要使命是實現 hpp 文件中聲明的函數(方法),包括公有函數(EOS 裏也叫 action)和私有函數。hpp 裏挖的坑,cpp 要一個不留地實現。
私有函數
照慣例,私有函數都是工具函數,供類內部的其他函數調用。
sub_balance(減資產)函數
作用:從指定賬戶中減去資產
參數:被操作賬戶,資產數,資產狀態
// 參數:被操作賬戶 資產種類與數量 資產狀態結構體void token::sub_balance( account_name owner, asset value, const currency_stats& st ) { //建立一個 multi_index,用來操作數據庫 //這裏的參數 _self 表示數據的擁有者為智能合約本身,參數 owner 表示儲存在名為被操作賬戶的表中 //這樣並不是直接建立了一個新表,而是讓 C++ 程序與數據庫對應的表之間建立了數據傳輸的通道 accounts from_acnts( _self, owner ); //在數據表中查詢要減少的代幣結構體,就是 hpp 文件中定義的 account 結構體 const auto& from = from_acnts.get( value.symbol.name() ); //校驗,要減少的代幣數量應該小於目前擁有的代幣數量,否則會報錯。 eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); //判斷是否有被操作賬戶的授權 if( has_auth( owner ) ) { //校驗,賬戶是否被凍結 eosio_assert( !st.can_freeze || !from.frozen, "account is frozen by issuer" ); //校驗,這種代幣是否被凍結 eosio_assert( !st.can_freeze || !st.is_frozen, "all transfers are frozen by issuer" ); //校驗,賬戶是否在白名單中 eosio_assert( !st.enforce_whitelist || from.whitelist, "account is not white listed" ); //如果沒有被操作賬戶的授權,檢查是否有發幣者的授權 } else if( has_auth( st.issuer ) ) { //如果有發幣者的授權,那麽肯定是在召回代幣,查看代幣是否可以召回 eosio_assert( st.can_recall, "issuer may not recall token" ); } else { //如果兩種授權都沒有,則失敗,沒有足夠的權限 eosio_assert( false, "insufficient authority" ); } //通過 Lambda 表達式(匿名函數)修改將代幣結構體 from_acnts.modify( from, owner, [&]( auto& a ) { //匿名函數 函數體 a.balance -= value; }); }
add_balance(增加資產)函數
作用:從指定賬戶中增加資產
參數:被操作賬戶,資產數,資產狀態,存儲資源支付賬戶
// 參數:被操作賬戶 代幣數量 代幣狀態結構體 儲存支付賬戶void token::add_balance( account_name owner, asset value, const currency_stats& st, account_name ram_payer ) { //建立一個 multi_index,用來操作數據庫 accounts to_acnts( _self, owner ); //在數據表中查詢要增加的代幣結構體 auto to = to_acnts.find( value.symbol.name() ); //如果 to == to_acnts.end(),說明查找到數據表的末尾都沒有對應的結構體,說明該賬戶沒有該代幣 if( to == to_acnts.end() ) { //校驗,該代幣是否開啟了白名單功能 eosio_assert( !st.enforce_whitelist, "can only transfer to white listed accounts" ); //使用 emplace 方法,在數據表中增加一項 to_acnts.emplace( ram_payer, [&]( auto& a ){ //匿名函數體,代幣數量等於每次轉入的數量,因為之前沒有 a.balance = value; }); //如果數據表中已經存在此項,只需增加代幣數量 } else { //檢查賬戶是否在白名單中 eosio_assert( !st.enforce_whitelist || to->whitelist, "receiver requires whitelist by issuer" ); //使用 modify 方法,修改項目 to_acnts.modify( to, 0, [&]( auto& a ) { //直接修改代幣數量 a.balance += value; }); } }
公有函數
EOS 合約中的公有函數大多是供別的賬戶調用的 Action,根據 hpp 文件,我們需要實現 create、issue、transfer 三個公有函數(action)。
create(新建代幣)函數
create 函數用來創建一種新的代幣,並設置這種新代幣的各種參數。
//參數:發幣賬戶void token::create( account_name issuer, //最大發行量 asset maximum_supply, //發幣者是否可以凍結代幣 uint8_t issuer_can_freeze, //發幣者是否可以召回代幣 uint8_t issuer_can_recall, //是否可以設置白名單 uint8_t issuer_can_whitelist ) { //需要 eosio.token 賬戶本身的授權 require_auth( _self ); auto sym = maximum_supply.symbol; //校驗,新代幣名稱是否有效 eosio_assert( sym.is_valid(), "invalid symbol name" ); //校驗,最大發行量是否有效 eosio_assert( maximum_supply.is_valid(), "invalid supply"); //校驗,最大發行量是否大於零 eosio_assert( maximum_supply.amount > 0, "max-supply must be positive"); //建立一個 milti_index 數據表,用來與數據庫交互 stats statstable( _self, sym.name() ); //在表中搜索相同名稱的代幣 auto existing = statstable.find( sym.name() ); //校驗,是否已經存在相同名稱的代幣 eosio_assert( existing == statstable.end(), "token with symbol already exists" ); //使用 emplace 方法,在數據表中增加一項 statstable.emplace( _self, [&]( auto& s ) { // 使用匿名函數,將傳入的參數賦值給 currency_stats 結構體 s.supply.symbol = maximum_supply.symbol; s.max_supply = maximum_supply; s.issuer = issuer; s.can_freeze = issuer_can_freeze; s.can_recall = issuer_can_recall; s.can_whitelist = issuer_can_whitelist; }); }
transfer(轉賬)函數
transfer 應該是這個智能合約最常用的函數,就是將代幣從一個賬戶轉到另一個。
//轉出方賬戶名void token::transfer( account_name from, //轉入方賬戶名 account_name to, //代幣種類與數量 asset quantity, //轉賬備忘(目前還沒實現) string /*memo*/ ) { //打印轉賬提示 print( "transfer" ); //檢查轉出方權限 require_auth( from ); //得到代幣名稱 auto sym = quantity.symbol.name(); //建立一個 milti_index 數據表,用來與數據庫交互 stats statstable( _self, sym ); //在數據表中尋找代幣的 currency_stats 結構體 const auto& st = statstable.get( sym ); //向轉出方獲取回執 require_recipient( from ); //向轉入方獲取回執 require_recipient( to ); //校驗,轉出的代幣是否有效 eosio_assert( quantity.is_valid(), "invalid quantity" ); //校驗,轉賬數量要大於0 eosio_assert( quantity.amount > 0, "must transfer positive quantity" ); //調用 sub_balance 私有方法 sub_balance( from, quantity, st ); //調用 add_balance 私有方法 add_balance( to, quantity, st, from ); }
issue(發幣)函數
上面的 create 函數創建代幣後只是給定了參數,並沒有真正的代幣被創建出來,需要 issue 函數進行發幣。
//參數:代幣接收方 代幣數量和種類 備忘void token::issue( account_name to, asset quantity, string memo ) { //打印提示 print( "issue" ); //獲取代幣名稱 auto sym = quantity.symbol.name(); //建立一個 milti_index 數據表,用來與數據庫交互 stats statstable( _self, sym ); //在數據表中搜索代幣 currency_stats 結構體 const auto& st = statstable.get( sym ); //檢查發幣者授權 require_auth( st.issuer ); //檢查資產是否有效 eosio_assert( quantity.is_valid(), "invalid quantity" ); //檢查資產是否大於零 eosio_assert( quantity.amount > 0, "must issue positive quantity" ); //檢查創造的總資產是否大於最大代幣數 eosio_assert( quantity <= st.max_supply - st.supply, "quantity exceeds available supply"); //更新資產創造數量記錄 statstable.modify( st, 0, [&]( auto& s ) { s.supply += quantity; }); //給發布者增加資產 add_balance( st.issuer, quantity, st, st.issuer ); //判斷代幣接受方是否是發幣者 if( to != st.issuer ) { //這裏使用了一個特殊處理,先給發幣者增加相應的代幣,再調用 transfer 函數轉賬給代幣接受方。 //這樣做的目的是讓代幣接受方收到通知 SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); } }
設置 action
大家知道 EOS 系統的智能合約是以 action 為基本動作單位的,我們要將需要聲明為 action 的函數告知 EOS 系統,通過以下宏即可實現。
//將 create issue transfer 三個共有函數聲明為 action,供其他賬戶調用。EOSIO_ABI( eosio::token, (create)(issue)(transfer) )
EOS 智能合約案例解析(2)
相關推薦
EOS 智能合約案例解析(2)
EOS 智能合約詳解 EOS 智能合約的 cpp 文件之前的文章介紹了 eosio.token 智能合約的 hpp 文件,這次向大家介紹 eosio.token.cpp 文件,cpp 文件即 C++ 代碼文件,智能合約所有的業務邏輯內容都是在 cpp 文件中實現的。eosio.token.cpp 文件地址:
EOS 智能合約案例解析(3)
EOS 智能合約詳解 EOS 智能合約的 abi 文件這次向大家介紹 eosio.token 智能合約的最後一個文件 —— abi文件。ABI 全稱 Application Binary Interface,中文名“應用程序二進制接口”,顧名思義是一個接口文件,描述了智能合約與上層應用之間的數據交換格式。ab
EOS智能合約案例解析(1)
EOS智能合約為了幫助大家熟悉 EOS 智能合約,EOS 官方提供了一個代幣(資產)智能合約 Demo —— eosio.token。eosio.token 智能合約目前還不是特別完善,個別功能還沒有完成。但這個示例合約給出了 EOS 官方智能合約開發的標準結構和開發方法,並且真正的 EOS 代幣也會借鑒這個
EOS智能合約授權限制和數據存儲
shu imageview author start clas strip -i eache 效果 EOS智能合約授權限制和數據存儲 在EOS合約中,調用合約需要來自賬戶的授權,同時還要指定需要調用的動作。當然,有的合約並不是所有賬戶都可以調用的,這就需要用到授權限制。接
EOS智能合約與DApp開發入門教程
EOS 智能合約 DApp 開發 入門 教程 EOS的是Block.One主導研發的一個區塊鏈底層公鏈系統,它專門為支撐商業去中心化應用(Decentralized Application)而設計,其代碼開源。 比特幣被稱為區塊鏈1.0,因為它開辟了數字
以太坊去中心化淘寶智能合約案例
安全 中國 重置 枚舉 是什麽 出現 功能 received 支付寶 篇文章我們來介紹一個簡易的區塊鏈電商系統的核心功能,10多年來,我們習慣了淘寶的電商模式,淘寶為電商在中國普及做出了突出貢獻,值得肯定,也完成了歷史使命。 淘寶模式的核心是什麽? 免
智能合約語言 Solidity 教程系列2 - 地址類型介紹
區塊鏈 智能合約 Solidity教程系列第二篇 - Solidity地址類型介紹. Solidity 系列完整的文章列表請查看分類-Solidity。 寫在前面 Solidity是以太坊智能合約編程語言,閱讀本文前,你應該對以太坊、智能合約有所了解,如果你還不了解,建議你先看以太坊是什麽 本文前半部
OKEX智能合約交易平臺系統解析
company limited 企業 投資 穩定 個人 平時 多媒體 平臺 說到區塊鏈,首先不得不提的是比特幣,區塊鏈能夠在今天達到眾人皆知的地位,主要歸功於一個叫中本聰的老兄創造了比特幣,並賦予比特幣以金融價值,這才引得世人癲狂。你想想啊,前幾年的比特幣無人搭理,慢慢地能
通過一個案例精通以太坊智能合約和Solidity
perm 讀寫 編譯 nap utf-8 index listen eip 散列函數 作者介紹 Silver CEO 星際區塊鏈信息發展有限公司 項目組件 ??這個項目是一個構建在以太坊上的遊戲,感謝這個團隊給我們提供的案例:https://cryptozombies.io
第一行代碼:以太坊(2)-使用Solidity語言開發和測試智能合約
之一 腳本語言 其他 括號 add row ans img 運行方式 智能合約是以太坊的核心之一,用戶可以利用智能合約實現更靈活的代幣以及其他DApp。不過在深入講解如何開發智能合約之前,需要先介紹一下以太坊中用於開發智能合約的Solidity語言,以及相關的開發和測試環境
基於Linux的智能家居的設計(2)
數據交互 mod class 類庫 nbsp man linux系統 單片機 popu 1 系統整體設計方案 智能家居系統的是一個實時查詢家庭的溫濕度、照明控制、自己主動控制的設定。集家庭娛樂、智能安防為一體,大量數據快處理、可靠的系統,因此在硬件和軟件上都有非常大
區塊鏈入門(5)Truffle 項目實戰,Solidity IDE, 智能合約部署
第四章 margin 其中 exports nba 接口 ive 另一個 date 在上一張我們學習了Truffle項目的創建,部署等相關內容,今天我們就來實戰一下. 今天我們要做3件事: 1) 學習搭建一個Solidity IDE(Remix).
Solidity編程 四 之 智能合約的結構
以及 function imp class 以太坊 str end reat sender Solidity的智能合約和面向對象語言中的類很相似。每個智能合約可以包含的元素有:state變量的定義,方法,函數修改器,事件,結構類型以及枚舉類型。同時合約可以繼承於另外一個
使用Go語言與Ethereum智能合約進行交互
程序 nes ack 產生 back -a 可能 ner 進行 盡管最近出現了麻煩,但Ethereum仍然是區塊鏈空間中實現智能合約最重要的系統,而且這種情況似乎不太可能很快改變。 在我看來,技術本身具有很大的潛力,從學術的角度來看是非常有趣的,但正如前面提到的問題,之前展
CPS智能合約系統開發區塊鏈新思維
應用 參與 所有 平臺 虛擬機 框架類 lang c++ .net框架 經常有同學會在.NET、C#和ASP.NET這三者之間區別不清楚,到底它們之間有什麽聯系呢?在這裏我給大家歸納如下: 1、.NET是一個平臺,一個抽象的平臺的概念。 .
智能合約語言 Solidity 教程系列5 - 數組介紹
編程 class 參數 == logs erro arrays hang push 寫在前面 Solidity 是以太坊智能合約編程語言,閱讀本文前,你應該對以太坊、智能合約有所了解, 如果你還不了解,建議你先看以太坊是什麽 本文前半部分是參考Solidity官方文檔(當前
Hyperledger Fabric Chaincode是什麽,智能合約是什麽
eas https erl 應用 運行 支持 pos 編程語言 type 首先看下Blockchain結構,除了header指向下一個block的hash value外,block是由一組transaction構成, Transactions --> Blocks -
智能合約語言 Solidity 教程系列7 - 以太單位及時間單位
hal 技術交流 ont zab 變量 nic 我們 oracle variables 這是Solidity教程系列文章第7篇介紹以太單位及時間單位,系列帶你全面深入理解Solidity語言。 寫在前面 Solidity 是以太坊智能合約編程語言,閱讀本文前,你應該對以太
以太坊Crypto Countries加密國家火爆,區塊鏈遊戲成智能合約應用探索突破口
場景 好的 交換 系統 trie 發的 ebr 可用 tar 繼加密貓(CryptoKitties)之後,以太坊上又出現了幾款火爆的區塊鏈遊戲,它們是CryptoCountries,Crypto-All Stars,CryptoCelebrities和EtherBots。
以太坊私有鏈下智能合約部署
配置文件 臺電腦 問題: != 第一步 attribute int lock asc 上一篇文章實現了搭建私有鏈,以下進行智能合約的部署 一、 編寫合約 簡單的乘法例子: pragma solidity ^0.4.2; contract test { functio