Access Controller는 Story의 모든 권한 관련 상태와 권한 검사를 관리합니다. 특히, 다음을 유지합니다 Permission TablePermission Engine 권한을 처리하고 저장합니다. IPAccount 권한은 IPAccount 소유자가 설정합니다.

Permission Table

Permission Record

IPAccountSigner (caller)To (only module)Function SigPermission
0x123..1110x789..2220x790..3330xAaAaAaAaAllow
0x123..1110x789..2220x790..3330xBBBBBBBBDeny
0x123..1110x789..2220x790..3330xCCCCCCAbstain

각 레코드는 다음 형식으로 권한을 정의합니다 Signer (호출자)가 FuncTo (모듈)을 IPAccount를 대신하여 호출합니다.

권한 필드는 “Allow,” “Deny,” 또는 “Abstain”으로 설정할 수 있습니다. Abstain은 권한 결정이 상위 수준 권한에 의해 결정됨을 나타냅니다.

와일드카드

권한을 정의할 때 와일드카드도 지원됩니다. 이는 여러 모듈 및/또는 함수에 적용되는 권한을 정의합니다.

와일드카드를 사용하면 사용자가 쉽게 허용 목록이나 차단 목록의 권한을 정의할 수 있습니다.

IPAccountSigner (caller)To (module)FuncPermission
0x123..1110x789..222**Allow
0x123..1110x789..2220x790..333*Deny

위의 예시는 서명자(0x789…)가 IPAccount(0x123…)를 대신하여 모듈(0x790…)의 어떤 함수도 호출할 수 없음을 보여줍니다.

다시 말해, IPAccount는 서명자가 모듈 0x790…333의 어떤 함수도 호출하지 못하도록 차단 목록에 추가했습니다.

  • 지원되는 와일드카드:
매개변수와일드카드
Funcbytes4(0)
주소 (IPAccount / To)address(0)

권한 우선순위

특정 권한이 일반 권한보다 우선합니다.

IPAccountSigner (caller)To (module)FuncPermission
0x123..1110x789..222**Allow
0x123..1110x789..2220x790..333*Deny
0x123..1110x789..2220x790..3330xCCCCDDDDAllow

위의 예시는 서명자(0x789…)가 IPAccount(0x123…)를 대신하여 모듈(0x790…)의 어떤 함수도 호출할 수 없지만, 함수 0xCCCCDDDD는 예외임을 보여줍니다.

또한, 서명자(0x789…)는 IPAccount(0x123…)를 대신하여 다른 모든 모듈을 호출할 수 있습니다.

접근 제어가 있는 호출 흐름

Access Controller가 예상하는 세 가지 유형의 호출 흐름이 있습니다.

  1. IPAccount가 모듈을 직접 호출합니다.
  2. 모듈이 다른 모듈을 직접 호출합니다.
  3. 모듈이 레지스트리를 직접 호출합니다.

IPAccount가 모듈을 직접 호출하는 경우

  • IPAccount는 Access Controller와 권한 검사를 수행합니다.
  • 모듈은 msg.sender가 유효한 IPAccount인지만 확인하면 됩니다.msg.sender 유효한 IPAccount입니다.

IPAccount에서 모듈을 호출할 때, IPAccount는 AccessController와 접근 제어 검사를 수행하여 현재 호출자가 해당 호출을 할 수 있는 권한이 있는지 확인합니다. 모듈에서는 트랜잭션 msg.sender가 유효한 IPAccount인지만 확인하면 됩니다.msg.sender 유효한 IPAccount입니다.

AccessControlled는 modifier를 제공합니다 onlyIpAccount() 액세스 제어 확인을 수행하는 데 도움이 됩니다.

Solidity
contract MockModule is IModule, AccessControlled {
    function action(string memory param) external view onlyIpAccount() returns (string memory) {
            // do something
    }
}

모듈이 다른 모듈을 호출

  • 호출된 모듈은 자체적으로 인증 확인을 수행해야 합니다.

모듈이 다른 모듈에서 직접 호출될 때, 해당 모듈은 AccessController를 사용하여 액세스 제어 확인을 수행할 책임이 있습니다. 이 확인은 현재 호출자가 모듈을 호출할 권한이 있는지 결정합니다.

AccessControlled 수정자를 제공합니다 verifyPermission(address ipAccount) 액세스 제어 확인을 수행하는 데 도움이 됩니다.

Solidity
contract MockModule is IModule, AccessControlled {
    function callFromAnotherModule(address ipAccount) external verifyPermission(ipAccount) returns (string memory) {
        if (!IAccessController(accessController).checkPermission(ipAccount, msg.sender, address(this), this.callFromAnotherModule.selector)) {
		        revert Unauthorized();
        }
			  // do something
    }
}

모듈이 Registry를 호출

  • 레지스트리는 AccessController를 호출하여 인증 확인을 수행합니다.
  • 레지스트리는 전역 권한 설정을 통해 모듈을 인증합니다

모듈에 의해 레지스트리가 호출될 때, AccessController를 사용하여 액세스 제어 확인을 수행할 수 있습니다. 이 확인은 호출된 모듈이 레지스트리를 호출할 권한이 있는지 결정합니다.

Solidity
// called by StoryProtocl Admin
IAccessController(accessController).setGlobalPermission(address(0), address(module), address(registry), bytes4(0))) {
Solidity
contract MockRegistry {
    function registerAction() external returns (string memory) {
        if (!IAccessController(accessController).checkPermission(address(0), msg.sender, address(this), this.registerAction.selector)) {
		        revert Unauthorized();
        }
			  // do something
    }
}

소유권 이전 시 IPAccount의 권한이 취소됩니다.

IPAccount와 연관된 권한은 현재 소유자에게만 독점적으로 연결됩니다. IPAccount의 소유권이 새로운 개인에게 이전될 때, 이전 소유자에게 부여된 기존 권한은 자동으로 취소됩니다. 이는 현재의 합법적인 소유자만이 이러한 권한에 접근할 수 있도록 보장합니다. 만약 향후 IPAccount 소유권이 원래 소유자에게 다시 이전된다면, 처음에 취소되었던 권한이 복원되어 원래 소유자의 접근 및 제어 권한이 회복됩니다.