跟我学 Solidity:关于变量

开始在以太坊上编写智能合约

> * 来源:https://medium.com/better-programming/learn-solidity-variables-part-1-657fc27c2cc1作者:[智慧哈吉](https://wissal-haji.medium.com) > * 译文出自:[登链翻译计划](https://github.com/lbc-team/Pioneer) > * 译者:[翻译小组](https://learnblockchain.cn/people/412) > * 校对:[Tiny 熊](https://learnblockchain.cn/people/15) > * 本文永久链接:[learnblockchain.cn/article…](https://learnblockchain.cn/article/1758) 欢迎来到跟我学习Solidity系列中的第二篇文章。如果你还没有阅读[第一篇:Solidity入门](https://learnblockchain.cn/article/1755),我强烈建议你这样做以设置开发环境以及编写和部署第一个合约。 在本文中,我们将研究Solidity中的变量,它们的类型,它们的存储方式以及如何使用它们。 在[Solidity](https://learnblockchain.cn/docs/solidity/types.html)中,我们有两种类型的变量: ## 状态变量 这些变量在函数外部声明(例如类的属性),并永久存储在以太坊区块链中,更具体地说存储在存储Merkle Patricia树中,这是形成帐户状态的信息的一部分(这就是为什么我们称其为状态变量)。 ![diagram of Merkle Patricia tree](https://img.learnblockchain.cn/2020/11/18/mlqDId7g.png) > 以太坊Merkle Patricia树:[来源](https://medium.com/cybermiles/diving-into-ethereums-world-state-c893102030ed) 你可以找到有关数据存储在以太坊区块链中的更多信息,参考[文章](https://medium.com/cybermiles/diving-into-ethereums-world-state-c893102030ed). 状态变量可以在声明时进行初始化,并且具有以下可见性: - `private`:状态变量仅在定义的合约里可见。 - `public`:状态变量也可以在定义合约的外部访问,因为编译器会自动创建一个与该变量同名的getter函数。 - `internal`:状态变量在定义的合约以及所有继承合约都是可见的。 可见性指示符放在状态变量的类型之后,如果未指定,则状态变量将被视为`internal`。 ## 局部变量 这些是在函数内部声明的变量,其作用域限定在声明它们的代码块内。 ```js // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.7.0; contract HelloWorldContract { address owner; // 状态变量 function helloword() external pure returns(string memory){ string memory greeting ="hello world"; // 局部变量 return greeting; } } ``` 与其他任何语言一样,我们有基本数据类型和复杂数据类型。当用作函数参数或在赋值中时,基本数据类型始终按值传递,而复杂数据类型(如数组和结构体)则按引用传递。 ## 基本数据类型 ![table of Solidity elementary data types and what each may contain](https://img.learnblockchain.cn/2020/11/18/V5fu4Stw.png) > Solidity 基本数据类型 [有关地址类型的更多信息:](https://learnblockchain.cn/docs/solidity/types.html#address) - 地址字面常量:通过地址校验和测试的十六进制字面常量,例如`0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF`属于`address payable`类型。 - 类型转换:`address payable`可以隐式转换为简单的`address`类型,这表示你可以将`address payable`分配给`address`类型,而无需显式转换。 [整数字面常量](https://learnblockchain.cn/docs/solidity/types.html#rational-literals)和`bytes20`,可以使用以下语法:`address(x)`进行显式转换为地址。这种转换将产生`address payable`类型。 - [地址类型成员:](https://learnblockchain.cn/docs/solidity/units-and-global-variables.html#address-related)地址类型的两个重要成员是`balance`(允许查询地址的余额)和`transfer`(允许发送以wei单位的以太币到`address payable`类型的地址。 - [合约和地址类型:](https://learnblockchain.cn/docs/solidity/types.html#contract-types) 你可以使用之前看到的语法将合约明确转换为地址类型:` address(x)`,其中x是合约的一个实例。如果合约定义了[receive](https://learnblockchain.cn/docs/solidity/contracts.html#receive)函数或[fallback function](https://learnblockchain.cn/docs/solidity/contracts.html#fallback)函数(我们后面会介绍这两个函数的更多详情),则会转换为`address payable`,如果没有这两个函数,则转换为`address`,此时,如果你希望转换为payable,则必须使用` payable(address(x))`。 ## 全局可用变量 全局命名空间中始终存在一些特殊变量,这些变量主要用于提供有关区块链的信息。 我们可以将这些变量分为三类: 1. 区块属性 ![table of block types and what each main contain](https://img.learnblockchain.cn/2020/11/18/LuhTRS7Q.png) 2. 消息属性 ![table of message types and what each may contain](https://img.learnblockchain.cn/2020/11/18/eYTQwKiw.png) 3. 交易属性 ![table of transaction types and what each may contain](https://img.learnblockchain.cn/2020/11/18/CZE545Cw.png) 我们将大量使用的两个属性是`msg.sender`和`msg.value`,`msg.sender`可以向我们提供发送方的地址,从而可以保存合约所有者的地址,而`msg.value`则可以获取发送的金额。 举个例子(练习),我们保存合约创建者的地址并修改` HelloWorldContract`,这样,如果交易信息是由创建者发送的,我们将用` hello Daddy`向他们打招呼(编写`sayHello`方法)。否则,我们向发送者打招呼` hello world`。 ``` pragma solidity ^0.7.0; contract HelloWorldContract { address owner; // 状态变量 constructor() { owner = msg.sender; } function sayHello() external pure returns(string memory){ if(owner==msg.sender) { return "hello Daddy"; } string memory greeting ="hello world"; // 局部变量 return greeting; } } ``` 按照我们在[上一篇](https://learnblockchain.cn/article/1755)文章中看到的那样部署合约,然后单击`sayHello`,你将得到`hello Daddy`,因为你用于部署合约的地址与你用来调用该合约的地址相同功能。 让我们更改帐户,然后再次调用该功能。为了更改你的帐户,你需要单击“帐户”部分的下拉列表,然后选择其他地址。 ![Image for post](https://img.learnblockchain.cn/2020/11/18/IJL55PIA.png) 如果这次调用`sayHello`,你应该会得到` hello world`。 太好了,我们学到了一些东西。 在练习应用所学知识之前,我想提到一下,Solidity中的`this`关键字引用了当前合约的类型,并且可以明确转换为地址,正如我们在合约实例中看到的那样。 本文要结束了,尝试下完成以下作业: - 获取合约的地址。 - 获取合约所有者的地址。 - 获取发送者的地址。 - 获取合约余额。 - 获取合约所有者的余额(仅当发送者是所有者时)。 - 获取发送者的余额。 你可以在[GitHub](https://gist.github.com/wissalHaji/43ba02467834e5d07e42fa3a1978d15c)上找到解决方案. 希望你喜欢这篇文章。下次,我们将讨论复杂的类型,并揭示上一代码中我在`string`旁边使用的`memory`关键字背后的奥秘。因此,如果你想了解更多信息,请坚持学习,并在[下一篇](https://learnblockchain.cn/article/1759)文章中见。 ------ 本翻译由 [Cell Network](https://www.cellnetwork.io/?utm_souce=learnblockchain) 赞助支持。

  • 来源:https://medium.com/better-programming/learn-solidity-variables-part-1-657fc27c2cc1作者:[智慧哈吉](https://wissal-haji.medium.com)
  • 译文出自:登链翻译计划
  • 译者:翻译小组
  • 校对:Tiny 熊
  • 本文永久链接:learnblockchain.cn/article…

