调用write的智能合约方法时,有些方法可以来起来metamask,有些方法却不可以,甚至有些方法一开始可以,后面不可以了。这些问题的原因如下:
首先确定一点,就是调用智能合约方法都是纯前端的代码,完全没有和服务器后段交互。是前端js直接和钱包的rpc接口进行通信的。
当调用一个需要写入的合约方法时,流程是这样的:
用户点击调用 -> gas估算 -> MetaMask签名 -> 发送交易 -> 等待确认
在 addCommitteeMember 的情况下:
用户点击调用 -> gas估算(失败) -> 直接报错,不会到MetaMask签名步骤
具体原因:
而在 setChallengePeriod 的情况下:
用户点击调用 -> gas估算(成功) -> MetaMask弹出签名请求 -> 用户确认/拒绝
这就是为什么两个方法会有不同的表现:
要解决这个问题,我们需要在调用前先检查合约状态,避免在 gas 估算阶段就失败。这就是为什么我们之前添加了检查委员会成员数量的代码。
在 gas 估算阶段,节点会使用调用者的地址(from 地址)来模拟执行交易。这个地址就是我们在代码中通过 provider.getSigner() 获取的签名者地址。
让我们看看相关代码:
const createContract = () => {
const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner()
return new ethers.Contract(verifyData.address, verifyData.abi, signer)
}
当合约执行 onlyOwner 修饰符时:
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
所以关键点是:
这就是为什么:
所以,权限检查在 gas 估算阶段是有效的,因为:
节点使用实际的调用者地址进行模拟合约的权限检查是基于 msg.sender 的如果权限检查失败,gas 估算就会失败,整个交易就不会继续
这就是为什么我们需要确保:
用户连接了正确的 MetaMask 账户这个账户有足够的权限执行合约方法在调用前检查权限状态,避免在 gas 估算阶段就失败filecoin PDP 笔记
drand服务发起随机数,PDP SP收到随机数当作随机挑战,对挑战到的数据生成proof,提交到链上,这个时候不管proof正确与否,链上合约都不用验证,等到PDP SP调用合约取钱的时候,才进行proof的验证,如果已经提交了数据是错误的,或者没有提交,则会扣钱,或者不能取现。否则获得收入。