5.4 交易鑑權

5.4.1 賬戶權限相關概念

權限

EOS採用父子分層的權限結構,低級權限(子權限)由高級權限(父權限)派生而來,父權限擁有子權限所有的能力。子權限能做的事父權限也能做,但是反過來,父權限能做的事,子權限不一定能做。

  • owner 是最高等級權限,擁有owner權限就意味着擁有賬戶的所有權,我們可以把owner理解爲超級管理員權限。
  • active 是owner的子權限,主要用來發送交易、投票或者進行高級別的賬戶修改操作。

權重

權限擁有者在權限中的重要程度,具體以不小於1的整數表示。

閾值

執行該權限的最低權重的臨界值,大於此臨界值就可以執行該權限了。

賬戶

執行操作的執行體,當一個賬戶被創建時,就具備了兩種基本權限(permission)。每個權限綁定在一個公鑰或多個公鑰上,還可以綁定到另一個有效的賬戶的權限(permission)上。

賬戶權限由權限(permission)、對應公鑰或另一個賬戶的權限(嵌套權限)、權重(weight)以及閾值(threshold)四個部分組成,賬戶下的權限結構如下:

5.4 交易鑑權

5.4.2 交易鑑權過程

當執行一筆交易時,通過權限驗證,可以開始執行,分成兩步:

  1. 獲取賬戶權限中的公鑰,通過錢包找到私鑰,然後通過私鑰對交易進行簽名;
  2. 從簽名串中解出公鑰,進行數字簽名認證(查看公鑰是否在賬戶權限中存在),如果存在則獲取此公鑰的權重,並比較權重是否大於權限的閾值,若大於閾值則鑑權通過;如果賬戶權限是多重嵌套權限,則需要把每個權限鑑權通過後的權重相加,把最後權重的總和與權限閾值做比較;

我們通過一個例子來說明權限的驗證過程:
賬戶account1加載token合約,執行account1轉賬給account2,5個SDF代幣,由account1執行;

./cleos set contract account1 ../../contracts/eosio.token -p account1@active
./cleos push action account1 transfer '[ "account1", "account2", "5.00 SDF", "m" ]' -p account1@active

創建賬戶時,系統同時會把賬戶下默認的權限設置好,寫入chainbase數據庫中,但可以通過命令修改賬戶下的權限的公鑰,嵌套關係,權重,閾值;

比如:賬戶account1的權限表如下表所示:
5.4 交易鑑權

因爲賬戶account1的權限表中存在嵌套關係:account2@active,則也需要賬戶account2的權限表,如下表所示:
5.4 交易鑑權

簽名交易過程

做操作push action時,會最終打包成交易,接下來需要對交易做簽名。
首先需要從賬戶account1中獲取權限中的所有公鑰,根據account1的權限表得到的required_keys如下:

{
    "EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC",
    "EOS8hSFZmpPrXvnT9YgT94hDfQ9S3vVddxpMvDBZL2MWL1XTD6aLK"
}

其次,通過required_keys列表在錢包中找到對應的私鑰,通過私鑰對交易數據簽名,生成兩個個簽名交易串signatures如下;

{
    "SIG_K1_K55WNdUGH3nvhqUmUXmZcYP7wvNs5sA3RGFrdgsoz1LtAfWSfWd4GTxAFvn66dFkzhGNBrPK4xPWvLcCnwLZzhDy8DhNXd",
    "SIG_K1_Y98JhdUGH3nvhqUmUXmZcYP7wvNdfgergrdrNJkjjkiUJjLKfWSfWd4GTxAFvn66dFgfdBrPK4xPWvLJIHIU4jI6iIiopL"
}

權限驗證過程

先了解下公私鑰的作用:

Private key: 5JaGpdrxRstRLZ9yNaCsAVhLmvYcAsyLRZ1BJiy8pEmDMZmNtij
Public  key: EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC

EOS系統採用的是DSA+ECC加密簽名算法,主要用於數字簽名和驗證;
私鑰主要用於簽名,公鑰用於驗證;

所以,首先需要從簽名串中解出公鑰,作爲權限驗證的輸入條件,根據上面的簽名結果signatures,解出公鑰列表provided_keys如下:

{
    "EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC",
    "EOS8hSFZmpPrXvnT9YgT94hDfQ9S3vVddxpMvDBZL2MWL1XTD6aLK"
}

看下account1賬戶下的信息:
5.4 交易鑑權

看下account2賬戶下的信息:
5.4 交易鑑權

修改account1賬戶下的信息:
5.4 交易鑑權

