solidity基础(1)

solidity基础-1

ReadMe
测试环境:系统win10x64,solidity版本:0.4.18
声明:该笔记参考Solidity入门系列,同时我会把学习时的错误理解也写出来,然后用删除线区别

  1. 整数
    • 简介:
      • solidity支持有符号整数和无符号整数
      • 所占位数可以指定从int8/uint8int256/uint256,以8为步长,递增不同的长度;int/uint默认都是256位。
      • 整数支持数学运算符,位运算符和比较运算符
        • 数学运算符:+,-,一元+,一元-,*,/,%,**(求幂)
        • 位运算符:&,|,^,~
        • 比较运算符:<=,<,==,!=,>=,>
    • 除法截断:
      • 字面量:是一种用于表达源代码中一个固定值的表示法
      • 和其他语言一样,整数的除法运算总会被截断,例如:1/4=0,【但是使用字面量的方式则不会截断,例如:var e = 1/4,当然可能也是var本身就具有智能推断的功能】此段待商榷
    • 移位:
      • 左移<<:相当于乘法,和C语言中的用法相同
      • 右移>>:相当于除法,和C语言中的用法相同
      • 所以:移位并不会改变符号位
      • 注意:右移最小是0,例如:1>>4=0
    • 异常:除以0或者对0取模,对一个值移负数位都会报异常
    • 溢出:
      • 上溢:如果一个整型变量的值达到其类型的上限,再给它加上一个正数,最终结果会是(变量值 + 正数) - 类型上限
      • 下溢:如果一个整型变量的值达到其类型的下限,再减去一个正数,会变成它的上限值-该正数的值

  2. 地址
  • 对比:以太坊提供的是账户模型,而比特币提供的是UTXO模型
  • 地址(address):
    • 一个地址代表一个账户,账户可以是普通的个人账户,也可以是包含代码的合约账户;因此在某些时候,地址代表的是一份合约代码
    • 长度:固定20字节
    • 支持的操作符:<=,<,==,!=,=,>
    • 成员:
      • balance:查询地址的余额,可以用this.balance来直接查询当前合约的余额,类型为uint
      • send:使用send()来向某个地址转账(货币单位是wei)
      • call(),callcode(),delegatecall():支持传入任意类型的任意参数来直接与合约进行交互
  • 参考资料:
  1. 以太币支付
    • payable标识符:
      • 函数上增加payable标识,即可接收ether,并会把ether存在当前合约
    • send()函数发送ether
      • 地址对象中的send()可以向某地址直接进行支付
        • 如果是普通地址将会直接收到
        • 但是合约要接收通过send()函数发送的ether,会有限制
          1. 如果我们要在合约中通过send()函数接收,就必须定义fallback函数,否则会抛异常
          2. fallback函数必须增加payable关键字,否则send()执行结果将会始终为false
    • 支付中可能的失败
      • send()失败
        1. 由于调试者可以强制指定调用堆栈的深度,当调用的栈深超过指定值时,一般为1024
        2. 接收地址处理支付过程中out of gas,即gas不够时
      • 合约的fallback()
        如果是合约地址,在执行send()时,默认关联执行fallback(),这是EVM的默认行为,不可阻止,所以这个函数引起的失败,交易会被撤销,send()为false

        EVM:以太坊虚拟机,参考资料
      • payable标识
        如果一个函数要进行货币操作,必须带上payable关键字,这样才能正常接收msg.value
    • 参考资料:
  2. 定长字节数组
    • 简介:
      • 定义定长字节数组的方式是bytesN,N的取值范围1~32byte默认标识bytes1
      • 定长字节数组的步长为1,整数类型的步长为8
    • 定义新变量
      定义新变量时可以使用整数字面量,或者字符串字面量
      • bytes1 a = 255;
      • byte a = "a";
      • 用整数字面量定义时,注意取值范围,如:byte整数范围为-128~255
    • 运算符:
      • 比较运算符有<=,<,==,!=,>,=>,返回的结果为bool类型
      • 位运算符:&,|,^,~,<<,>>
        移位操作符的右值必须为整数,移位操作同样也要注意越界问题,越界会抛异常;如:byte a = 'a' << 1,会报错,但是可以byte b = 'a';byte a = b << 1这样通过中间变量来避免报错
      • 不支持数学运算符
    • 使用序号访问定长字节数组:
      可以使用序号来访问定长字节数组的某个字节;但是序号的取值不能超过定长字节数组的长度,和数组类似
    • 长度:
      定长字节数组提供了一个只读属性.length来查看其长度,.length的返回值类型是uint8

  3. 函数
    • 关键字:function,类似于go语言中的func

    • 函数的参数:类似于C语言的函数参数,同样分实参和形参

    • 命名参数:函数调用可以使用命名参数,将参数名和参数值这样的键值对以任意顺序放进{}即可,类似于go语言中的map

       function f(uint k,uint v) returns(uint,uint) {
           return (k,v);
       }
       function g() returns(uint,uint) {
         return f({v:2,k:1});
       }
      
    • 函数的返回值:

      • 返回值的定义与参数类似,跟在returns之后即可,如果在返回值中已经定义了变量,可以不调用return,直接返回变量即可

        function f(uint a,uint b) returns(uint r) {
           r = a + b;
         }
        
      • return关键字:和其他语言类似

    • 函数的高级特性:
      函数还支持跨合约函数调用的可见性控制,函数级别货币支付支持,函数级的访问控制等独有特性

  4. 函数的可见性与访问权限控制
    • 简介:
      介绍solidity作为一个分布式网络语言所特有的internalexternal这两种不同的函数调用方式,以及solidity提供的对函数调用的可见性控制语法
    • 调用方式:
      1. internal:
        internal调用,实现时转为简单的EVM跳转,所以可以直接使用上下文环境中的数据,对于引用传递时将会变得非常高效
        在当前的代码单元内,如对合约内函数,引入的库函数,以及父类合约中的函数直接使用即是以internal方式的调用

         pragma solidity ^0.4.18;
         contract Test {
         function f() {}
         //以internal的方式调用
         function call() {
           f();
           }
         }
        
      2. external:

        external调用,实现为合约的外部消息调用,所以在合约初始化时不能以external的方式调用自身函数,因为合约还未初始化完成

         pragma solidty ^0.4.18;
         //contract afunction
         contract Afunction {
           //function f(uint k) external returns
           function f(uint k) returns(uint r) {
             r = k;
           }
         }
        
         contract bfunction {
           //以external的方式调用另一合约中的函数
           //function callAfunction(afunction a)
           function callAfunction(Afunction a) {
             a.f(4);
           }
         }
        

        和go语言一样,合约的首字母必须为大写才可以被外部合约调用;如果不大写的话,就必须为函数加上external,不然不能调用
        external调用时,实际是向目标合约发送一个消息调用。消息中的函数定义部分是一个24字节大小的消息体,20字节为地址,4字节为函数签名

      3. this
        我们可以在合约的调用函数前加this.来强制以external的方式调用,需要注意的是,这里的this的用法与大多数语言都不一致。
        当然,我们回到上面看一下external的说明,在合约初始化时不能以external的方式来调用自身函数,所以强制调用会报错,这也从反方面说明this.的确是以external方式调用

      4. 调用方式说明:
        上面所提到的internalexternal指的是函数调用方式,请不要与后面的函数可见性声明:external,public,internal,pravite弄混,声明只是意味着这个函数需要使用相应的调用方式去调用。后续说明中会用以某某方式调用,来强调是对调用方式的阐述以加以区分

    • 函数的可见性
      • 简介:solidity为函数提供了四种可见性:external,public,internal,pravite

      • external:

        • 声明为external的函数可以从其他合约或通过Transaction进行调用,所以声明为external的函数是合约对外接口的一部分
        • 不能以internal的方式进行调用
        • 有时在接收大的数据数组时性能更好

          声明为external的函数只能以external的方式进行调用;在同一个合约中调用声明为external的函数,要用this.强制调用,以internal的方式调用会报错
      • public:

        • 函数默认声明为public

        • pubic的函数允许以internal的方式调用,也允许以external的方式调用

        • public的函数由于被外部合约访问,所以是合约对外接口的一部分

           pragma solidity ^0.4.18;
           contract FunctionTest {
             function publicFunc() {}
          
             function callFunc() {
               //以internal的方式调用
               publicFunc();
               //以external的方式调用
               this.publicFunc();
             }
           }
          
      • internal:

        • 在当前的合约或继承的合约中,声明为internal的函数只允许以internal的方式调用

           pragma solidity ^0.4.18;
           contract functionTest {
             //默认是public函数
             function internalFunc() internal{}
             function callFunc() {
               //当前函数中的调用
               internalFunc();
             }
           }
          
           //solidity中用contract B is A
           //来表示,B是A的继承
           contract functionTest1 is functionTest {
             function callinernalFunc() {
               //子合约中的调用
               internalFunc();
             }
           }
          
      • pravite:

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

推荐阅读更多精彩内容

  • 原文:Smart contracts 正如我们在[intro]中看到的那样,以太坊中有两种不同类型的帐户:外部拥有...
    Jisen阅读 4,925评论 1 7
  • 1. 合约A中引用合约B,是根据 import和路径 引用。一旦合约A编译完成,那么意味着合约B此时此刻的abi...
    _Danniel_阅读 4,710评论 0 11
  • 声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互...
    凯哥学堂阅读 424评论 0 0
  • 选修这门课,主要是因为题目很有趣,批判性思维于我这种逻辑性不怎么强的人来说就是一种吸引力。从前对于批判性思维的理解...
    爱自由的Noqia阅读 155评论 0 0