我有一份合同叫做exchange
. 用户Bob
想要通过放置 的方式花钱near tokens
购买头寸。
有一个名为 的字段,在这种情况下,合约必须证明某个地址归某个地址所有,这一点很重要。markets
Order
Order
owner
order
Bob
当前处理发送到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-tokens
onexchange
并且exchange
只要它可以证明它通过由 签名的“登录访问令牌”来证明它正在这样做Bob
,那么这里的问题再次是:这可能吗?如果是这样怎么办?