特定ContractからのACL

Contractの関数では、どのアドレスからの呼び出しに対して処理を実行するかのアクセスコントロールが非常に重要になります。

あるコントラクトに対して特定のアドレスからの命令しか受け付けない場合は下記のような記述になります。

contract SomeContract is VersionContract {

    address owner = msg.sender;
    mapping(address => bool) allowAddresses;

    function SomeContract(ContractNameService _cns) VersionContract(_cns, "SomeContract") {}

    modifier onlyOwner() {
        if (owner != msg.sender) throw;
        _;
    }
    modifier onlyAllowAddress() {
        if (!allowAddresses[msg.sender]) throw;
        _;
    }
    function someMethod(bytes _sign, uint _timestamp, uint _p1, bytes32 _p2) onlyAllowAddress {
        // do something
    }

    function addAllowAddress(address _addr) onlyOwner {
        allowAddresses[_addr] = true;
    }
}

上記の方法でもアクセスコントロールは可能ですが、この方式では常に呼出許可アドレス(allowAddresses)の調整をしないといけません。

基本Contract構成 で作成されたコントラクトから呼び出される場合、基本的にはVersionLogicのサブコントラクトから呼び出されることになります。

VersionLogicのサブコントラクトから呼び出されるコントラクトは、VersionLogicのサブコントラクトのバージョンが上がってアドレスが変更されても対応できる形式になっている必要があります。

そのために用意してあるのが、ContractNameService#isVersionLogic となります。

呼出元のアドレスの認証を下記のように変更することで、バージョンが上がっても対象のコントラクトからの呼び出しは許可されます。

contract SomeContract is VersionContract {

    address owner = msg.sender;
    mapping(address => mapping(bytes32 => bool)) allowCnsContract;

    function SomeContract(ContractNameService _cns) VersionContract(_cns, "SomeContract") {}

    modifier onlyOwner() {
        if (owner != msg.sender) throw;
        _;
    }
    modifier onlyAllowCnsContract() {
        VersionLogic logic = VersionLogic(msg.sender);
        if (!allowCnsContract[logic.getCns()][logic.getContractName()]) throw;
        if (!logic.getCns().isVersionLogic(_sender, logic.getContractName())) throw;
        _;
    }
    function someMethod(bytes _sign, uint _timestamp, uint _p1, bytes32 _p2) onlyAllowCnsContract {
        // do something
    }

    function addCnsContract(address _cns, bytes32 _contractName) onlyOwner {
        allowAddresses[addr] = true;
    }
}

実際には、下記のような工夫が必要になります。

  • 各フィールドはFieldコントラクトなどに実装し、ロジックと分離するように実装する。
  • 各ID毎に許可するCNSアドレス+Contractを指定できるようにする。

これらの条件に基づいた実装の仕方については、下記のコントラクト実装を参考にしてください。

results matching ""

    No results matching ""