Solidity所有權和訪問控制教程指南

買賣虛擬貨幣
介    紹在寫智慧合約時,我傾向於採取引導方式。即使它們旨在用於生產環境,我也使它們儘可能易於理解。我寫的智慧合約是可重用的,但是通常會針對每個特定的業務案例重新編寫智慧合約。在本文中,我將討論solidity智慧合約中的三種許可方法。討論這些方法的複雜性從高到低,這是您在專案中應考慮的順序。 我提供了可用於每種方法的程式碼。本文假定您可以輕鬆地編寫智慧合約,並使用繼承和傳遞合約地址等功能作為引數。簡單方法— Ownable.solOpenZeppelin的Ownable.sol合同必須是最重用的合同之一。它在77行中實現:
1. 斷言某人是智慧合約所有者的邏輯。2. 限制函式呼叫以繼承智慧合約的所有者的邏輯。3. 將所有權轉移到其他地址的邏輯。在編寫智慧合約時,您會經常從Ownable繼承。讓我們來看一個如何使用Ownable的示例。想象一下,您想在智慧合約中保留一個地址列表,但是您想成為唯一可以新增更多地址的列表。可以將其視為您信任的人的登錄檔。您可以執行以下操作:contract Whitelist is Ownable {   mapping (address => bool) members;
   constructor() public Ownable() {   }   function addMember(address _member)       public       onlyOwner   {
       members[_member] = true;   }}從Ownable繼承並在您的Ownable上呼叫其建構函式可確保將部署智慧合約的地址註冊為所有者。如果未透過註冊為所有者的地址呼叫,則onlyOwner修飾符會使函式恢復。部署此智慧合約後,只有您或您指定的人可以將新成員新增到其中的列表中。儘管有用,但很多時候Ownable還不夠。 在給定時間只有一個地址可以成為所有者,只有所有者可以決定誰可以成為新所有者,您只能檢查您是否是所有者,而不是其他人。
中級複雜方法— Whitelist.solWhitelist.sol保留一個地址列表,然後可用於限制功能或任何其他目的。它在功能上與OpenZeppelin的Roles.sol非常相似,儘管有一些重要差異。Whitelist.sol僅具有三個功能:function isMember(address _member) public view returns(bool);function addMember(address _member) public onlyOwner;function removeMember(address _member) public onlyOwner;
例如透過該智慧合約,您可以保留一份已批准的利益相關者列表,這些利益相關者可能是令牌轉移的唯一接收者。 您可以執行以下操作:pragma solidity ^0.5.0;import "@openzeppelin/contracts/token/ERC20/ERC20.sol";import "../access/Whitelist.sol";contract ERC20Whitelisted is ERC20 {   Whitelist whitelist;
   constructor(address _whitelistAddress) public {       whitelist = Whitelist(_whitelistAddress);   }   function transfer(address account, uint256 amount) public {       require(whitelist.isMember(account), "Account not whitelisted.");       super._transfer(account, amount);
   }}在上面的示例中,您還可以使ERC20Whitelisted繼承自ERC20和Whitelist。 我很樂意討論一些折衷方案。簡單的白名單功能可能非常強大。OpenZeppelin使用它們實現了許多ERC20和ERC721變體,並設法提供了超出我們大多數人所需的更多功能。在TechHQ,我們也僅使用白名單實施了CementDAO。但是有時候,白名單也會落空。您可能需要有多個所有者才能擁有白名單。或者您可能需要管理許多重疊的白名單。對於這些情況,我們具有分層的角色合約。高階複雜方法-RBAC.sol
我們開發了RBAC.sol,旨在提供與現代共享系統一樣的多使用者功能。1. 有些角色不過是地址組。2. 組成員資格只能由某些管理員角色的成員修改。3. 可以在執行時建立新角色。4. 可以驗證角色成員身份。在低層,我們使用使用者選擇的bytes32引數來標識角色。 通常,這些是可識別的短字串,但是您也可以使用加密的值或地址。
角色本身是一組成員地址和admin角色的識別符號。 有趣的是,我們不需要將角色的識別符號儲存在其自己的結構中。struct Role {    bytes32 adminRoleId;    mapping (address => bool) members;}現在有兩種方法可以新增新角色並驗證角色是否存在:
function roleExists(bytes32 _roleId) public view returns(bool);function addRole(bytes32 _roleId, bytes32 _adminRoleId) public;並且管理成員的功能是相同的,只是現在必須指定相關角色:function isMember(address _member, bytes32 _roleId) public view returns(bool);function addMember(address _member, bytes32 _roleId) public;function removeMember(address _member, bytes32 _roleId) public;
僅當呼叫者屬於我們要新增成員的角色的管理員角色時,addMember和removeMember才會成功。僅當呼叫者屬於將管理所建立角色的角色時,addRole才會成功。這些簡單的規則將允許建立角色的層次結構,然後可將其用於實現具有不同許可權級別或區域的複雜多使用者平臺。進階學習為了進一步深入兔子洞,我建議從OpenZeppelin的這個問題開始。他們的程式碼庫與我們的程式碼庫沒有什麼不同,即使在我們選擇採用其他方法的情況下,您也會發現大多數設計決策的透徹推理。他們在諸如ERC20Mintable之類的合約中使用Roles是一個很好的例子,可以替代Whitelist。勇敢者的另一個資源是AragonOS ACL合約。介面一眼就可以看出他們決定走得更遠:
function hasPermission(address who, address where, bytes32 what, bytes how) public view returns (bool);對於我們自己的@ hq20 / contracts包中的示例,我們使用本文中描述的三個級別的訪問控制,因此,您也應該注意這一點。結  論對於智慧合約的實現,最好僅實現所需的複雜性,而無需再實現任何複雜性。 在許可方面,存在三種不同的複雜性級別:· 單使用者
· 使用者群· 使用者組的層次結構您可以將Ownable.sol用於單個使用者允許的系統。 您可以將@ openzeppelin/Roles.sol或@ hq20/Whitelist.sol用於需要組中許可權使用者的系統。對於需要組層次結構的系統,我們過去已成功使用@ hq20/RBAC.sol。您將有自己的要求,並且需要權衡取捨。瞭解每個實現背後的設計決策將使您可以使用現有合約,也可以修改合約以供自己使用。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;