1. 程式人生 > >eos智慧合約執行流程

eos智慧合約執行流程

eos智慧合約執行

1. 執行流程

controller::push_transaction()  // 事務

  -> transaction_context::exec()  // 事務

    -> transaction_context::dispatch_action() // 通過便利transaction中的各個action來分發執行

      -> apply_context::exec() // action

        -> apply_context::exec_one() // action 執行具體的智慧合約

          -> controller::get_wasm_interface()->apply() // 進入虛擬機器開始執行對應智慧合約

            -> wasm_interface_impl::get_instantiated_module()->apply() // 載入智慧合約並執行

              -> wavm_instantiated_module::apply() // 具體模組開始接收呼叫

                -> wavm_instantiated_module::call() // 開始執行具體函式

                  -> Runtime::invokeFunction() // 進入到wasm執行時庫開始執行具體函式

2. 分析exec_one

/**

 * IMPORTENT:執行具體action

 */

void apply_context::exec_one(action_trace &trace)

{

   auto start = fc::time_point::now();

 

   ...

 

   const auto &cfg = control.get_global_properties().configuration;

   try

   {

      try

      {

         /**

          * 接收者資訊,智慧合約賬號?應該是對應為eosio

          */

         const auto &a = control.get_account(receiver);

         privileged = a.privileged;

         /**

          * IMPORTENT:智慧合約查詢apply_handler,Native是原生api

          */

         auto native = control.find_apply_handler(receiver, act.account, act.name);

         if (native)

         {

           ......

           ...內建API呼叫

            (*native)(*this);

         }

 

         /**

          * IMPORTENT:智慧合約,a.code?這部分是程式碼?智慧合約賬號對應code就是合約程式碼

          */

         if (a.code.size() > 0 && !(act.account == config::system_account_name && act.name == N(setcode) &&

                                    receiver == config::system_account_name))

         {

            ......

            try

            {

               /**

                * IMPORTENT:執行智慧合約

                */

               control.get_wasm_interface().apply(a.code_version, a.code, *this);

            }

            catch (const wasm_exit &)

            {

            }

         }

      }

      FC_RETHROW_EXCEPTIONS(warn, "pending console output: ${console}", ("console", _pending_console_output.str()))

   }

   catch (fc::exception &e)

   {

     ...

     throw;

   }

   ...

}