修改後的account1賬戶下的信息:
5.4 交易鑑權

account1轉賬給account2,5個SDF代幣:
5.4 交易鑑權

現在我們分析下執行轉賬的具體鑑權過程:

我們在代碼中關鍵點添加了一些打印信息,打印結果如下圖:
5.4 交易鑑權
trx.actions : 交易的所有action,需要驗證的所有action
provided_keys :簽名串中解出的公鑰列表,用於數字簽名認證,與權限對應的公鑰做比對
permisions_to_satisfy : 需要驗證的權限列表
authority_key : Key類型的權限列表
authority_accounts : 嵌套類型的權限列表
current weight : 鑑權過程中的當前權重,用做與閾值做比對的
current threshold : 鑑權需要的閾值

1.account1的active權限,閾值爲2,權限部分由兩部分組成:
(1).公鑰key權限,EOS8hSFZmpPrXvnT9YgT94hDfQ9S3vVddxpMvDBZL2MWL1XTD6aLK權限,權重爲1;
(2).嵌套的賬戶account2權限,權重爲1;account2的active權限對應EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC權限;

2.依次驗證active權限:
(1).驗證公鑰key權限,系統會拿出active的key權限,對應的公鑰是EOS8hSFZmpPrXvnT9YgT94hDfQ9S3vVddxpMvDBZL2MWL1XTD6aLK,然後拿這個公鑰在provided_keys中查找是否存在,如果存在,則判斷對應的權重是否大於等於閾值,若滿足,則鑑權通過,若不滿足,則需要加上嵌套賬戶account2權限的權重,求總和後,判斷是否滿足;

(2).驗證嵌套賬戶account2權限,賬戶account2的active的key權限,對應的公鑰是EOS8FERV2Qd6UQ5GvgB1VtAJmwg4C2WZjR6HMxPyfSJVYacNc8DPC,然後拿這個公鑰在provided_keys中查找是否存在,如果存在,則加上步驟一對應的權限,求出和,判斷總的權重是否大於等於account1的active權限的閾值,若滿足,則鑑權通過,若不滿足,則鑑權失敗;

從上面的打印結果可以看出,鑑權經過了兩次判斷,因爲account1的active權限的閾值爲2,而賬戶的的兩個權限的權重都爲1,所以需要兩次;

5.4.3 源碼分析鑑權過程

從上面的鑑權過程,我們可以知道,鑑權接口需要交易打包的actions和交易簽名解出來的公鑰列表;

看下action的定義:
5.4 交易鑑權
5.4 交易鑑權

從簽名串中解出公鑰:
5.4 交易鑑權
recover_keys()函數會調用下面的代碼,如圖:
5.4 交易鑑權
在push_transaction()會做鑑權驗證,接口爲check_authorization():
5.4 交易鑑權
在check_authorization()中做驗證時,分爲三步:
(1).驗證是否滿足最小權限;
(2).把滿足最小權限的權限加入到待驗證的權限列表中;
(3).對權限列表中的權限依次驗證;
5.4 交易鑑權
把滿足最小權限的權限加入到待驗證的權限列表中後,看下 permissions_to_satisfy 的定義:
map<permission_level, fc::microseconds> permissions_to_satisfy;
5.4 交易鑑權

開始驗證權限:
5.4 交易鑑權
5.4 交易鑑權
因爲weight_tally_visitor結構體重載了()操作符,所以在調用 visitor(permission_level_weight{permission, 1}) 時,會調用weight_tally_visitor結構體()操作符的重載函數;
5.4 交易鑑權
在satisfied()函數時,會按權限類型分類驗證;

先看下權限的分類定義:
5.4 交易鑑權
5.4 交易鑑權

遞歸調用key類型()的重載函數,判斷權限是否滿足權重大於等於閥值,如果大於等於閾值,則鑑權成功;
5.4 交易鑑權
5.4 交易鑑權

5.4.4 總結

總結:
1.有多個或多種權限的鑑權過程就是判斷滿足多個或多種權限對應的權重的總和是否大於等於執行者的權限閾值;
2.所有的嵌套的賬戶權限的驗證,最終都轉化爲驗證最小單位Key類型的權限驗證;
3.最小單位Key類型權限的驗證即對交易簽名串的簽名認證(證明是某個賬戶發起的交易),也就是驗證該權限對應的公鑰是否在簽名串解出的公鑰列表中存在;

鏈接

http://www.3heu.club:8008/
https://www.jianshu.com/p/0b7365ea43fe
https://blog.csdn.net/arm_snow/article/details/90318052

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章