主页 > imtoken钱包有客服吗 > 【译文】完全理解以太坊智能合约

【译文】完全理解以太坊智能合约

imtoken钱包有客服吗 2023-03-23 07:34:12

这篇文章是我看过的介绍以太坊智能合约原理的最经典的文章,尤其是后半部分,原作者Gjermund Bjaanes,本文为译文。

您可能听说过“智能合约”的概念,或许也知道它们是可以在区块链上运行的“代码”。

但是如何在区块链上运行代码?如果你不是很了解,这篇文章将解释智能合约是如何在以太坊区块链上工作的。

如果你对编程有一定的了解,对理解这篇文章会有帮助,因为本文将包含一些简单的代码,为了简洁明了,本文中的一些技术细节略有简化,但概念是正确的的。

区块链概览

不赘述,区块链技术的核心概念是分布式账本。它是许多参与者共享的一种特定类型的数据库。

这个特殊的数据库只是一个交易列表,跟踪网络中发生的每一笔交易。每个人都可以拥有自己的交易清单备份副本,再加上强大的货币激励措施,以消除各方之间的信任成本。

传统交易通常会引入第三方(双方信任的中间人)来解决互不信任的人进行的交易,例如:支付宝、Paypal、银行等。

使用区块链,信任可以放在一个网络中,不需要第三方,它有很强的动机避免作弊(简而言之:遵守规则更有利可图)。

分布式账本

更具体地说:区块链网络是一堆机器,它们都有相同的交易列表,因为每个人都有相同的列表,所以很难欺骗网络接受虚假交易。结合一些加密算法和货币激励,只要每个人都遵守规则,就可以建立一个安全的区块链网络。

这种方式也使得区块链几乎不可能被篡改。改变历史的唯一方法是让大多数节点(矿工)同意这样做。

如果想对区块链进行更深入的介绍,还可以参考原作者的另一篇文章:什么是区块链(英文)

什么是智能合约?

以太坊和比特币最大的区别在于以太坊有智能合约的概念。比特币是一种数字货币——一种价值储存手段。虽然以太坊不仅仅是一种数字货币,但“智能合约”这个名称有点误导。它不是真正的合约,也不是特别聪明区块链货币有几种,它们只是在区块链上运行代码。

首先要了解的是,智能合约是以太坊网络上的一种特殊账户。我们有用户账户,也可以有智能合约账户。

用户帐户有:

智能合约账户有:

地址是帐户的唯一标识符,就像普通用户帐户一样。

余额也与普通用户帐户相同。不同的是,智能合约的余额意味着代码可以拥有资金并且可以管理资金。因此,如果代码不正确,可能会导致资金处理不当。

智能合约账户的状态是智能合约中声明的所有变量和变量的当前状态。它的工作方式与大多数编程语言中类中的变量变量相同。事实上,理解智能合约最简单的方法可以类比为类实例化一个对象,唯一的区别是该对象将始终存在于区块链网络中(除非程序自毁)。

智能合约的代码是编译后的字节码,可以在以太坊客户端和节点上运行。它是创建智能合约时执行的代码,它包含我们可以调用的函数。就像面向对象编程语言中的对象一样。

旁注:智能合约更有趣的地方是:它们可以调用其他智能合约区块链货币有几种,这开启了创建可以自行进行交易的自治代理的能力。

contract Counter {
    uint counter;
    function Counter() public {
        counter = 0;
    }
    function count() public {
        counter = counter + 1;
    }
}

假设我们使用上面的代码来创建一个智能合约。该代码有一个名为“counter”的变量,类型为 uint(无符号整数)。计数器变量的内容(值)是合约的状态。每当我们调用 count() 函数时,这个智能合约的区块链状态就会加 1,这对每个人都是可见的。

智能合约账户结构

我们稍后会用更多的例子来解释它是如何工作的,但首先我们来介绍一下以太坊和比特币在交易层面的区别。

以太坊和比特币在交易层面的区别

比特币交易很简单,它只做一件事,就是进行交易。忽略细节,一切都归结为 TO(谁收钱)、FROM(谁寄钱)和 AMOUNT(多少钱)。这允许比特币网络中的参与者转移价值和储存价值。

以太坊最大的不同在于它的交易也有一个 DATA 字段。 DATA 字段支持三种类型的交易:

创建合约调用合约函数

虽然实际交易有更复杂的细节,但这些都是核心概念。

让我们看一些更具体的例子来说明这些交易是什么样的。

以太坊交易价值转移

{
    to: '0x687422eEA2cB73B5d3e242bA5456b782919AFc85',
    value: 0.0005
    data: ‘0x’ // 也可以附加消息
}

很简单,就是将一定数量的以太币转入一个地址,我们也可以在交易中添加消息。

创建智能合约

