
适用范围:先明确授权对象
区块链开发授权有哪些常见误区,需要从授权对象说起。本文讨论以太坊智能合约中的访问控制与ERC-20代币授权。OpenZeppelin访问控制文档解释账户如何获得操作权限,ethereum.org的ERC-20说明介绍代币支出授权;两者解决的问题不同,不能混用。
误区一:代币授权等于管理员授权
ERC-20的approve用于设置指定支出方可使用的代币额度,allowance用于查询剩余额度,transferFrom承担相应转移操作。approve本身不完成转账,也不授予铸币或管理合约的权限。

排查授权问题时,应分别确认代币持有人、支出方、代币合约和额度。业务函数的调用权限则需要检查该函数自己的访问控制条件。

误区二:所有功能交给一个管理员就足够
单一管理员适合权限需求简单的合约。涉及多种职责时,可以通过角色划分限制各账户的操作范围。例如,负责铸币的账户未必需要拥有其他管理权限。
角色数量多也不等于权限分离有效。如果同一账户持有所有关键角色,实际权限仍然集中。设计时应围绕职责分配权限,并检查账户之间是否形成预期的边界。
误区三:持有业务角色就能分配该角色
AccessControl区分业务角色与管理该角色的权限。拥有某项业务角色,通常只意味着能够通过对应检查;能否授予或撤销角色,取决于其管理员角色。
DEFAULT_ADMIN_ROLE默认管理其他角色,也管理自身,因此需要特别审视其控制范围。默认管理员并不自动拥有全部业务角色,但可能具备授予这些角色的能力。权限评估应同时查看直接操作权和角色分配权。
误区四:转移或放弃所有权总能补救
所有权交给无法操作合约的地址,可能使管理功能无法使用。Ownable2Step通过新所有者主动接受来完成交接,降低错误转移带来的风险。放弃所有权则会使受onlyOwner保护的功能无法再被调用。
交接前应确认接收方能够完成所需调用。若合约还使用独立的角色机制,也要分别检查角色持有人;所有权变化不能代表所有授权状态都已变化。
常见问题:如何确认权限真正生效
权限验证应覆盖授权账户调用成功、未授权账户调用失败,以及撤销后调用失败等情形。仅定义角色名称不足以限制函数,关键入口必须实际执行权限检查。
基础AccessControl不支持链上枚举全部角色成员,可通过授予与撤销事件在链下追踪;需要链上枚举时可使用相应扩展。核对权限时,应结合当前状态与变更记录,避免把部署时的账户名单当作长期有效的结果。