主页 > imtoken老版本 > 系统理解以太坊(四)整体提升

系统理解以太坊(四)整体提升

imtoken老版本 2023-03-29 05:14:13

以太坊的目的是基于脚本、山寨币和链上元协议(on-chain meta-protocol)的概念进行整合和改进,让开发者可以创建任意的基于共识的、可扩展的、标准化的和特性化的。完整、易于开发和协作的应用程序。 通过建立最终的抽象基础层——内置图灵完备编程语言的区块链——以太坊使任何人都可以创建合约和去中心化应用程序,他们可以在其中自由定义所有权规则、交易方式和状态转换函数。 Namecoin 的主要框架仅需两行代码即可实现,而货币和信誉系统等其他协议仅需不到二十行代码即可实现。 智能合约——包含价值且只有满足特定条件才能打开的加密宝箱——也可以在我们的平台上创建,并且由于图灵完备性、价值意识、区块链意识和多状态的附加力量很多比 Bitcoin Script 可以提供的智能合约更强大。

以太坊账户

在以太坊系统中,状态由称为“账户”的对象(每个账户由一个 20 字节的地址组成)和在两个账户之间传递价值和信息的状态转换组成。 以太坊账户由四部分组成:

以太币(Ether)是以太坊内部的主要密码燃料,用于支付交易费用。 一般来说,以太坊有两种账户:外部拥有账户(由私钥控制)和合约账户(由合约代码控制)。 外部账户没有代码,人们可以通过创建和签署交易从外部账户发送消息。 每当合约账户收到一条消息时,合约内的代码就会被激活,允许它读取和写入内部存储、发送其他消息或创建合约。

新闻和交易

以太坊消息传递与比特币交易有些相似以太坊合约地址创建规则,但两者之间存在三个重要区别。 首先,以太坊消息可以由外部实体或合约创建,而比特币交易只能在外部创建。 其次,以太坊消息可以选择性地包含数据。 第三,如果以太坊消息的接收者是合约账户,它可以选择响应,这意味着以太坊消息也包含函数的概念。

以太坊中的“交易”是指存储从外部账户发送的消息的签名数据包。 一笔交易包含消息的接收者、确认发送者的签名、以太账户余额、要发送的数据和两个称为 STARTGAS 和 GASPRICE 的值。 为了防止代码的指数爆炸和无限循环,每个交易都需要对执行代码引起的计算步骤进行限制——包括初始消息和执行引起的所有消息。 STARTGAS是limit,GASPRICE是每一步计算需要支付给矿工的费用。 如果在交易执行过程中,“gas耗尽”,所有状态变化都会恢复到原来的状态,但已经支付的交易手续费无法收回。 如果在交易执行中止时还有剩余的气体,那么气体将被退还给发送者。 创建合约有单独的交易类型和对应的消息类型; 合约地址是根据账户随机数和交易数据的哈希值计算得出的。

消息机制的一个重要后果是以太坊的“一等公民”属性——合约拥有与外部账户相同的权利,包括发送消息和创建其他合约的权利。 这允许合约同时扮演多个不同的角色,例如,用户可以使用自定义的基于量子证明的蓝图,使去中心化组织的成员(一个合约)成为偏执用户的中介账户(另一个合约)。 签署 Porter(第三份合同)的个人和本身使用由五个私钥保护的帐户(第四份合同)的共同签署实体提供中介服务。 以太坊平台的优势在于去中心化组织和代理合约不需要关心每个合约参与者的账户类型。

以太坊状态转换函数

以太坊的状态转移函数:APPLY(S,TX) -> S',可以定义如下:

检查交易是否格式正确(即具有正确的值)、签名是否有效以及随机数是否与发送方帐户的随机数匹配。 如果不是,则返回错误。

计算交易费用:fee=STARTGAS * GASPRICE,由签名确定发送方地址。 从发送者的账户中减去交易费用并增加发送者的随机数。 如果账户余额不足,则返回错误。

设置初始值GAS = STARTGAS,根据交易字节数减去一定量的gas值。

将价值从发送者的账户转移到接收者的账户。 如果接收帐户尚不存在,请创建它。 如果收款账户是合约,则运行合约的代码,直到代码用完或者gas用完。

如果由于发送方账户资金不足或代码执行耗尽gas导致价值转移失败,将恢复原状,但仍需支付交易手续费,交易手续费将加到矿工账户中帐户。

否则,所有剩余的 gas 将返回给发送者,消耗的 gas 作为交易费用发送给矿工。 例如,假设合约的代码如下:

if !self.storage[calldataload(0)]:
    self.storage[calldataload(0)] = calldataload(32)

