真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎樣理解eos區(qū)塊鏈的eosio.token合約

今天就跟大家聊聊有關(guān)怎樣理解eos區(qū)塊鏈的eosio.token合約,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:空間域名、虛擬主機(jī)、營(yíng)銷軟件、網(wǎng)站建設(shè)、都蘭網(wǎng)站維護(hù)、網(wǎng)站推廣。

我必須承認(rèn),學(xué)習(xí)eosio一直沒有閑庭信步的感覺,我可以看到為什么很多人說它有一個(gè)陡峭的學(xué)習(xí)曲線。隨著eosio軟件繼續(xù)經(jīng)歷大量快速發(fā)展,文檔數(shù)量有限,很少有工作實(shí)例可供參考。我已經(jīng)被困了好幾次,也希望幫助改善下一個(gè)開發(fā)人員的體驗(yàn)。

什么是eosio.token合約?

eosio.token合約允許創(chuàng)建許多不同的代幣。這使任何人都能夠創(chuàng)建和發(fā)送代幣。每個(gè)代幣必須由issuer帳戶發(fā)行。由于帳戶可以包含多方,因此你可以使用具有所有者和活動(dòng)權(quán)限的普通帳戶或自定義配置帳戶來創(chuàng)建和管理代幣。每個(gè)代幣都是asset類型,如下所示:

1000000000.0000 SYS

1.0000 SYMBOL

0.10 SYS

asset類型是一個(gè)數(shù)字(如果我沒記錯(cuò)的話可以達(dá)到18位小數(shù))和一個(gè)可以在1-7個(gè)大寫字母之間的符號(hào)。此合約有三個(gè)操作可用于與之交互。它們是:創(chuàng)建,發(fā)布和轉(zhuǎn)賬。

創(chuàng)建用于定義新代幣的特征。這包括代幣asset符號(hào),最大供應(yīng)量以及允許發(fā)出代幣的帳戶。創(chuàng)建還會(huì)將新代幣配置保留在區(qū)塊鏈上。這意味著新代幣配置的存儲(chǔ)必須由某人放置。正如你稍后將看到的,部署此合約的帳戶(在我們的案例中為'eosio.token')也將支付代幣配置存儲(chǔ)。

發(fā)布用于增加代幣的有效供應(yīng)??梢猿掷m(xù)發(fā)出代幣,直到達(dá)到最大供應(yīng)量。在代幣創(chuàng)建期間定義的issuer必須批準(zhǔn)此操作才能使其成功。

轉(zhuǎn)賬讓一個(gè)帳戶將代幣轉(zhuǎn)移到另一個(gè)帳戶。

部署合約

你應(yīng)該知道的第一件事是每個(gè)eosio智能合約都屬于一個(gè)eosio帳戶。合約基本上是其他帳戶可以與之交互的對(duì)象。合約包含在區(qū)塊鏈上執(zhí)行代碼的操作actions。合約可以直接訪問區(qū)塊鏈上的存儲(chǔ),刪除和更新數(shù)據(jù)。

將一個(gè)action推送到合約需要至少一個(gè)帳戶的授權(quán)。根據(jù)合約的復(fù)雜性,可能需要進(jìn)一步的帳戶和權(quán)限。帳戶可以由基于權(quán)限的配置中設(shè)置的單個(gè)或多個(gè)個(gè)人組成。智能合約只能由一個(gè)帳戶運(yùn)行,而一個(gè)帳戶只能擁有一個(gè)智能合約。最佳做法是為帳戶和合約提供相同(小寫)的名稱。

在你與eosio.token合約進(jìn)行交互之前,你需要?jiǎng)?chuàng)建一個(gè)具有相同名稱的帳戶,并將合約部署到該帳戶。

首先創(chuàng)建一個(gè)帳戶

$cleos create account eosio eosio.token  

然后編譯合約

$cd eos/contract/eosio.token

$eosiocpp -o eosio.token.wast eosio.token.cpp

最后將合約部署到帳戶上

$cleos set contract eosio.token ../eosio.token

你可以驗(yàn)證合約是否已部署

$cleos get code eosio.token

合約架構(gòu)