欢迎来到跟我学习Solidity系列中的第二篇文章。如果你还没有阅读第一篇:Solidity入门,我强烈建议你这样做以设置开发环境以及编写和部署第一个合约。 在本文中,我们将研究Solidity中的变量,它们的类型,它们的存储方式以及如何使用它们。

在Solidity中,我们有两种类型的变量:

状态变量

这些变量在函数外部声明(例如类的属性),并永久存储在以太坊区块链中,更具体地说存储在存储Merkle Patricia树中,这是形成帐户状态的信息的一部分(这就是为什么我们称其为状态变量)。

以太坊Merkle Patricia树:来源

你可以找到有关数据存储在以太坊区块链中的更多信息,参考文章.

状态变量可以在声明时进行初始化,并且具有以下可见性:

  • private:状态变量仅在定义的合约里可见。
  • public:状态变量也可以在定义合约的外部访问,因为编译器会自动创建一个与该变量同名的getter函数。
  • internal:状态变量在定义的合约以及所有继承合约都是可见的。

可见性指示符放在状态变量的类型之后,如果未指定,则状态变量将被视为internal

局部变量

这些是在函数内部声明的变量,其作用域限定在声明它们的代码块内。

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.7.0;

contract HelloWorldContract {

    address owner; // 状态变量

    function helloword() external pure returns(string memory){

        string memory  greeting ="hello world"; // 局部变量

        return greeting;
    }

}

