5.4 交易鉴权

5.4.1账户权限相关概念

权限

EOS采用父子分层的权限结构,低级权限(子权限)由高级权限(父权限)派生而来,父权限拥有子权限所有的能力。子权限能做的事父权限也能做,但是反过来,父权限能做的事,子权限不一定能做。

- owner 是最高等级权限,拥有owner权限就意味着拥有账户的所有权,我们可以把owner理解为超级管理员权限。

active 是owner的子权限,主要用来发送交易、投票或者进行高级别的账户修改操作。

权重

权限拥有者在权限中的重要程度,具体以不小于1的整数表示。

阈值

执行该权限的最低权重的临界值,大于此临界值就可以执行该权限了。

账户

执行操作的执行体,当一个账户被创建时,就具备了两种基本权限(permission)。每个权限绑定在一个公钥或多个公钥上,还可以绑定到另一个有效的账户的权限(permission)上。

账户权限由权限(permission)、对应公钥或另一个账户的权限(嵌套权限)、权重(weight)以及阈值(threshold)四个部分组成,账户下的权限结构如下:

图1

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的权限表如下表所示:

图2

因为账户account1的权限表中存在嵌套关系:account2@active,则也需要账户account2的权限表,如下表所示:

图3

签名交易过程

做操作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账户下的信息:

图4

看下account2账户下的信息:

图5

修改account1账户下的信息:

图6

修改后的account1账户下的信息:

图7

account1转账给account2,5个SDF代币:

图8

现在我们分析下执行转账的具体鉴权过程:

我们在代码中关键点添加了一些打印信息,打印结果如下图:

图9

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的定义:

图10
图11

从签名串中解出公钥:

图12

recover_keys()函数会调用下面的代码,如图:

图13

在push_transaction()会做鉴权验证,接口为check_authorization():

图14

在check_authorization()中做验证时,分为三步:

(1).验证是否满足最小权限;

(2).把满足最小权限的权限加入到待验证的权限列表中;

(3).对权限列表中的权限依次验证;

图15

把满足最小权限的权限加入到待验证的权限列表中后,看下 permissions_to_satisfy 的定义:

map<permission_level, fc::microseconds> permissions_to_satisfy;

图16

开始验证权限:

图17
图18

因为weight_tally_visitor结构体重载了()操作符,所以在调用 visitor(permission_level_weight{permission, 1}) 时,会调用weight_tally_visitor结构体()操作符的重载函数;

图19

在satisfied()函数时,会按权限类型分类验证;

先看下权限的分类定义:

图20
图21

递归调用key类型()的重载函数,判断权限是否满足权重大于等于阀值,如果大于等于阈值,则鉴权成功;

图22
图23

5.4.4 总结

1.有多个或多种权限的鉴权过程就是判断满足多个或多种权限对应的权重的总和是否大于等于执行者的权限阈值;

2.所有的嵌套的账户权限的验证,最终都转化为验证最小单位Key类型的权限验证;

3.最小单位Key类型权限的验证即对交易签名串的签名认证(证明是某个账户发起的交易),也就是验证该权限对应的公钥是否在签名串解出的公钥列表中存在;

链接

星河公链

5.4 交易鉴权-wx5ca1790914ac4的博客-51CTO博客

5.4 交易鉴权 - arm_snow的博客 - CSDN博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容