N与name

弁言

在EOS智能合约中,你应当见到过相似如许的语句:

require_auth( N(user));

结合上一篇的内容,这句话的意义是指,搜检:在以后action的已受权的允许列表中,是不是存在user账号,若是存在,则甚么也不做;若是不存在,则抛出非常。

还记得我们之前写的hello合约吗?外面的hi 这个action的处置惩罚函数(handler)大抵是如许的:

      /// @abi action
void hi( account_name user ) {
require_auth( user );
print( "Hi, ", name{user} );
}

那末这个require_auth( user );与后面的require_auth( N(user) );有甚么区别呢?下一行中的name{user}又是甚么意义呢?
我们下面逐一解说。

N的用法

在EOS合约中,你会经常看到N的用法,它是甚么东西呢?实际上,它是一个宏界说:


/** * Used to generate a compile time uint64_t from the base32 encoded string interpretation of X * * @brief Used to generate a compile time uint64_t from the base32 encoded string interpretation of X * @param X - String representation of the name * @return constexpr uint64_t - 64-bit unsigned integer representation of the name * @ingroup types */
#define N(X) ::eosio::string_to_name(#X)

这是间接从eos源码中的types.h文件里,摘取出来的。可以或许看到N(x)等同于::eosio::string_to_name(#X)#X代表把X转化它的字面量的字符串形式,若是X是user,那末#X就即是"user"。这是C语言中宏界说的一种语法。

eosio::string_to_name是一个函数,它可以或许把一个字符串转化为一个数字。我们来看下它的界说:

/***  Converts a base32 string to a uint64_t. This is a constexpr so that*  this method can be used in template arguments as well.**  @brief Converts a base32 string to a uint64_t.*  @param str - String representation of the name*  @return constexpr uint64_t - 64-bit unsigned integer representation of the name*  @ingroup types*/static constexpr uint64_t string_to_name( const char* str ) {uint32_t len = 0;while( str[len] ) ++len;uint64_t value = 0;for( uint32_t i = 0; i <= 12; ++i ) {uint64_t c = 0;if( i < len && i <= 12 ) c = uint64_t(char_to_symbol( str[i] ));if( i < 12 ) {c &= 0x1f;c <<= 64-5*(i+1);}else {c &= 0x0f;}value |= c;}return value;}

详细在for轮回里的运算细节可以或许没必要穷究,它实际上是把传出去的字符串str看成一个base32编码的字符串,然后把它转化为对应的整数形式(uint64_t范例的)。

在EOS体系中,险些一切的标识性的name,都是以和base32编码可以或许相互转换的整数范例(详细是uint64_t)存在的。好比,账户名, 权限名,table的名字,多重署名提案的名字等等。

为了包管这些名字可以或许以base32位编码,而且能被一个对应的unint64_t整数独一标识,划定这些名字要知足以下请求:长度不超过12个字符,而且每一个字符必需是以下之一:.12345abcdefghijklmnopqrstuvwxyz

如今你应当知晓,为何账户名要有这些限定了吧?实在不止账户名,也不止下面的这些名字,哪怕是你未来自身的智能合约界说了一个可以或许标识某种耐久化数据的名字,最好也恪守这个商定,如此可以确保它能转化位uint64_t整型。
为何非要能转化为uint64_t呢?由于EOS体系的设想云云。能转化uint64_t是一个在效力和易用性下面的均衡,起首这12位字符可以或许透露表现32^12次方个名字,也就是2^60 次方,这是个天文数字,充足运用;同时不凌驾64位bit;其次,uint64_t数值,在现代的64位CPU上,一个时钟周期就可以或许运算一次。若是是uint128_t,则须要拆分红一个个64位的局部去运算,就慢了许多;若是uint32_t呢,缺乏64位,也异样须要一个时钟周期。所以64位刚恰好。

我们回到后面我们抛出的哪一个题目:

require_auth( user );require_auth( N(user) );有甚么区别?

require_auth(user)中,user是一个变量,它的值可能是bob也可以或许是carl,也或许为一个名为user"user"账户,以user变量的值而定。

我们看下hi这个action 处置惩罚器的函数声明:

void hi( account_name user );

eos在挪用action handler的时刻,传出去的account_name范例,实际上就是uint64_t范例,若是user变量所代表的账户的是bob,那末user自身并非"bob"字符串,而是它对应的uint64_t范例的值。

若是这里的user是bob账户,那末require_auth( user );就是在磨练:

bob账户是不是存在于以后action的已受权允许列表中。

require_auth( N(user) );是甚么意义呢?N(user)user转化成了"user"字符串代表的整数形式,那么require_auth( N(user) );的意义就是在校验:

名为user的账户是不是存在于以后action的已受权允许列表中。

name

name是一种范例,它的源码是如许的:

​
/** * Wraps a uint64_t to ensure it is only passed to methods that expect a Name and * that no mathematical operations occur. It also enables specialization of print * so that it is printed as a base32 string. * * @brief wraps a uint64_t to ensure it is only passed to methods that expect a Name * @ingroup types */
struct name {
/** * Conversion Operator to convert name to uint64_t * * @brief Conversion Operator * @return uint64_t - Converted result */
operator uint64_t()const { return value; }
// keep in sync with name::operator string() in eosio source code definition for name
std::string to_string() const {
static const char* charmap = ".12345abcdefghijklmnopqrstuvwxyz";
std::string str(13,".");
uint64_t tmp = value;
for( uint32_t i = 0; i <= 12; ++i ) {
char c = charmap[tmp & (i == 0 ? 0x0f : 0x1f)];
str[12-i] = c;
tmp >>= (i == 0 ? 4 : 5);
}
trim_right_dots( str );
return str;
}
/** * Equality Operator for name * * @brief Equality Operator for name * @param a - First data to be compared * @param b - Second data to be compared * @return true - if equal * @return false - if unequal */
friend bool operator==( const name& a, const name& b ) { return a.value == b.value; }
/** * Internal Representation of the account name * * @brief Internal Representation of the account name */
account_name value = 0;
private:
static void trim_right_dots(std::string& str ) {
const auto last = str.find_last_not_of(".");
if (last != std::string::npos)
str = str.substr(0, last + 1);
}
};
} // namespace eosio

