我正在尝试获取 EGLD 中 USDT 的价格。我正在使用这个:https://github.com/multiversx/mx-exchange-sc/blob/main/dex/pair/src/lib.rs#L604端点来获取价格。但不确定这样做的过程是否正确。一位社区成员建议我这样做。
我的代码是:
#![no_std]
multiversx_sc::imports!();
pub mod callee_proxy {
multiversx_sc::imports!();
#[multiversx_sc::proxy]
pub trait CalleeContract {
#[view(getAmountOut)]
fn get_amount_out_view(&self, token_in: TokenIdentifier, amount_in: BigUint) -> BigUint;
}
}
#[multiversx_sc::contract]
pub trait MinterContract {
#[init]
fn init(&self, address: ManagedAddress, price: BigUint, token_id: TokenIdentifier, usdt_token_id: TokenIdentifier) {
self.set_address().set(&address);
self.set_esdt_price().set(&price);
self.set_token_id().set(&token_id);
self.set_usdt_token_id().set(&usdt_token_id);
}
#[payable("*")]
#[endpoint]
fn buy_token(&self, amount: BigUint) {
require!(amount >= 1000, "Withdrawal of token amount of less than 1000 is not allowed");
require!(amount <= 10000, "Withdrawal of token amount of more than 10000 is not allowed");
let _price : BigUint = amount.clone() * self.set_esdt_price().get();
let _output_amount_as_egld: BigUint = self.contract_proxy(self.set_address().get()).get_amount_out_view(self.set_token_id().get(), _price).execute_on_dest_context();
require!(self.call_value().egld_value().clone_value() >= _output_amount_as_egld, "Not enough ELGD paid!");
self.send().direct_esdt(&self.blockchain().get_caller(), &self.set_token_id().get(), 0, &amount);
}
#[endpoint]
fn get_usdt_to_egld(&self, amount: BigUint) -> BigUint{
let output_amount: BigUint = self.contract_proxy(self.set_address().get()).get_amount_out_view(self.set_usdt_token_id().get(), amount).execute_on_dest_context() ;
output_amount
}
#[proxy]
fn contract_proxy(&self, sc_address: ManagedAddress) -> callee_proxy::Proxy<Self::Api>;
#[storage_mapper("Key_tokenId")]
fn set_token_id(&self) -> SingleValueMapper<TokenIdentifier>;
#[storage_mapper("Key_tokenId")]
fn set_usdt_token_id(&self) -> SingleValueMapper<TokenIdentifier>;
#[storage_mapper("key_address")]
fn set_address(&self) -> SingleValueMapper<ManagedAddress>;
#[storage_mapper("key_price")]
fn set_esdt_price(&self) -> SingleValueMapper<BigUint>;
}
如您所见,我创建了这样的代理,并声明了目标端点。我使用这个地址:
erd1qqqqqqqqqqqqqpgqeel2kumf0r8ffyhth7pqdujjat9nx0862jpsg2pqaq
作为这里的交换地址:https://explorer.multiversx.com/accounts/erd1qqqqqqqqqqqqqpgqeel2kumf0r8ffyhth7pqdujjat9nx0862jpsg2pqaq/tokens。
但是当我这样调用 get_usdt_to_egld()
时: mxpy --verbose contract call erd1qqqqqqqqqqqqqpgq027dusnhgjug07pwzhdaqv0sxt7j0hsn2nfsww256n --chain D --pem="../walletKey.pem" --gas-limit=2000000 --function="get_usdt_to_egld" --arguments 1000 --proxy="https://devnet-gateway.multiversx.com" --recall-nonce --send
我的交易失败,请在此处查看交易: https://devnet-explorer.multiversx.com/transactions/bae86eec15ce3a3a6aac39447bd3d7a6f4197b98b448b5188ea0bc8756b4369a#decimal .
当我这样查询时:
mxpy contract query erd1qqqqqqqqqqqqqpgq027dusnhgjug07pwzhdaqv0sxt7j0hsn2nfsww256n --proxy="https://devnet-gateway.multiversx.com" --function="get_usdt_to_egld" --arguments 10000
我得到了这个错误:
RuntimeError: Query failed: invalid contract code (not found)
我想做什么? => 我想实现逻辑:
buy_token()
中输入他们想要购买的代币数量。buy_token()
中,金额(由用户给出)将乘以 500,因为 USDT 有 6 位小数。
这样我们就得到了USDT代币总量的价格。这就是我想要实现的。帮我实现它。
我知道这可能是一个迟到的答案,但也许它会对其他开发人员有所帮助。在过去的几个月里,我们查询代币价格的方式发生了一些变化,因为我们现在可以使用安全价格查询 SC 来执行此操作。
您可以在交换仓库中查看以下代码。在这里,您可以看到所有可用的视图函数,用于根据 LP 内的价格获取特定代币的价格。它们为您提供了广泛的选择,从提供价格查询的特定时间范围、使用默认参数计算价格,甚至获取 LP 中两种代币的安全价格等等。
https://github.com/multiversx/mx-exchange-sc/blob/main/dex/pair/src/safe_price_view.rs
现在,将安全价格查询 SC 集成到合约中的方法是对通用合约进行代理调用,这允许您从要获取价格的位置提供所需的货币对地址。基本上,所有配对合约的一个查询地址。
按照您的示例,您想要查询 WEGLD 的价格,通过提供稳定的代币输入金额,实现会类似于:
let wegld_price: EsdtTokenPayment = self
.pair_proxy(price_query_address)
.get_safe_price_by_default_offset(
stable_pair_address,
EsdtTokenPayment::new(stable_token_id, 0, stable_worth_amount),
)
.execute_on_dest_context();
希望这有助于澄清在合同中实施安全价格逻辑时的事情。