开始在以太坊上编写智能合约
欢迎来到跟我学习Solidity系列中的第二篇文章。如果你还没有阅读[第一篇:Solidity入门](https://learnblockchain.cn/article/1755),我强烈建议你这样做以设置开发环境以及编写和部署第一个合约。
在本文中,我们将研究Solidity中的变量,它们的类型,它们的存储方式以及如何使用它们。
在[Solidity](https://learnblockchain.cn/docs/solidity/types.html)中,我们有两种类型的变量:
## 状态变量
这些变量在函数外部声明(例如类的属性),并永久存储在以太坊区块链中,更具体地说存储在存储Merkle Patricia树中,这是形成帐户状态的信息的一部分(这就是为什么我们称其为状态变量)。

> 以太坊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;
}
}
“`
与其他任何语言一样,我们有基本数据类型和复杂数据类型。当用作函数参数或在赋值中时,基本数据类型始终按值传递,而复杂数据类型(如数组和结构体)则按引用传递。
## 基本数据类型

> 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. 区块属性

2. 消息属性

3. 交易属性

我们将大量使用的两个属性是`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`,因为你用于部署合约的地址与你用来调用该合约的地址相同功能。
让我们更改帐户,然后再次调用该功能。为了更改你的帐户,你需要单击“帐户”部分的下拉列表,然后选择其他地址。

如果这次调用`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 作者:wissal haji
- 译文出自:区块链开发网翻译计划
- 译者:翻译小组
- 校对: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))
。
全局可用变量
全局命名空间中始终存在一些特殊变量,这些变量主要用于提供有关区块链的信息。
我们可以将这些变量分为三类:
- 区块属性
- 消息属性
- 交易属性
我们将大量使用的两个属性是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;
}
}
按照我们在上一篇文章中看到的那样部署合约,然后单击sayHello
,你将得到hello Daddy
,因为你用于部署合约的地址与你用来调用该合约的地址相同功能。
让我们更改帐户,然后再次调用该功能。为了更改你的帐户,你需要单击“帐户”部分的下拉列表,然后选择其他地址。
如果这次调用sayHello
,你应该会得到hello world
。 太好了,我们学到了一些东西。
在练习应用所学知识之前,我想提到一下,Solidity中的this
关键字引用了当前合约的类型,并且可以明确转换为地址,正如我们在合约实例中看到的那样。
本文要结束了,尝试下完成以下作业:
- 获取合约的地址。
- 获取合约所有者的地址。
- 获取发送者的地址。
- 获取合约余额。
- 获取合约所有者的余额(仅当发送者是所有者时)。
- 获取发送者的余额。
你可以在GitHub上找到解决方案.
希望你喜欢这篇文章。下次,我们将讨论复杂的类型,并揭示上一代码中我在string
旁边使用的memory
关键字背后的奥秘。因此,如果你想了解更多信息,请坚持学习,并在下一篇文章中见。
本翻译由 Cell Network 赞助支持。
本文参与区块链开发网写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。
- 发表于 2020-11-19 16:05
- 阅读 ( 4572 )
- 学分 ( 170 )
- 分类:Solidity