合約分為兩個(gè)文件eosio.token.cppeosio.token.hpp。.hpp文件定義合約類,操作和表,而.cpp文件實(shí)現(xiàn)操作邏輯。讓我們首先看一下將用于實(shí)例化合約對(duì)象的合約類。(我從eosio.token.hpp中刪除了一些遺留代碼)

/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#pragma once

#include 
#include 

#include 

namespace eosiosystem {
   class system_contract;
}

namespace eosio {

   using std::string;

   class token : public contract {
      public:
         token( account_name self ):contract(self){}

         void create( account_name issuer,
                      asset        maximum_supply);

         void issue( account_name to, asset quantity, string memo );

         void transfer( account_name from,
                        account_name to,
                        asset        quantity,
                        string       memo );

      private:

         friend eosiosystem::system_contract;

         inline asset get_supply( symbol_name sym )const;

         inline asset get_balance( account_name owner, symbol_name sym )const;

         struct account {
            asset    balance;

            uint64_t primary_key()const { return balance.symbol.name(); }
         };

         struct currency_stats {
            asset          supply;
            asset          max_supply;
            account_name   issuer;

            uint64_t primary_key()const { return supply.symbol.name(); }
         };

         typedef eosio::multi_index accounts;
         typedef eosio::multi_index stats;

         void sub_balance( account_name owner, asset value );
         void add_balance( account_name owner, asset value, account_name ram_payer );

   };

   asset token::get_supply( symbol_name sym )const
   {
      stats statstable( _self, sym );
      const auto& st = statstable.get( sym );
      return st.supply;
   }

   asset token::get_balance( account_name owner, symbol_name sym )const
   {
      accounts accountstable( _self, owner );
      const auto& ac = accountstable.get( sym );
      return ac.balance;
   }

} /// namespace eosio

構(gòu)造函數(shù)和操作被定義為公共成員函數(shù)。構(gòu)造函數(shù)采用帳戶名稱(將是部署合約的帳戶,也就是eosio.token)并將其設(shè)置為contract變量。請(qǐng)注意,此類繼承自eosio::contract

表和helper函數(shù)作為私有成員提供。兩個(gè)內(nèi)聯(lián)函數(shù)在底部定義但從未使用過。這給我們留下了重要的函數(shù)sub_balance()add_balance()。這些將由轉(zhuǎn)移操作調(diào)用。

定義的兩個(gè)表是accountsstat。accounts表由不同的account對(duì)象組成,每個(gè)account對(duì)象持有不同代幣的余額。stat表由持有供應(yīng),max_supply和發(fā)行者的currency_stats對(duì)象(由struct currency_stats定義)組成。在繼續(xù)之前,重要的是要知道該合約將數(shù)據(jù)保存到兩個(gè)不同的范圍。accounts表的范圍限定為eosio帳戶,stat表的范圍限定為代幣符號(hào)名稱。

根據(jù)eosio::multi_index定義,code是具有寫權(quán)限的帳戶的名稱,scope是存儲(chǔ)數(shù)據(jù)的帳戶。

范圍本質(zhì)上是一種在合約中劃分?jǐn)?shù)據(jù)的方法,以便只能在定義的空間內(nèi)訪問。在代幣合約中,每個(gè)eosio帳戶都用作accounts表的范圍。accounts表是一個(gè)包含多個(gè)account對(duì)象的多索引容器。每個(gè)account對(duì)象都由其代幣符號(hào)編制索引,并包含代幣余額。使用其范圍查詢用戶的accounts表時(shí),將返回用戶具有現(xiàn)有余額的所有代幣的列表。

這是我如何想象它。

怎樣理解eos區(qū)塊鏈的eosio.token合約

在上圖中,有一個(gè)名為tom的eosio帳戶,他有自己的范圍。在他的范圍內(nèi)是一個(gè)名為accounts的表。在該表中是一個(gè)單獨(dú)的account對(duì)象,用于他持有的每個(gè)代幣,SYSEOS。

還有一個(gè)名為stat的第二個(gè)表。此表將包含現(xiàn)有代幣的狀態(tài)。新標(biāo)記在其自己的符號(hào)名稱范圍內(nèi)創(chuàng)建。范圍內(nèi)是一個(gè)包含currency_stats對(duì)象的stat表。與包含許多不同account對(duì)象的accounts表不同,stat表僅包含給定標(biāo)記符號(hào)的單個(gè)currency_stats對(duì)象。

