PKU - Blockchain - Lecture 8

智能合约是运行在区块链上的一段代码,代码的逻辑定义了合约的内容。

智能合约账户保存了合约当前的运行状态:

  1. balance(账户余额)
  2. nonce(迄今为止的发起交易次数)
  3. code(合约代码)
  4. storage(存储,数据结构是一颗 MPT)

智能合约的编写,通常采取 Solidity,语法上与 JavaScript 很像。

Solidity 代码的结构:

20250227133000

智能合约的调用

20250227133725

20250227134058

20250227135605

20250227135518

20250227140121

智能合约的创建和运行

20250227140500

20250227140756

20250227141515

20250227141654

先挖矿还是先执行智能合约:先执行,确保 Block Header 中的三颗树的根哈希值计算完毕后(原理如下图),才是挖矿找 nonce 的过程。

Root、TxHash、ReceiptHash:状态树、交易树、收据树的根哈希值
GasLimit:这个块的最大汽油限量(防止该块所耗资源过多,链上不平均)
GasUsed:块内所有交易已经使用的汽油量。

20250223222021

执行发生错误的合约也要发布到区块链上去,这样才能扣掉汽油费(下图中收据树上每个节点的 Status 域就表示该交易是否执行成功)。

20250227145032

20250227145708

20250227145810

三种发送 ETH 的方式:

  1. <address>.transfer(uint256 amount)
  2. <address>.send(uint256 amount) returns (bool)
  3. <address>.call.value(uint256 amount)()

20250227150002

Solidity 例子:简单拍卖

20250227133000

下面代码中是否存在问题?

20250227153113

若一个黑客外部账户通过某个合约账户发起竞拍操作,且该合约中没有写 callback 函数,那么在拍卖结束后的 auctionEnd 过程中,transfer 操作会找不到地址,然后发出异常,导致所有操作回滚。这样会使得所有拍卖者的钱锁在智能合约中,取不出来!

20250227154923

20250227155830

这样会有陷入递归无限从合约中取钱的行为。应该向右边那样先清零再转账。

![20250227160203](httpsraw.githubusercontent.comzylbeyondlimitsImagesmainblog-images20250227160203.png)

或者用 transfer 或 send 的方式(Gas 有限,不会让其陷入新的调用)。

20250227160825

作者

Zylll

发布于

2025-02-27

更新于

2025-02-27

许可协议