与其他任何语言一样,我们有基本数据类型和复杂数据类型。当用作函数参数或在赋值中时,基本数据类型始终按值传递,而复杂数据类型(如数组和结构体)则按引用传递。

基本数据类型

Solidity 基本数据类型

有关地址类型的更多信息:

  • 地址字面常量:通过地址校验和测试的十六进制字面常量,例如0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF属于address payable类型。
  • 类型转换:address payable可以隐式转换为简单的address类型,这表示你可以将address payable分配给address类型,而无需显式转换。

整数字面常量和bytes20,可以使用以下语法:address(x)进行显式转换为地址。这种转换将产生address payable类型。

  • 地址类型成员:地址类型的两个重要成员是balance(允许查询地址的余额)和transfer(允许发送以wei单位的以太币到address payable类型的地址。

  • 合约和地址类型: 你可以使用之前看到的语法将合约明确转换为地址类型:address(x),其中x是合约的一个实例。如果合约定义了receive函数或fallback function函数(我们后面会介绍这两个函数的更多详情),则会转换为address payable,如果没有这两个函数,则转换为address,此时,如果你希望转换为payable,则必须使用payable(address(x))

全局可用变量

全局命名空间中始终存在一些特殊变量,这些变量主要用于提供有关区块链的信息。

我们可以将这些变量分为三类:

  1. 区块属性

  1. 消息属性

  1. 交易属性

我们将大量使用的两个属性是msg.sendermsg.valuemsg.sender可以向我们提供发送方的地址,从而可以保存合约所有者的地址,而msg.value则可以获取发送的金额。

举个例子(练习),我们保存合约创建者的地址并修改HelloWorldContract,这样,如果交易信息是由创建者发送的,我们将用hello Daddy向他们打招呼(编写sayHello方法)。否则,我们向发送者打招呼hello world

pragma solidity ^0.7.0;

contract HelloWorldContract {

  address owner; // 状态变量

  constructor() {
      owner = msg.sender;
  }

  function sayHello() external pure returns(string memory){
      if(owner==msg.sender) {
        return "hello Daddy";
      }

      string memory  greeting ="hello world"; // 局部变量

      return greeting;
  }

}

按照我们在上一篇文章中看到的那样部署合约,然后单击sayHello,你将得到hello Daddy,因为你用于部署合约的地址与你用来调用该合约的地址相同功能。

让我们更改帐户,然后再次调用该功能。为了更改你的帐户,你需要单击“帐户”部分的下拉列表,然后选择其他地址。

如果这次调用sayHello,你应该会得到hello world。 太好了,我们学到了一些东西。

在练习应用所学知识之前,我想提到一下,Solidity中的this关键字引用了当前合约的类型,并且可以明确转换为地址,正如我们在合约实例中看到的那样。

本文要结束了,尝试下完成以下作业:

  • 获取合约的地址。
  • 获取合约所有者的地址。
  • 获取发送者的地址。
  • 获取合约余额。
  • 获取合约所有者的余额(仅当发送者是所有者时)。
  • 获取发送者的余额。

你可以在GitHub上找到解决方案.

希望你喜欢这篇文章。下次,我们将讨论复杂的类型,并揭示上一代码中我在string旁边使用的memory关键字背后的奥秘。因此,如果你想了解更多信息,请坚持学习,并在下一篇文章中见。

本翻译由 Cell Network 赞助支持。

区块链技术网。

  • 发表于 2020-11-19 16:05
  • 阅读 ( 2816 )
  • 学分 ( 166 )
  • 分类:Solidity
  • 专栏:全面掌握Solidity智能合约开发

评论