怎樣理解eos區(qū)塊鏈的eosio.token合約

操作

操作在.cpp文件中實(shí)現(xiàn)。要?jiǎng)?chuàng)建新代幣,必須發(fā)送創(chuàng)建操作。Create有兩個(gè)參數(shù):發(fā)行者,以及新代幣的最大供應(yīng)量。issuer是唯一允許增加新代幣供應(yīng)的人。issuer不能超過最高供應(yīng)量發(fā)行。

怎樣理解eos區(qū)塊鏈的eosio.token合約

第一行代碼只需要合約帳戶本身的授權(quán)。這可以在推動(dòng)操作時(shí)使用命令行標(biāo)志-p eosio.token給出。

怎樣理解eos區(qū)塊鏈的eosio.token合約

接下來的幾行提取傳入的maximum_supply資產(chǎn)的符號(hào)并執(zhí)行一些錯(cuò)誤處理。如果任何eosio_assert失敗,那么所有代碼都將被回滾,并且交易不會(huì)被推送到區(qū)塊鏈。

怎樣理解eos區(qū)塊鏈的eosio.token合約

一個(gè)stat表使用符號(hào)名稱(標(biāo)記符號(hào))作為其范圍構(gòu)造為statstable。代碼檢查代幣是否已存在。如果沒有,則創(chuàng)建新代幣狀態(tài)并將其保存到區(qū)塊鏈中。emplace函數(shù)中的第一個(gè)參數(shù)_self意味著此合約帳戶eosio.token將支付投注存儲(chǔ)。

怎樣理解eos區(qū)塊鏈的eosio.token合約

請(qǐng)注意,保存supply的符號(hào),因?yàn)樗米鞫ㄎ槐硇械逆I,但供應(yīng)量尚未發(fā)出。

你現(xiàn)在可以執(zhí)行下一個(gè)操作,發(fā)布。發(fā)布將采用將收到已發(fā)行代幣的帳戶,發(fā)出的代幣數(shù)量和備忘錄。發(fā)布操作在一個(gè)中執(zhí)行兩個(gè)操作,因?yàn)樗鼘⑿薷膭?chuàng)建的代幣供應(yīng)并調(diào)用轉(zhuǎn)賬操作以發(fā)送已發(fā)布的代幣。同樣,前幾行提取代幣符號(hào)并執(zhí)行錯(cuò)誤檢查。

怎樣理解eos區(qū)塊鏈的eosio.token合約

以下代碼部分將使用符號(hào)名稱作為范圍構(gòu)造stat表。這用作查找先前使用create action創(chuàng)建的代幣的鍵。

怎樣理解eos區(qū)塊鏈的eosio.token合約

請(qǐng)注意,從statstable.find()返回的existing currency_stat是一個(gè)指向找到的對(duì)象的迭代器。為簡(jiǎn)潔起見,聲明了一個(gè)名為st的新變量,并將其設(shè)置為existing迭代器指向的實(shí)際對(duì)象。這讓我們可以使用.運(yùn)算符訪問成員變量而不是指針表示法->

創(chuàng)建代幣的issuer者需要簽署此交易,并執(zhí)行更多錯(cuò)誤處理。

怎樣理解eos區(qū)塊鏈的eosio.token合約

最后,修改現(xiàn)有代幣的currency_stats st,并將已發(fā)放的quantity添加到supply。issuer也將此supply添加到他們的余額中,以便初始供應(yīng)可以追溯到他們的帳戶。

怎樣理解eos區(qū)塊鏈的eosio.token合約

緊接著,通過SEND_INLINE_ACTION()調(diào)用transfer函數(shù),這會(huì)將資金進(jìn)行轉(zhuǎn)移。論點(diǎn)如下:

  • 1.*this是行動(dòng)所屬的合約代碼。

  • 2.transfer操作的名稱。

  • 3.{st.issuer, N(active)}操作所需的權(quán)限。

  • 4.{st.issuer, to, quantity, memo}操作本身的參數(shù)。