就像name类的正文中说的那样,它的作用是把一个uint64_t的值转化位base32编码字符串形式,作用恰好和N相反。

再看下下面我们看过的hi 函数:

      /// @abi action
void hi( account_name user ) {
require_auth( user );
print( "Hi, ", name{user} );
}

name{user},这里user是个某个账户的整数形式,它本来的字符串多是"bob",也多是其他的名字。我们假设是"bob"吧,那末name{user}就是"bob"了。
这里在print函数外面,我们就可以打印出bob了,若是我们间接用print( "Hi, ",user );,那末打印出来的user局部,就是一个让人摸不着头脑的数字了。

所以,name这个类关于我们打印一个name名字。关于name{user}这句话的语法寄义,是实际上是挪用了name类的默许组织函数,生成了一个name工具,print函数在打印的时刻,会主动挪用name工具的to_string函数,转换为字符串并打印出来。由于本文着重于EOS,所以关于C++语法寄义,本文由于篇幅题目,只能点到为止,更多C++的信息,发起购置相干书本或许网上搜刮相干材料进修。

eos 账户名与uint64_t转换(N与name)相关推荐

  1. WIN10下更改计算机名、中文账户名

    对新买电脑装系统时,我们会创建一个本地账户,用于对电脑的设置.访问.这时候的用户名常常设置为中文.但很多软件对于中文支持不是很好,例如Git Bash,所以后期访问用户配置文件时经常出现很多问题.显示 ...

  2. xp怎么删除计算机管理员用户,windowsXP如何显示Administrator账户/如何删除计算机管理员权限的账户/如何更改账户名...

    windows XP 新建管理员账户后如何显示/登陆Administrator账户: 1.永久性操作 方法一:进入"控制面板"->"用户账户"->& ...

  3. windows11及以下系统怎么修改账户名

    由于一时兴起把公家台式机的系统给设置成了自己的名字,不耽误使用,但是自己心里不得劲,所以开始去网上找寻各种修改用户名的方法,但是看了很多都是说需要修改"本地用户和用户组",而win ...

  4. winserver修改计算机用户名,如何修改Windows系统的管理员账户名

    下面给大家分享的是如何彻底完美的实现修改Windows系统的管理员账户名,非常的简单实用,有需要的小伙伴可以参考下. 在Windows 安装的时候会输入一个用户名,电脑店装的一般都会设置成Admin之 ...

  5. Office2016登录的账户名和microsoft账户名不照应的解决方法

    照有些网友提示,更改微软账户名https://account.microsoft.com/profile/.能够更改微软账户名,但是更改成功后,office用户名一直无法更新过来.始终是第一次注册的微 ...

  6. win7账号切换计算机名,win7风林火山系统电脑如何修改系统账户名

    可能在此之前,小编需要先解释一下什么叫做win7 旗舰版的系统账户名,大家在登陆系统的时候,或者是在注销的时候,会需要选择一个账户进行登陆,当然,如果咱们的电脑中没有设置其他的用户的话,就只有一个选项 ...

  7. 计算机名、主机名、用户账户名与NetBIOS名有什么区别

    1.计算机名:右击"我的电脑",选择"属性",在"系统属性"对话框的"计算机名"选项卡里,可以设置计算机名.计算机名是对 ...

  8. win7家庭版开机登录画面多了一个管理员的账户名

    windows 7打开关闭administrator账户的方法 方法1:适合win7旗舰版,家庭版简化了.进入administrator帐户,打开"管理"(右键"计算机& ...

  9. win10pe系统计算机名修改,Win10怎么修改账户名?|Win10怎么改用户名称?

    有些用户在重装win10系统的时候,因为忘记在开始的时候修改账户名称,所以,重装完成后系统的账户名称会默认是Administer,但是有些用户想修改,却不知道应该怎么修改,所以PE吧就给大家带来了wi ...

最新文章

  1. modoer点评系统3.5_丰田“奥拓”正式亮相,油耗3.5L,配软顶敞篷+四开门,或4万起...
  2. java 教室借用管理系统_教师办事指南 | 借用教室
  3. JVM资源分析工具jprofiler使用简介
  4. 访问vue实例中的数据
  5. 查看mysql语句运行时间的2种方法
  6. 停车管理系统汽车到达汽车离去c语言,停车场管理系统 C语言实现
  7. .编写一个注解。并添加元注解,让该注解可以用在方法上,类上,和属性上
  8. centos6设置静态IP
  9. Diccuz!NT的dll版本号控制技巧
  10. bzoj1036 树的统计Count 树链剖分
  11. Selenium Webdriver 简易教程
  12. 一文简介常见的机器学习算法
  13. kotlin使用mapstruct(二)
  14. SYNOPSYS™使用不同透镜设计程序 来改善透镜设计
  15. 腾讯课堂后台扩容和性能优化实战
  16. IP 库的那些事儿之 2013 - 2014 流水帐版
  17. [025] 微信公众帐号开发教程第1篇-引言
  18. 电脑开机显示“Windows\system\vgaoem.fon”丢失的解决方法
  19. maven导入oracle驱动jar包
  20. 工具条研究手记(2) - 认识CToolBar工具条类

热门文章

  1. 阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
  2. Android加载网页JavaScript与Java之间的相互调用
  3. 艺术饭 x 版权猫:塔链科技“鲸确”精确云清算支持ArtFin艺术饭之文艺金融战略
  4. oracle存储过程rowcount用法,Oracle带输入、输出参数的存储过程回来受影响的行数SQL%ROWCOUNT...
  5. 视频压缩编码的一些概念
  6. Alfred安装与使用
  7. 数据结构实验四 约瑟夫生死游戏
  8. Mybatis plus 数据加密
  9. 经历困难后才能见阳光
  10. Oracle数据库双机热备方案