近くの呼び出しプロトコルのクロス契約呼び出し


初期の明確化
  • 次の記事は、Rustを使用してスマート契約の開発に焦点を当てています.
  • その例は近くで開発されますが、以下の情報の多くは、それがさびを使って開発されることができるどんな他のBlockinにも移されることができます.
  • 例を以下のリポジトリから取得します.BlockJobs-Marketplace , いくつかのクロスコントラクトコールは、下記の使用に加えて見ることができます.
  • この記事は、大部分の他の資金のトークンのサービスのための支払いを許すために、専門のサービス市場からの大契約への十字契約呼び出しを示します.
  • 導入
    情報を要求したり修正したりするなどの契約間の呼び出しを必要とする様々な理由があります.これは、サードパーティ契約からのコードを使用せずに、トークンを転送するコードを使用しています.
    この例を以下に示し、クロスコントラクトコールがどのように動作するかを文脈的に説明する.
    1 -呼び出し契約
    外部の関数を呼び出すことができるようにするには、まず最初にすべきことは、どのような情報が要求されるのかを示す情報を、それぞれのデータ型をパラメータとして指定することです&self が追加され、返されるデータの型が追加されますが、これは省略することができます).これは最初にインポートする必要がありますnear_sdk::ext_contract そして、以下に示すように実装します.
    use near_sdk::ext_contract;
    
    impl Contract {
       …
    }
    
    #[ext_contract(ext_contract)]
    trait ExtContract {
    fn ft_transfer(&mut self, receiver_id: AccountId, amount: U128, memo: Option<String>);
    }
    #[ext_contract(ext_self)]
    pub trait ExtSelf {
        fn on_buy_service(service_id: u64) -> Service;
    }
    
  • 括弧内の' extRule契約'は、与えられている名前であり、次に、どのような形質が呼ばれているかを示すために使用されます.
  • '“ExtContract”は、後で必要とされない名前です.つまり、それは無関心です.
  • 呼び出された関数が公開されている場合は、' ft 'は十分である.
  • 関数名とパラメーターの名前は、呼び出されたコントラクトと全く同じである必要があります.入力エラーの場合は“不十分なガス量”エラーが表示されます.
  • 特性EXTSELEについては後述する.
  • 1.1 -呼び出しをする
    対応する関数のうち、呼び出しは以下のようにします.
    ext_contract::ft_transfer(
       self.contract_me.clone(),
       service.metadata.price.into(),
       None,
       &token, 
       ONE_YOCTO, 
       GAS_FT_TRANSFER
    ).then(ext_self::on_buy_service(
       service_id,
       &env::current_account_id(), 
       NO_DEPOSIT, 
       BASE_GAS)
    );
    
  • ft_transfer が最初に3つの対応するパラメタを渡すと呼ばれて、次に、契約のアドレスtoken ), 次に、支払可能なタイプ関数の場合、および最後にガスの量、最後に拡張されるトピックの場合に接続の量.パラメタの順序は厳密に尊重されなければなりません、さもなければ、それは失敗します、そして、コンパイラは必ずしも誤りを示しません.
  • デポジットとガスは定数に割り当てられていますが、数値も直接指定できます.
  • The then メソッドを省略することができ、関数が返す関数に応じて2番目の関数を実行したい場合に使用されます.
  • 1.2 -呼び出し背中
    2番目の関数は、呼び出しを行うコントラクトに作成できます.それは厳密に必要ではありませんが、通常、最初の関数の名前の前に、最初に呼び出された関数の例ではbuy_service , だから今、名前はon_buy_service を返します.
    pub fn on_buy_service(&mut self, service_id: u64) -> Service {
      match env::promise_result(0) {
          PromiseResult::Successful(_data) => {
              service.sold = true;
              service.on_sale = false;
              self.service_by_id.insert(&service_id, &service);
              return service;
          }
          PromiseResult::Failed => env::panic(b"Callback faild"),
          PromiseResult::NotReady => env::panic(b"Callback faild"),
      };
    }
    
  • 呼び出しにエラーが発生した場合は、「callback失敗」というメッセージでパニック型のエラーが実行されます.もし呼び出しが正しく実行された場合、最初に呼び出したコントラクトの状態を変更するコードが実行されます(これはthen 方法ですが、これは良い練習です.
  • この場合、返される値は使用されていませんdata パラメータの前に“Count”があり、警告が出されないようにしていますが、この値はステータス変更に必要です.
  • 最初に共有されたリポジトリでは、これを省略した例も参照できます.
  • この例では使用されませんが、それは約束を返すのに便利ですnear_sdk::PromiseOrValue インポートする必要がありますlink このトピックで展開します.
  • 2 -契約と呼ばれる
    呼び出されたコントラクトは独自のものであるかもしれませんが、そのパラメータと呼ぶアドレスとメソッドを知る必要があるだけです.
    この例では、大コントラクトの転送関数が呼び出されているので、転送が正しく実行されている場合は、on_buy_service が実行され、ステータスが示されるように変更される.しかし、返される値は、例えばBooleanのような他のデータであり、これから情報を変更する.このコード例では、validate_user and validate_tokens の両方の関数mediator.rs 契約.
    3 -ガス管理
    最も一般的なエラーは「不十分なガス量」であり、これはガスの不足量や取り付けによるものであるが、結果として呼ばれる関数が実行を終了して結果を返すのを防止するエラーのためである.この問題が発生した場合、各関数の開始時と終了時にログを発行し、実行が実行されるまでの状態を参照してください.また、問題が呼び出しの場合、または関数の一部の内部コードに対して状態変化を確認するコードをコメントすることは良い考えかもしれません.
    上記を実行することによってエラーが見つからなかった場合、実施例200では、TGAが実行されるパラメータとして通過された場合、300 TGAである、近くに支持された最大値より大きいガスの量が確立されていることがあるft_transfer と120のTGAon_buy_service , それらの300は十分でないでしょう、あるいは、Testnetで働く場合には、十分なガスが取り付けられていないかもしれません.テストのために、追加することによってガスの最大量を指定することをお勧めします--gas 300000000000000 関数呼び出しの最後まで.その後、残りのガスは、取引に署名する人に返されますが、この値がどれだけのガスが消費されているか見て調整することができます好む場合は、常にそれは不十分ではないことを確認するために、より高い量、おそらく2倍を示すことが賢明です.
    最終清算
  • 作成したコントラクト間の関数と呼び出しのテストを書くことが望ましいことを覚えておいてください.
  • ガスの使用と価値に関する情報を見る​​関数が返すNear Explorer .
  • 質問については、我々はStackOverflow , またはTelegram channel for devs .
  • この情報があなたにとって有益であることを願っています.