這將我們帶到最后的轉(zhuǎn)賬操作。轉(zhuǎn)賬操作將從from,to,quantitymemo獲取四個(gè)輸入?yún)?shù)。from是誰將發(fā)送代幣,因此quantity將從他們的余額中減去。to是誰將收到代幣,因此quantity將被添加到他們的余額。quantity是要發(fā)送的代幣數(shù)量,memo是一個(gè)可以與交易一起發(fā)送的字符串。memo未在本合約中使用或存儲(chǔ)。

該操作首先要求from accounts帳戶權(quán)限并對(duì)fromto帳戶執(zhí)行發(fā)布處理。該符號(hào)從quantity提取并用于獲取代幣的currency_stats。

怎樣理解eos區(qū)塊鏈的eosio.token合約

require_recipient()函數(shù)將在操作完成時(shí)通知發(fā)送方和接收方。

怎樣理解eos區(qū)塊鏈的eosio.token合約

完成更多發(fā)布處理,最后調(diào)用兩個(gè)私有函數(shù)sub_balance()add_balance()以從發(fā)送add_balance()減去代幣余額并增加接收方的代幣余額。

這是完整的'eosio.token.cpp'文件。

/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */

#include "eosio.token.hpp"

namespace eosio {

void token::create( account_name issuer,
                    asset        maximum_supply )
{
    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");

    stats statstable( _self, sym.name() );
    auto existing = statstable.find( sym.name() );
    eosio_assert( existing == statstable.end(), "token with symbol already exists" );

    statstable.emplace( _self, [&]( auto& s ) {
       s.supply.symbol = maximum_supply.symbol;
       s.max_supply    = maximum_supply;
       s.issuer        = issuer;
    });
}


void token::issue( account_name to, asset quantity, string memo )
{
    auto sym = quantity.symbol;
    eosio_assert( sym.is_valid(), "invalid symbol name" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );

    auto sym_name = sym.name();
    stats statstable( _self, sym_name );
    auto existing = statstable.find( sym_name );
    eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" );
    const auto& st = *existing;

    require_auth( st.issuer );
    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must issue positive quantity" );

    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply");

    statstable.modify( st, 0, [&]( auto& s ) {
       s.supply += quantity;
    });

    add_balance( st.issuer, quantity, st.issuer );

    if( to != st.issuer ) {
       SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} );
    }
}

void token::transfer( account_name from,
                      account_name to,
                      asset        quantity,
                      string       memo )
{
    eosio_assert( from != to, "cannot transfer to self" );
    require_auth( from );
    eosio_assert( is_account( to ), "to account does not exist");
    auto sym = quantity.symbol.name();
    stats statstable( _self, sym );
    const auto& st = statstable.get( sym );

    require_recipient( from );
    require_recipient( to );

    eosio_assert( quantity.is_valid(), "invalid quantity" );
    eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
    eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
    eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );


    sub_balance( from, quantity );
    add_balance( to, quantity, from );
}

void token::sub_balance( account_name owner, asset value ) {
   accounts from_acnts( _self, owner );

   const auto& from = from_acnts.get( value.symbol.name(), "no balance object found" );
   eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" );


   if( from.balance.amount == value.amount ) {
      from_acnts.erase( from );
   } else {
      from_acnts.modify( from, owner, [&]( auto& a ) {
          a.balance -= value;
      });
   }
}

void token::add_balance( account_name owner, asset value, account_name ram_payer )
{
   accounts to_acnts( _self, owner );
   auto to = to_acnts.find( value.symbol.name() );
   if( to == to_acnts.end() ) {
      to_acnts.emplace( ram_payer, [&]( auto& a ){
        a.balance = value;
      });
   } else {
      to_acnts.modify( to, 0, [&]( auto& a ) {
        a.balance += value;
      });
   }
}

} /// namespace eosio

EOSIO_ABI( eosio::token, (create)(issue)(transfer) )

示例命令:

$cleos push action eosio.token create '["usera","21000000.0000 DEMO"]' -p eosio.token usera 

$cleos push action eosio.token issue '["usera","21000000.0000 DEMO","issuance"]' -p usera 

$cleos push action eosio.token tranfser '["usera","userb","1000000.0000 DEMO","here you go"]' -p usera

表命令:

