主页 > imtoken钱包app下载链接 > 链桥教育在线|智能合约入门——以太坊智能合约学习笔记(一)

链桥教育在线|智能合约入门——以太坊智能合约学习笔记(一)

imtoken钱包app下载链接 2023-08-11 05:08:27

以太坊智能合约学习笔记(一)

58672f50188dab6cf222782f0966a3f3.jpeg

前言

以太坊的目标是创建一个运行智能合约的去中心化平台,并根据程序代码的设置来运行应用程序。 目的是确保程序运行时不存在审查、欺诈、宕机和第三方人为干预的可能。 开发者可以使用官方工具在其上开发、部署和运行智能合约。

一些术语的解释 1. 图灵完备

图灵完备性来源于计算机的概念,指的是一种程序代码语言加上计算规则,可以在图灵机上运行。 符合这一点的逻辑系统、设备或编程语言都可以认为是图灵完备的。 图灵完备的语言包括循环执行语句、判断分支语句等,理论上可以解决任何算法。 那么它的一个显着特点就是支持程序连续运行。 缺点是可能会进入死循环,导致程序崩溃。

2. 智能合约

img-hmKDeMta-1617168900726

智能合约的概念最早由 Nick Szabo 于 1995 年提出,是一种旨在以信息化方式传播、验证或执行合约的计算机协议。 智能合约允许在没有第三方的情况下进行可信交易,具有可追溯性和不可逆性。智能合约的目的是提供一种优于传统合约条款执行的安全方法,降低合约相关交易成本

智能合约以数字形式执行,这意味着合约必须以计算机可读代码的形式呈现。 只要双方达成一致,智能合约履历的权利义务将由计算机或计算机网络执行。

合约的作用

(1) 维护存储的数据。

(2) 服务于访问规则复杂的EOA账户

(3) 管理执行中的合同

(4) 向其他合约提供功能。

3. 智能合约与DApps的关系与区别

DApp(Decentralized App),即去中心化应用,是一种基于智能合约的应用。 其目的是使智能合约具有友好的界面,并扩展一些附加功能以太坊的实际用途,例如分布式存储。 与传统网站不同,DApp 不能运行在普通服务器上,而是运行在以太坊交互节点或与以太坊节点交互的中心化服务器上​​。 交易需要提交到区块链,并从区块链中读取区块链中的重要数据。 用户在区块链网络上表现为一个“钱包”地址,其他用户数据存储在本地,区别于传统的用户登录系统。

655c9094a426b0ffbc5a2fff36c8a229.jpeg

一个完整的DApp流程如下:

1)用Solidity(或其他语言)编写智能合约(后缀为.sol)。

以太坊为什么叫以太坊_以太坊的实际用途_以太坊和以太经典未来哪个好

2) 使用唯一编译器将.sol 合约编译成EVM 字节码。

3)编译后的字节码回传给DApp前端。

4) 前端将编译好的智能合约部署到区块链上。

5)区块链返回智能合约地址+ABI(即合约接口)。

6)前端通过Address+ABI+nonce调用智能合约。

7) 智能合约开始处理。

4. 智能合约开发语言solidity

img-msYqHW4Y-1617168900732

Solidity语言是一种专门用于编写和执行智能合约的语言。 它是一种基于以太坊虚拟机运行的面向合约的高级语言。 它最初由以太坊前 CTO 和联合创始人于 2014 年 8 月创立。 它是由 Gavin Wood 提出的,后来以太坊开发者组成了一个专门的团队来不断改进 Solidity 语言。 它仍在开发和优化中。 GitHub上的开发存储区是https:/github。 com/thereum/solidity,在这里我们可以了解到最全面的Solidity语言开发迭代的流程细节和相关文档。

在语言风格上,Solidity语言深受三种语言的影响:C++、Python和JavaScript。 它是一种以字节码方式编译的静态类型编程语言,因此可以在以太坊虚拟机上运行。 Gavin Wood 在开发 Solidity 语言时,借鉴了 JavaScript 的 ECMAScript 脚本语言的语法规则,使其与现有的 Web 开发语言有些相似,但实际上却有很大的不同。 例如,Solidity 语言有静态类型和变量返回函数。 最重要的一点是Solidity语言可以编写具有自执行业务逻辑的合约并嵌入到智能合约中,所以它不仅是以太坊的基本编程语言之一 ,也是大多数其他基于以太坊的,智能合约。 合约的各种区块链产品(Blockchain 2.0)的基本编程语言在当前大多数区块链产品中被广泛使用。 例如Hyperledger项目就是用Soliditv语言开发的。

简单的智能合约代码

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.8.0;
contract SimpleStorage {
    uint storedData;
    function set(uint x) public {
        storedData = x;

以太坊的实际用途_以太坊为什么叫以太坊_以太坊和以太经典未来哪个好

} function get() public view returns (uint) { return storedData; } }

第一行是注释,用于说明源代码的许可版本为:GPL3.0。 分发源代码时,需要在代码中包含机器可读的许可证。

第二行用于指定源码的版本,即solidity的版本范围为:0.4.16以上(含)0.8.0以下(不含)。 这行代码是为了防止编译器在编译代码时出现version异常而设置的。 pragma的意思是告诉编译器如何处理源代码指令。

接下来,contract 关键字声明了一个名为 SimpleSotrage 的合约结构。 合同是存储在以太坊区块链上特定地址的代码和数据的组合。

uint storedData ,声明一个名为 storedData 的 uint(256 位无符号)整数,用于存储特定的整数数据。 无符号表示数的最小值为0,不能存储负数。 数据将存储在以太坊的特定位置。