应该注意的是以太坊合约地址创建规则,实际上合约代码是用底层的以太坊虚拟机 (EVM) 代码编写的。 上面的合约是用我们的高级语言Serpent写的,可以编译成EVM代码。 假设一开始合约内存是空的,a value 是 10 Ether,gas 是 2000,gas price 是 0.001 Ether 和 64 个字节的数据,前 32 个字节代表数字 2,第二个字节代表单词 CHARLIE。 交易发送后,状态转换函数的处理如下:

检查交易是否有效且格式是否正确。

检查交易发送方至少有 2000*0.001=2 ETH。 如果是这样,从发送者的账户中减去 2 个以太币。

初始设置gas=2000,假设交易长度为170字节,每字节费用为5,减去850,所以还剩1150。

从发送者账户中减去 10 Ether,并向合约账户中添加 10 Ether。

运行代码。 在这个合约中,运行代码很简单:它检查合约内存索引 2 是否被使用,注意到它没有被使用,并将它的值设置为 CHARLIE。 假设这消耗了187个单位的gas,则剩余的gas为1150 - 187 = 963。 6. 向发送者账户添加963*0.001=0.963 ETH,返回最终状态。 如果没有合约收到交易,那么所有交易手续费等于GASPRICE乘以交易字节长度,交易数据与交易手续费无关。 此外,需要注意的是,合约发起的消息可以为它们生成的计算分配gas配额。 如果子计算的gas用完了,只会恢复到发送消息时的状态。 因此,就像交易一样,合约也可以通过对它们生成的子计算设置严格限制来保护它们的计算资源。

代码执行

以太坊合约的代码是用一种基于堆栈的低级字节码语言编写的,称为“以太坊虚拟机代码”或“EVM代码”。 该代码由一系列字节组成,每个字节代表一个操作。 一般来说,代码执行是一个死循环,程序计数器每加一(初始值为零)就执行一次操作,直到代码执行完或遇到错误、STOP或RETURN指令。 操作可以访问三种类型的空间来存储数据:

代码可以像访问区块头数据一样访问值、发送者和接收消息中的数据,代码也可以返回数据的字节队列作为输出。

EVM 代码的正式执行模型非常简单。 以太坊虚拟机在运行时,其完整的计算状态可以通过元组(block_state、transaction、message、code、memory、stack、pc、gas)来定义,其中block_state是包括所有账户余额和存储在内的全局状态。 在每一轮执行中,通过调用代码的 pc(程序计数器)字节找到当前指令,每条指令都有自己的定义,说明它如何影响元组。 例如,ADD 弹出两个元素并压入它们的总和,减少 gas 并增加 pc,SSTORE 弹出前两个元素并将第二个元素插入到每个元素定义的合约存储位置,同时减少 gas 值最多 200,并增加一台电脑。 虽然有很多方法可以通过即时编译来优化以太坊,但是以太坊的基本实现可以用几百行代码来实现。

区块链和采矿

尽管存在一些差异,但以太坊的区块链在许多方面与比特币区块链相似。 它们区块链架构的不同之处在于,以太坊区块不仅包含交易记录和最近状态,还包含区块号和难度值。 以太坊中的区块确认算法如下:

检查块引用的前一个块是否存在且有效。

检查块的时间戳是否大于和小于引用的前一个块的 15 分钟。

检查区块号、难度值、交易根、叔叔根和气体限制(以太坊特有的许多基本概念)是否有效。

检查块的工作证明是否有效。

将 S[0] 指定为前一个块的 STATE_ROOT。

指定TX作为区块的交易列表,一共有n笔交易。 对于属于 0...n-1 的 i,执行状态转换 S[i+1] = APPLY(S[i],TX[i])。 如果任何转换失败,或者如果程序执行比 GASLIMIT 花费更多的 gas 到达这里,则返回错误。

使用 S[n] 为 S_FINAL 赋值,并向矿工支付区块奖励。 8 检查 S-FINAL 是否与 STATE_ROOT 相同。 如果它们相同,则该块有效。 否则,该块无效。

这种确认方式乍一看似乎效率低下,因为它需要存储每个区块的所有状态,但实际上以太坊的确认效率与比特币不相上下。 原因是状态是以树状结构存储的,每增加一个块只需要改变树状结构的一小部分。 因此,一般来说,两个相邻块的树结构大部分应该是相同的,因此存储一次的数据可以使用指针(即子树哈希)引用两次。 称为“Patricia Tree”的树结构可以实现这一点,其中包括对 Merkle 树概念的修改,不仅允许更改节点,还允许插入和删除节点。此外,由于所有状态信息都是最后的一部分块,不需要存储整个块历史——如果这种方法可以应用到比特币系统中,可以计算出节省 10-20 倍的存储空间

未完待续.....

以太坊智能合约代码_以太坊合约地址创建规则_以太坊合约赚钱快吗

长按二维码继续阅读