$cleos get table eosio.token DEMO stat 
{ 
    "rows": [{ 
        "supply": "21000000.0000 DEMO" 
        "max_supply": "2100000000.0000 DEMO" 
        "issuer": "usera" 
      } 
    ], 
    "more": false 
} 

$cleos get table eosio.token usera accounts 
{ 
    "rows": [{ 
        "balance": "20000000.0000 DEMO" 
      } 
    ], 
    "more": false 
} 

 
$cleos get table eosio.token userb accounts 
{ 
    "rows": [{ 
        "balance": "10000000.0000 DEMO" 
      } 
    ], 
    "more": false 
}

注意:本文是在Dawn4.1代碼發(fā)布時(shí)編寫的。

======================================================================

分享一些以太坊、EOS、比特幣等區(qū)塊鏈相關(guān)的交互式在線編程實(shí)戰(zhàn)教程:

  • EOS教程,本課程幫助你快速入門EOS區(qū)塊鏈去中心化應(yīng)用的開發(fā),內(nèi)容涵蓋EOS工具鏈、賬戶與錢包、發(fā)行代幣、智能合約開發(fā)與部署、使用代碼與智能合約交互等核心知識(shí)點(diǎn),最后綜合運(yùn)用各知識(shí)點(diǎn)完成一個(gè)便簽DApp的開發(fā)。

  • java以太坊開發(fā)教程,主要是針對(duì)java和android程序員進(jìn)行區(qū)塊鏈以太坊開發(fā)的web3j詳解。

  • python以太坊,主要是針對(duì)python工程師使用web3.py進(jìn)行區(qū)塊鏈以太坊開發(fā)的詳解。

  • php以太坊,主要是介紹使用php進(jìn)行智能合約開發(fā)交互,進(jìn)行賬號(hào)創(chuàng)建、交易、轉(zhuǎn)賬、代幣開發(fā)以及過濾器和交易等內(nèi)容。

  • 以太坊入門教程,主要介紹智能合約與dapp應(yīng)用開發(fā),適合入門。

  • 以太坊開發(fā)進(jìn)階教程,主要是介紹使用node.js、MongoDB、區(qū)塊鏈、ipfs實(shí)現(xiàn)去中心化電商DApp實(shí)戰(zhàn),適合進(jìn)階。

  • C#以太坊,主要講解如何使用C#開發(fā)基于.Net的以太坊應(yīng)用,包括賬戶管理、狀態(tài)與交易、智能合約開發(fā)與交互、過濾器和交易等。

  • java比特幣開發(fā)教程,本課程面向初學(xué)者,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲(chǔ)、去中心化共識(shí)機(jī)制、密鑰與腳本、交易與UTXO等,同時(shí)也詳細(xì)講解如何在Java代碼中集成比特幣支持功能,例如創(chuàng)建地址、管理錢包、構(gòu)造裸交易等,是Java工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程。

  • php比特幣開發(fā)教程,本課程面向初學(xué)者,內(nèi)容即涵蓋比特幣的核心概念,例如區(qū)塊鏈存儲(chǔ)、去中心化共識(shí)機(jī)制、密鑰與腳本、交易與UTXO等,同時(shí)也詳細(xì)講解如何在Php代碼中集成比特幣支持功能,例如創(chuàng)建地址、管理錢包、構(gòu)造裸交易等,是Php工程師不可多得的比特幣開發(fā)學(xué)習(xí)課程。

  • tendermint區(qū)塊鏈開發(fā)詳解,本課程適合希望使用tendermint進(jìn)行區(qū)塊鏈開發(fā)的工程師,課程內(nèi)容即包括tendermint應(yīng)用開發(fā)模型中的核心概念,例如ABCI接口、默克爾樹、多版本狀態(tài)庫等,也包括代幣發(fā)行等豐富的實(shí)操代碼,是go語言工程師快速入門區(qū)塊鏈開發(fā)的最佳選擇。

看完上述內(nèi)容,你們對(duì)怎樣理解eos區(qū)塊鏈的eosio.token合約有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


當(dāng)前標(biāo)題:怎樣理解eos區(qū)塊鏈的eosio.token合約
文章出自:http://weahome.cn/article/gspdji.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部