&quot'当迅速致电函数时,但是当呼叫被隔开时却不是吗?

发布于 2025-01-25 05:22:33 字数 984 浏览 3 评论 0原文

我有一个智能合约,其中一个功能(队列)旨在允许用户与其他智能合约的其他用户找到“匹配”。逻辑是,如果您调用队列并且没有人等待,那么您现在是排队的用户 /钱包地址。如果您调用队列并且已经有一个排队的用户,则从队列中清除它们并设置比赛。

如果第一个队列呼叫在第二个呼叫之前几秒钟,则可以正常工作,但是如果两个用户同时呼叫队列,则第二个用户呼叫,第二个用户始终以不超过气体误差恢复。增加天然气的数量不能解决问题。

感谢任何想法!

该代码在IF块中失败。如果我删除了大部分逻辑,它将成功,但是我无法弄清楚原因。

if (awaitingMatch != address(0)) {
  userMap[awaitingMatch].opponent = msg.sender;
  userMap[awaitingMatch].matchedBlock = block.number;
  userMap[awaitingMatch].matchWins = 0;
  userMap[awaitingMatch].playAmount = msg.value;
  userMap[awaitingMatch].winsNeeded = winsToWin;

  userMap[msg.sender].opponent = awaitingMatch;
  userMap[msg.sender].matchedBlock = block.number; 
  userMap[msg.sender].matchWins = 0;
  userMap[msg.sender].winsNeeded = winsToWin;

  awaitingMatch = address(0);

  emit Match(msg.sender);
  emit Match(userMap[msg.sender].opponent);

// add this guy to the list awaiting a match, and set his desposit flag true
} else {
  awaitingMatch = msg.sender;
}

I have a smart contract, and one of the functions (queue) is meant to allow users to find "matches" with other users of the smart contract. The logic is that if you call queue and there is nobody waiting, you are now the queued user / wallet address. If you call queue and there is already a queued user, you clear them from the queue and set up the match.

This works fine if the first queue call is a few seconds before the second one, but if both users call queue at the same time, the second one always reverts with an Out of Gas error. Increasing the amount of gas does not solve the issue.

I would appreciate any ideas!

The code fails in the if block. If I remove most of the logic, it succeeds, but I can't figure out any rhyme or reason as to why.

if (awaitingMatch != address(0)) {
  userMap[awaitingMatch].opponent = msg.sender;
  userMap[awaitingMatch].matchedBlock = block.number;
  userMap[awaitingMatch].matchWins = 0;
  userMap[awaitingMatch].playAmount = msg.value;
  userMap[awaitingMatch].winsNeeded = winsToWin;

  userMap[msg.sender].opponent = awaitingMatch;
  userMap[msg.sender].matchedBlock = block.number; 
  userMap[msg.sender].matchWins = 0;
  userMap[msg.sender].winsNeeded = winsToWin;

  awaitingMatch = address(0);

  emit Match(msg.sender);
  emit Match(userMap[msg.sender].opponent);

// add this guy to the list awaiting a match, and set his desposit flag true
} else {
  awaitingMatch = msg.sender;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

原来分手还会想你 2025-02-01 05:22:33

我想我已经弄清楚了。问题在于,元主张试图估计每笔交易将使用的气体量。 Metamask擅长于此,并在估计气体之前对合同的状态进行分析。 如果部分(由第二个呼叫者运行)的工作要比 else 部分(由第一个呼叫者运行)要多得多。如果我同时拨打两个电话,他们都估计他们将运行更轻的 else 部分,但是其中一个会运行第一个,更昂贵的,如果部分。

我认为,我最好的选择是调整有关此类函数的任何呼叫中提供的气体量,该功能可以根据功能的那一刻,可以从事大量工作。

I think I have figured this out. The issue is that MetaMask tries to estimate the amount of gas that will be used for each transaction. MetaMask is quite good at this, and analyzes the state of the contract before estimating the gas. The if section (run by the second caller) does a lot more work than the else section (run by the first caller). If I make both calls at the same time, they both estimate that they'll run the lighter else section, but one of them will wind up running the first, more expensive if section.

I think my best bet here is to tweak the amount of gas being supplied on any call to a function like this that could do quite different amounts of work depending on the moment the function is called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文