我有一份合同叫做exchange. 用户Bob想要通过放置 的方式花钱near tokens购买头寸。
有一个名为 的字段,在这种情况下,合约必须证明某个地址归某个地址所有,这一点很重要。marketsOrderOrderownerorderBob
当前处理发送到exchange的事务的流程类似于:
const init = async () => {
this.near = await window.nearlib.connect(Object.assign({ deps: { keyStore: new window.nearlib.keyStores.BrowserLocalStorageKeyStore() } }, window.nearConfig));
this.walletAccount = new window.nearlib.WalletAccount(this.near);
this.accountId = this.walletAccount.getAccountId();
this.exchange = await this.near.loadContract(window.nearConfig.contractName, {
viewMethods: [],
changeMethods: ["place_new_order"],
sender: this.accountId,
});
}
await init();
// Bob logs into to near
this.walletAccount.requestSignIn(
window.nearConfig.contractName,
window.nearConfig.contractName,
);
// Login process
[...]
// Bob wants to place a new order
this.exchange.place_new_order(price, amount);
exchange合约导入一个struct被调用的Order.
Order看起来像:
use std::string::String;
use borsh::{BorshDeserialize, BorshSerialize};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize, Clone)]
pub struct Order {
pub owner: String,
pub amount: u64,
pub price: u64,
}
impl Order {
pub fn new(owner: String, amount: u64, price: u64) -> Self {
Order {
owner,
amount,
price
}
}
}
Exchange在这种情况下,是实现 mod 的合约order。Exchange有place_new_order一种方法,我希望能够确保这Bob是发送交易的人:
use near_bindgen::{near_bindgen, env};
[...]
mod Order;
[...]
pub fn place_new_order(&mut self, amount: u64, price: u64) {
// Stuff happens here
let order = Order::new(env::current_account_id(), amount, price);
// Stuff happens here
}
现在的问题是,以防万一,使用这个 nearlib 代码env::current_account_id()将始终返回exchange为current_account_id. 这是有道理的,因为所有登录所做的只是创建一个access_key允许exchange以 的名义做几件事,Bob但它仍在Exchange签署交易。
这里的问题是:我如何确保该交易所知道那Bob是初始化交易的人?
一种可行的方法是有意义的:
Bob用他的私钥签署每笔交易,我在这里的问题是:如何?
这将导致类似 Metamask 的 UX 问题,在每个 tx 上签名都是错误的 UX。
我建议如下:
Bob使用一种deposit方法来存入一定数量的near-tokensonexchange并且exchange只要它可以证明它通过由 签名的“登录访问令牌”来证明它正在这样做Bob,那么这里的问题再次是:这可能吗?如果是这样怎么办?