# argent钱包源码-（三）模块加载机制

By [daxiong](https://paragraph.com/@daxiong) · 2022-10-05

---

argent加载模块涉及到钱包合约、模块合约和工厂合约，具体流程如下：

1、walletFactory中创建钱包的时候，会调用baseWallet的init方法绑定模块合约，init方法中会将模块合约地址写入到authorised中并设置值为true；

     walletFactory.sol ：
      _wallet.init(_owner, extendedModules);
    ...
    
    baseWallet.sol:
    
    function init(address _owner, address[] calldata _modules) external {
            require(owner == address(0) && modules == 0, "BW: wallet     already initialised");
            require(_modules.length > 0, "BW: empty modules");
            owner = _owner;
            modules = _modules.length;
            for (uint256 i = 0; i < _modules.length; i++) {
                require(authorised[_modules[i]] == false, "BW: module is already added");
                authorised[_modules[i]] = true;
                IModule(_modules[i]).init(address(this));
                emit AuthorisedModule(_modules[i], true);
            }
            if (address(this).balance > 0) {
                emit Received(address(this).balance, address(0), "");
            }
        }
    

2、同时模块合约ArgentModule本身提供了 addModule 方法，来额外的给钱包增加模块，但是该方法只能由钱包主人调用并且必须提前在模块注册合约（ModuleRegistry.sol）进行注册；

    //该方法实际是调用的baseWallet合约的authoriseModule方法来设置
    function addModule(address _wallet, address _module) external override onlyWalletOwnerOrSelf(_wallet) onlyWhenUnlocked(_wallet) {
            require(registry.isRegisteredModule(_module), "AM: module is not registered");
            IWallet(_wallet).authoriseModule(_module, true);
        }
    

3、到此为止，模块合约的注册和变更都有说到了，总结如下：

3.1、模块合约的注册在baseWallet合约中；

3.2、如果要调用baseWallet中的invoke方法，必须通过moduleOnly 这个modifier的验证，而这个验证的规则就是只有注册授权的模块才能调用；

4、在梳理argent钱包源码的时候，注册这里也有一些不足和需要优化的地方，例如：

4.1、没有删除模块的功能；

4.2、argentModule由于是继承了relayerManager、tranactionManager 和SecurityManager，所有导致argentModule很大，容易触发eth的合约字节大小限制；

4.3、由于baseWallet合约本身没有实现onERC721Received方法（该方法在tranactionManager中实现），因此在没有加载任何模块的时候，钱包是不支持接受nft资产的；

4.4、由于baseWallet合约本身没有实现addModule方法（该方法在argentModule中实现），因此在没有加载任何模块的时候，钱包是不支持添加模块的，因此必须在创建钱包的时候，将默认的模块添加进去实现基础的功能；

5、下边是梳理的argetModule的继承关系，以及合约内部详细方法：

![](https://storage.googleapis.com/papyrus_images/40dc9103218ae12ea3cbc5ee5ae0a46456ae140527d0062898ab0c7f93829359.png)

---

*Originally published on [daxiong](https://paragraph.com/@daxiong/argent-2)*
