作者:科普 / 來源:IOST社區投稿
IOST賬戶系統簡介
IOST的賬戶由賬戶名(ID)和權限(permission)組成。一個賬戶中擁有若干權限,至少包含owner和active權限。每個權限中會登記若干條目(item) , item可以是 base58 編碼的公鑰,也可以是另一個賬戶的權限對。
而 item 是另一個賬戶的權限對時,表示方式為 用戶名@權限名
每個item都擁有一定的權重,而對應的,每個權限有一個閾值。當一筆交易中包含的item的權重之和大于閾值時,就認為這筆交易擁有這個權限。
判斷是否擁有這個item的標準就是交易的簽名是否包含這個item中公鑰對應的簽名(當這個item是一個公鑰時),或迭代地判斷該交易是否包含這個item 所記錄的賬戶-權限對(當這個item是一個賬戶-權限對時)。
總的來說,智能合約驗證權限時,會給出賬戶名和權限名,系統將檢查該筆交易的簽名,計算簽名當中包含的item權重,如果簽名足以提供這個權限, 則認為可以驗證通過,否則將會拒絕這此權限驗證。
active權限可以提供除了owner之外的所有權限,owner權限同樣可以提供這些權限,而且只有具備了owner權限才能修改owner和active權限下的item。 同時,發送一筆交易需要提供active權限。
權限可以通過組(group)進行操作。可以將權限加入一個組,然后將在組內添加item。這樣,一個item就能擁有這個組里所有的權限。
IOST賬戶系統的使用
在智能合約層面,有非常簡單的API可供使用
blockchain.requireAuth(id, permission_string)Copy
它將返回一個bool,需要判斷是否成立來進行下一步操作。
通常來說,使用用戶的ram和token時,應當先檢查用戶是否提供active權限,否則智能合約可能在開發者不希望的地方throw, 其他時候,permission_string應當設置為一個不與其他地方重復的名字。這樣可以最小化權限。
原則上說不應當require "owner",用戶沒有義務在不需修改owner,active秘鑰的情況下提供owner key
不需要require某筆交易的發起者,因為他總是擁有active權限。
在用戶層面,只有提供簽名這個動作可以為交易添加權限。假設有如下兩個賬戶: (注,示例賬戶中所有key默認weight=1,所有permission默認threshold=1)
User0 ├── Groups │ └── grp0: key3 └── Permissions ├── owner: key0 ├── active: key1 ├── perm0: key2, grp0 ├── perm1: User1@active, grp0 ├── perm2(threshold = 2): key4, key5, grp0 ├── perm3: key8 └── perm4(threshold = 2): User@perm3, key9 User1 └── Permissions ├── owner: key6 └── active: key7Copy
以下是requireAuth的表格
參數 | 簽名的key | 返回 | 說明 |
---|---|---|---|
User0, perm0 | key2 | true | 提供權限對應的公鑰的簽名即擁有權限 |
User0, perm0 | key3 | true | 提供權限組對應的公鑰可以擁有組下所有權限 |
User0, perm0 | key1 | true | 提供active權限即可擁有用戶名下除了owner之外的所有權限 |
User0, perm1 | key7 | true | key7提供了User1@active權限,因此也提供了perm1 |
User0, owner | key1 | false | active不能提供owner權限 |
User0, active | key0 | true | owner提供該用戶一切權限 |
User0, perm2 | key4 | false | 沒有提供足夠threshold的簽名 |
User0, perm2 | key4,key5 | true | 提供足夠threshold的簽名 |
User0, perm2 | key3 | true | 權限組不計算threshold |
User0, perm2 | key1 | true | active不計算threshold |
User0, perm4 | key8 | false | 如需要計算權限組的weight,可以這樣實現 |
IOST賬戶的創建和管理
賬戶的管理基于智能合約auth.iost
,其ABI如下:
{ "lang": "javascript", "version": "1.0.0", "abi": [ { "name": "signUp", // 創建賬號 "args": ["string", "string", "string"] // 用戶名,ownerKey ID,activeKey ID }, { "name": "addPermission", // 添加權限 "args": ["string", "string", "number"] // 用戶名,權限名,權限的閾值 }, { "name": "dropPermission", // 刪除權限 "args": ["string", "string"] // 用戶名,權限名 }, { "name": "assignPermission", // 指定權限給item "args": ["string", "string", "string","number"] // 用戶名,權限,公鑰ID或賬戶名@權限名,權重 }, { "name": "revokePermission", // 撤銷權限 "args": ["string", "string", "string"] // 用戶名,權限,公鑰ID或賬戶名@權限名 }, { "name": "addGroup", // 添加權限組 "args": ["string", "string"] // 用戶名,組名 }, { "name": "dropGroup", // 刪除權限組 "args": ["string", "string"] // 用戶名,組名 }, { "name": "assignGroup", // 指定item給權限組 "args": ["string", "string", "string", "number"] // 用戶名,組名,公鑰ID或賬戶名@權限名,權重 }, { "name": "revokeGroup", // 撤銷權限組的item "args": ["string", "string", "string"] // 用戶名,組名,公鑰ID或賬戶名@權限名 }, { "name": "assignPermissionToGroup", // 添加權限到組 "args": ["string", "string", "string"] // 用戶名,權限名,組名 }, { "name": "revokePermissionInGroup", // 刪除組中的權限 "args": ["string", "string", "string"] // 用戶名,權限名,組名 } ] }Copy
賬戶名的命名只可以使用[a-z0-9_],長度不小于5,不大于11。權限名,組名也只能使用[a-zA-Z0-9_],長度不小于1,不大于32。
通常,賬戶在申請時就需要質押IOST,否則賬戶將無法使用,例如,iost.js的做法如下:
newAccount(name, ownerkey, activekey, initialRAM, initialGasPledge) { const t = new Tx(this.config.gasPrice, this.config.gasLimit, this.config.delay); t.addAction("iost.auth", "signUp", JSON.stringify([name, ownerkey, activekey])); t.addAction("iost.ram", "buy", JSON.stringify([this.publisher, name, initialRAM])); t.addAction("iost.gas", "pledge", JSON.stringify([this.publisher, name, initialGasPledge])); return t }Copy
為了優化賬戶創建的流程,目前的扣費是這樣的:創建賬戶的交易,其gas是由交易的publisher付費,其ram(就是新賬戶產生需要的ram)也由publisher代付。 當被創建的賬戶增加了賬戶的ram大小時,由之前publisher代付的ram將會退回給其擁有者,然后被創建賬戶將會為自己的賬戶ram付費。
創建賬號時,可以選擇為被創建的賬戶購買ram和質押token,建議為被創建賬戶質押最少10個token,以便被創建賬戶有足夠的Gas使用網絡。 賬號的Gas質押至少要剩余10個Token,保證賬號在任何情況下,都有足夠的Gas來購買資源。