使用Solidity开发智能合约(二)
昨天,我们简单介绍了下Solidity与智能合约的结构。
使用Solidity开发智能合约,需要设置您的开发环境以及编写部署您的第一个合同,建议您先查阅该系列的第一篇文章【传送门:区块链研究实验室 | 使用Solidity开发智能合约(一)】。
在本文中,我们将研究Solidity中的变量,它们的类型,如何存储以及如何使用它们。在Solidity中,我们有两种类型的变量:
1.状态变量
这些变量在函数外部声明(例如类的属性),并永久存储在以太坊区块链中,更具体地说存储在存储Merkle Patricia树中,这是形成帐户状态的信息的一部分(这就是为什么我们称其为状态变量)。
以太坊Merkle Patricia树
您可以在本文中找到有关数据存储在以太坊区块链中的更多信息。
状态变量可以在声明时进行初始化,并且具有以下可见性:
private:状态变量仅在定义它的合同中可见。
public:状态变量也可以从定义它的协定外部访问,因为编译器会自动创建一个与该变量同名的getter函数。
internal:状态变量对于定义该合同的合同以及从该合同继承的所有其他合同都是可见的。
可见性说明符在状态变量的类型之后给出,如果未指定,则状态变量将被视为内部变量。
2.局部变量
这些是在函数内部声明的变量,其生存期限于声明它们的作用域。
// SPDX-License-Identifier: GPL-3.0pragma solidity ^0.7.0;contract HelloWorldContract { address owner; // state variable function helloWorld() external pure returns(string memory){ string memory greeting ="hello world"; // local variable return greeting; } }
与其他任何语言一样,我们有原始类型和复杂类型。当用作函数参数或在赋值中时,原始类型始终按值传递,而数组和结构等复杂类型则按引用传递。
3.原始数据类型
固体基本类型
有关地址类型的更多信息:
地址文字:通过地址校验和测试的十六进制文字,例如0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF是address payable类型。
类型转换:address payable可以隐式转换为simple address,这意味着您可以将应付地址分配给该地址,而无需显式转换。
// SPDX-License-Identifier: GPL-3.0pragma solidity ^0.7.0;contract HelloWorldContract { function transferFund(address payable receiver, uint amount) payable external { address newAddress = receiver; receiver.transfer(amount); // OK newAddress.transfer(amount); // shows an error }}
对于整数,整数文字并bytes20使用以下语法,允许显式转换为地址:address(x)。这种转换将产生一个address payable类型。
地址成员:地址类型的两个重要成员是balance,它允许查询地址的余额,和transfer,它允许将以太(以wei为单位)发送到应付款地址。
合同和地址类型:您可以使用我们之前看到的语法将合同显式转换为地址类型:address(x)在这种情况下,其中x是合同的一个实例。address payable如果合同定义了接收或应付款的后备功能(我们将在后面详细讨论功能),否则将产生一个合同address,否则,如果您希望它是可付款的,则必须这样做。使用payable(address(x))。
4.全局可用变量
全局命名空间中始终存在一些特殊变量,这些变量主要用于提供有关区块链的信息。
我们可以将这些变量分为三类:
(1)块属性
(2)邮件属性
(3)交易属性
我们将大量使用的两个属性是msg.sender,可以为我们提供发送者的地址,从而可以存储合同所有者的地址,并msg.value获得随消息发送的金额。
让我们举一个例子,在其中存储合同创建者的地址并进行修改,以HelloWorldContract使如果消息是由创建者发送的,我们将向他们打招呼“ hello Daddy;”。否则,我们用“ hello world”向发件人打招呼。
// SPDX-License-Identifier: GPL-3.0pragma solidity ^0.7.0;contract HelloWorldContract { string greeting; address owner; constructor() { greeting = "hello world"; owner = msg.sender; } function sayHello() external view returns(string memory) { if(msg.sender == owner) return "hello Daddy"; else return greeting; }}
如果按照我们在上一篇文章中看到的那样部署合同,然后单击sayHell,您将得到“ hello Daddy”,因为您用于部署合同的地址与您用来调用该函数的地址相同。
让我们更改帐户并再次调用该函数。为了更改您的帐户,您需要单击“帐户”部分的下拉列表,然后选择其他地址。
如果您sayHello这次打电话,您应该会得到“ hello world”。
在练习应用所学知识之前,我想提到一下this,Solidity中的关键字引用了当前合同的类型,并且可以明确地转换为地址,正如我们在合同实例中所看到的那样。
我现在将剩下的任务留给您作为练习:
合同的寄信人地址。
合同所有者的退货地址。
发件人的返回地址。
退还合同的余额。
返回合同所有者的余额(仅在发送者是所有者的情况下)。
返回发件人的余额。
Scan QR code with WeChat