{
    to: '',
    value: 0.0
    data: ‘0x6060604052341561000c57xlb60405160c0806……………’
}

如上,TO为空表示创建智能合约,DATA包含编译成字节码合约代码的智能合约。

调用合约方法

{
    to: '0x687422eEA2cB73B5d3e242bA5456b782919AFc85’, //合约
    value: 0.0
    data: ‘0x6060604052341561000c57fe5b60405160c0806……………’
}

函数调用信息放在DATA变量中,交易信息发送给智能合约调用。地址,下面将详细介绍它是如何做到的,让我们先了解一下这个概念。

关于成本和执行

可以想象,我们不能一直在区块链上免费运行计算密集型程序。

代码的执行由调用者以一种称为 Gas 的形式支付。 Gas 是运行以太坊虚拟机的燃料。我们可以将其视为每次执行指令的付款。

在拨打电话时,我们必须设置本次通话预计花费的最大gas消耗量(Gas Limit)。例如,如果我们调用的代码进入一个永恒循环,执行成本不会超过我们设置的gas限制。

Gas 执行费用由网络的矿工决定(他们是运行代码的节点)。

当然还有很多关于 Gas 的内容,让我们先来看看,如果你想深入了解以太坊的这一部分,请查看这篇 consensys 优秀文章:以太坊、Gas、Gas 和费用(英文)

智能合约如何运作?

当智能合约部署到以太坊网络时,任何人都可以调用智能合约的功能(当然可能有一些安全原因阻止人们使用该功能,但不阻止我们自由尝试) .

在智能合约上调用函数在很多方面类似于“正常”编程——当然在执行上存在一些差异。

假设我们有一个“MyObject”类型的对象。该对象有一个名为“myFunction”的函数。要调用它,我们可以简单地引用对象的实例、调用哪个函数以及调用它的参数。像这样:

myObjectReference.myFunction(parameters);

如果函数返回任何值,您可以将其存储在变量中:

myVariable = myObject.myFunction(parameters);

从概念上讲,调用智能合约是一回事。唯一的区别是我们必须将有关调用的信息放入交易中,对其进行签名并将其发送到以太坊网络以执行。

假设你要调用智能合约“0x0123456”上的函数“myFunction”,带有一些参数,大概包括以下四个步骤:

智能合约调用步骤

现在,当交易被打包到区块链中时,状态的变化将反映在整个网络中。

世界计算机

许多人称以太坊为世界计算机。比喻不错,真的是世界维护的虚拟机!

要记住一件事:虽然智能合约是图灵完备的,理论上可以做任何事情,但它们不适合繁重的计算工作。

以太坊世界计算机就像一台可以运行简单程序的老式慢速计算机。出于成本和安全原因,保持以太坊智能合约小而简单是至关重要的。

合约的计算量越多,运行它的成本就越高。合同越复杂,发生安全漏洞的可能性就越大。由于区块链的不可变特性,智能合约中的安全漏洞很难修复。

世界计算机

智能合约应用:代币(token or token)

解释令牌的工作原理。在 ICO 中大家都赞不绝口的代币是智能合约,我们自己可以在以太坊上创建自己的代币。

这些代币大部分是在以太坊上创建的,概念很简单,我们需要注意以下信息:

总供应账户中的金额 硬币的流量

1、2、3可以通过用户和金额的简单映射来实现:

Map<Account, Double> usersAndTheirMoney;

使用构造函数,我们可以在自己的账户中设置初始供应(或分配到任何其他账户):

public Token(Account initialAccount, double initialSupply) {
  usersAndTheirMoney.put(initialAccount, initialSupply);
}

代币的移动是通过简单的函数完成的,只需从一个帐户中减去并添加到另一个帐户:

public transfer(Account from, Account to, double amount) {
  verifySenderOfMoneyIsCaller(from);
  verifySenderOfMoneyHasEnoughMoney(from, amount);
  usersAndTheirMoney.put(from, usersAndTheirMoney.get(from)-amount);
  usersAndTheirMoney.put(to, usersAndTheirMoney.get(to)+amount);
}

这与我们在以太坊中创建代币所使用的概念完全相同。

但是以太坊有自己的编程语言Solidity,用Solidity写代码是这样的:

contract MyToken {
    mapping (address => uint256) public balances;
    function MyToken(uint256 initialSupply) {
        balances[msg.sender] = initialSupply;
    }   
    function transfer(address to, uint256 amount) public {
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }
}

为简单起见,一些细节可以参考这篇文章来创建一个标准的ERC20代币。

如果你想学习在以太坊上编程,你可以学习这门课程。以太坊DAPP开发实践

本文英文原文链接为:

区块链技术问答 - 专家随时为您解答任何问题。通晓区块链——打造优质区块链技术博客,来这里学习区块链,关注知乎和微博。