声明了storedData之后,有一个函数(function):named set,指定了一个参数,uint x,是一个无符号整数x,访问权限是public的,也就是公开的,任何人都可以访问和访问用它。 将参数x中保存的数据传送到storedData表示的数据地址。

另一个函数get的作用与set相反,它的作用是读取storedData中存储的数据。

对于以太坊,上述合约是拥有合约。

要访问状态变量,需要这样的前缀。 不是必需的,尽管这在其他语言中是常​​见的做法。

合约非常简单,只能做两件事: 1. 允许任何人在合约中存储一个数字; 2.这个号码全世界任何人都可以访问,没有任何可行的方法可以阻止你发布这个号码。 当然,任何人都可以再次调用 set,传入不同的值,覆盖之前的数字,但该数字仍会存储在区块链的历史记录中。

货币合约(子货币)示例

下面的合约实现了最简单的加密货币。 在这里,币确实可以无中生有,但只能由创建合约的人产生(实施不同的发行计划并不困难)。 此外,任何人都可以将硬币转移给其他人,不需要注册用户名和密码——只需要一个以太坊密钥对。

// SPDX-License-Identifier: GPL-3.0

以太坊和以太经典未来哪个好_以太坊为什么叫以太坊_以太坊的实际用途

pragma solidity >=0.7.0 <0.9.0; contract Coin { // 关键字“public”让这些变量可以从外部读取 address public minter; mapping (address => uint) public balances; // 轻客户端可以通过事件针对变化作出高效的反应 event Sent(address from, address to, uint amount); // 这是构造函数,只有当合约创建时运行 constructor() { minter = msg.sender; } function mint(address receiver, uint amount) public { require(msg.sender == minter); require(amount < 1e60); balances[receiver] += amount;

以太坊的实际用途_以太坊和以太经典未来哪个好_以太坊为什么叫以太坊

} function send(address receiver, uint amount) public { require(amount <= balances[msg.sender], "Insufficient balance."); balances[msg.sender] -= amount; balances[receiver] += amount; emit Sent(msg.sender, receiver, amount); } }

这个合约比上一个稍微复杂一点,所以让我们解释一下:

第一行仍然是代码许可证,第二行是编译后的版本。

接下来是合约的名称,这次我们将其命名为Coin。

第 6 行地址 public minter; 这一行声明了一个名为 minter 的可访问变量,用于存储地址(address)。 地址类型为整数,长度为 160 位,但不允许任何计算操作。 这种类型适用于存储外部方的合约地址或密钥对。 关键字public 表示允许外部访问。 在编译时,编译器会自动生成一个函数,允许从合约外部访问这个状态变量的当前值。 编译器生成的函数的代码大致如下(external view就是external access):

function minter() external view returns (address) { return minter; }

需要注意的是,这个函数已经由编译器自动为我们生成了,我们不需要再写了:)。

第 7 行,映射(地址 => uint)公共余额; 这里新建了一个变量balances,但是它的类型是映射(mapping),是一种比较复杂的数据类型,可以看到它的括号中的映射描述是用来建立地址address和一个uint值的对应关系,即可以通过这个地址从这个映射表中得到一个uint值。 程序运行时,映射会有一个初始化过程,初始uint值都是0。同样,public关键字也会创建一个access函数,只不过这次会返回地址映射的uint值,大致如下:

function balances(address _account) external view returns (uint) {

以太坊为什么叫以太坊_以太坊和以太经典未来哪个好_以太坊的实际用途

return balances[_account]; }

可以看到,通过这个功能可以很方便的查询到账户的余额。

第 10 行,事件发送(地址来自,地址至,单位数量); 这一行声明了一个“事件(event)”,它将在发送函数的最后一行(第 27 行代码)发出,使用 emit 关键字触发一个事件。 用户界面(当然还有服务器应用程序)可以监听在区块链上发送的事件而无需太多成本。 一旦发出,所有监听该事件的监听器都会收到通知。 并且所有事件都包含from、to和amount三个参数以太坊的实际用途,可以方便跟踪交易。 为了监听这个事件,你可以使用下面的 JavaScript 代码(假设 Coin 是一个通过 web3.js 创建的合约对象:

Coin.Sent().watch({}, '', function(error, result) {
    if (!error) {
        console.log("Coin transfer: " + result.args.amount +
            " coins were sent from " + result.args.from +
            " to " + result.args.to + ".");
        console.log("Balances now:\n" +
            "Sender: " + Coin.balances.call(result.args.from) +
            "Receiver: " + Coin.balances.call(result.args.to));
    }
})

这里,请注意自动生成余额函数是如何从用户界面调用的(事件监控代码的第 8 和 9 行)。

合约代码第13行,constructor是一个构造函数,只在合约创建过程中运行,之后无法调用。 它永久存储创建合同的人的地址: msg (以及 tx 和 block )是一个特殊的全局变量,包含一些允许访问区块链的属性。 msg.sender 始终是当前(外部)函数调用的源地址。

最后,真正被用户或其他合约调用来完成本合约功能的方法是 mint 和 send。 如果 mint 被合约创建者以外的人调用,则什么也不会发生(验证条件由 require 函数控制)。 另一方面,任何人都可以使用 send 函数向其他人发送代币(当然,前提是发送者拥有这些代币)。 请记住,如果您使用合约将硬币发送到某个地址,当您在区块链浏览器上查看该地址时,您将看不到任何关于该地址的信息。 因为,实际上,你发币和改变余额的信息只是保存在具体合约的数据内存中。 通过使用事件,您可以非常简单地为您的新硬币创建一个“区块链浏览器”来跟踪交易和余额。

注意:代码仅供学习之用。