#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. Я так думаю, спасибо за это!