29

I would like to have a modifier that looks like this:

modifier restrictTargetType(uint contractType) {
    if (contractTypes[target] != contractType) { throw; }
    _
}

Where target is an address passed as a function argument. Simply naming the function argument target isn't sufficient, and gives me an Error: Undeclared identifier.

PeterBB
  • 615
  • 1
  • 6
  • 11

2 Answers2

43

At the point where you use the modifier, the function arguments are already in scope. This means something like the following is possible:

contract C {
  modifier restrictTargetType(address target, uint contractType) {
    require(contractTypes[target] == contractType);
    _;
  }
  function f(address target, uint contractType) restrictTargetType(target, contractType) {
    ....
  }
}

There is no generic way to provide access to the function arguments, though.

Utgarda
  • 791
  • 5
  • 20
chriseth
  • 3,392
  • 1
  • 20
  • 17
4

I've found a hacky solution that uses inline assembly, but would love a more "native" solution if there is one.

modifier restrictTargetType(uint contractType) {
  if (contractTypes[_getFirstArg(msg.data)] != contractType) { throw; }
}

function _getFirstArg(bytes calldata) returns(address result) {
  assembly {
    calldatacopy(mload(0x40), 4, 32)
    result := mload(mload(0x40))
  }
}
PeterBB
  • 615
  • 1
  • 6
  • 11