Потребуется отменить изменения в хранилище, внесенные в отдельный контракт в той же транзакции — Надежность

#blockchain #ethereum #solidity #smartcontracts #erc20

Вопрос:

Я новичок в солидности (и кодировании в целом), поэтому, пожалуйста, простите меня, если это глупый вопрос! Я пытаюсь понять объем заявления require для нескольких контрактов. Я хочу разработать главный контракт, в котором пользователь может установить надбавку за это, а затем взаимодействовать с несколькими другими субподрядчиками, для взаимодействия с которыми требуется пользовательский токен ERC20. Идея заключается в том, что пользователю нужно только авторизовать главный контракт, который управляет их токенами и гарантирует, что они будут переданы другим контрактам для оплаты при взаимодействии с ним, а не заставлять пользователя устанавливать надбавку для всех других контрактов по отдельности.

Допустим, например, у нас есть два контракта: контракт A является основным (в этом сценарии пользователь уже установил правильное разрешение) и контракт B, контракт, с которым пользователь хочет взаимодействовать. Пользователь вызывает функцию в контракте A, которая проверяет наличие у него необходимого количества токенов для использования функции в b перед выполнением. если все проверяется на финансовой стороне, контракт A вызывает функцию в контракте B, которая также должна проверить определенные переменные, чтобы продолжить. При условии, что все проверено, B добавляет пользователя в сопоставление и возвращает, затем A выполняет функцию transferfrom. (Я надеюсь, что все это имеет смысл);

Может ли пользователь в какой-то момент во время выполнения call_b изменить допустимое значение на ноль таким образом, чтобы прошли первые две инструкции require, но произошел сбой при выполнении transferfrom, и если это произойдет, произойдет ли сбой require в A, в результате которого изменения в хранилище, внесенные в B, будут отменены?

или

другой вариант, который я рассмотрел, — это передача токенов пользователя сразу после прохождения финансовых проверок и использование инструкции require вокруг B. f(msg.отправитель), чтобы отменить перевод, если это не удастся. (если продолжить, установите значение false)

или

неужели все это действительно глупо и есть гораздо лучший способ действовать?

Заранее спасибо за всю вашу помощь.

 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

import "Contract_B.sol";
import "Token.sol";

contract Contract_A{

  Contract_B public contract_B;
  Token public token;

   constructor(Contract_B _contract_B, Token _token){
      contract_B =  Contract_B(_contract_B);
      token = Token(_token);
       
    }

    function call_b() public returns(bool){
      //financial checks - the cost against balance and allowance
      uint costToUse = b.costToUse;
      require(token.balanceOf(address(msg.sender)) >= costToUse ,"You don't have enough!");
      require(token.allowance(address(msg.sender), address(this)) >= costToUse , "Allowance to 
      low");

      //Would transerfrom be better here?.Would (require b.f(msg.sender)) revert a transfer.

      //effects - set values  
      require(b.f(msg.sender), "failed!");

      require(token.transferFrom(address(msg.sender), address(this), costToUse ), "Transfer 
      Error");
    }

}

contract Contract_B{
  
  // insstance of master contract for security check
  Contract_A public contract_A;
  
  bool public continue;
  uint public costToUse;
  uint public userCount;
  mapping(uint => address) users;
  
  constructor(Contract_A _contract_A, uint _costToUse){
    contract_A = new(_contract_A); 
    costToUse = _costToUse;
    continue = true;
  }

  modifier onlyA(){
      require(msg.sender == contract_A, "not contract A!");  
    _;
  }
  
  function f(address _user) public onlyA() returns (bool){
    require(continue , "Can not continue");
    users[userCount] = _user;
    userCount  ;
    return true;
  }
   
  function setContinue(bool _continue) public onlyA() returns(bool){
      continue= _continue;
      return true;
  }


}
 

Комментарии:

1. отвечает ли это на ваш вопрос здесь: ethereum.stackexchange.com/questions/28985/…

2. Я так думаю, спасибо за это!