- A+
北京大学肖臻老师《区块链技术与应用》公开课笔记
什么是智能合约?
1.智能合约是运行在区块链上的一段代码,代码的逻辑定义了合约的内容。
2.智能合约的账户保存了合约当前的运行状态。有以下几方面:
-
balance:当前余额
-
nonce:交易次数
-
code:合约代码
-
storage:存储,数据结构是一棵MPT(状态树)
*solidity是智能合约最常用的语言,语法上与javascript近似。
外部账户如何调用智能合约?
创建一个交易,接收地址为要调用的那个智能合约的地址,data域填写要调用的函数及其参数的编码值。
其中TXDATA为调用的函数。
一个合约如何调用另一个合约中的函数?
-
直接调用
-
使用address类型的call()函数
-
代理调用delegatecall()
-
fallback()函数
转账金额可以为0,汽油费不可以为0,否则没有矿工打包这个交易。
智能合约的创建和运行
汽油费(gas fee)
汽油费会在执行合约时一次性扣除。汽油费如果扣多了会退回多余的,如果少了交易会被回滚,但已经消耗的汽油费不会退回。这样处理的原因是防止恶意用户发起DOS攻击,浪费算力,造成以太坊处理交易能力下降。
*Denial of Service (DoS)是分布式拒绝服务攻击软件,DDoS攻击可以分为带宽消耗型和资源消耗型。
错误处理
智能合约要么执行全部内容,要么都不执行,不会执行一部分。
嵌套调用
Block Header
这里的GasLimit是指这个区块所有交易能消耗的Gas值上限。设置这个值的原因是为了防止一个区块里交易太多。后一个块可以选择上调或下调1/1024的GasLimit值。
**问题1:**假设某个全节点要打包一些交易到一个区块里,交易里有一些是对智能合约的调用,那么这些全节点是把智能合约执行完成后再去挖矿呢?还是先挖矿,获得记账权后再执行智能合约呢?
**答:**先执行智能合约再去挖矿,通过执行交易实现状态同步。各个全节点执行完智能合约后会在本地的数据库将对应的Gas fee减去。
**问题2:**会不会有矿工因为得不到Gas fee就不去验证交易?
**答:**不会。若不去验证,会危及到区块链的安全。若跳过验证,就无法继续挖矿。因为挖矿要执行所有交易得到hash值,然后更新状态树。
**问题3:**若执行智能合约过程中出现了错误,要不要发不到区块链上去?
**答:**要,因为要发布后形成共识,矿工才能得到Gas fee。
Receipt数据结构
每个交易完成之后形成一个收据,如图是交易的内容。
以太坊中,多线程可以提高挖矿效率吗?
不可以,solidity不支持多线程,因为多线程可能会造成执行结果不确定。
智能合约可以获得的区块信息
智能合约可以获得的调用信息
地址类型
所有智能合约均可显示的转换成地址类型。
从一个例子开始:简单拍卖
竞拍流程:发起人写一个拍卖的程序,发布一个智能合约,转账金额为0,需要一定的Gas fee,然后由矿工发布到区块链上,会返回给发起人一个地址。其他想要参与竞拍的人直接调用这个智能合约就行了。
有什么问题吗?
问:假设有人通过这样的合约账户参与竞拍会有什么结果?
答:智能合约里的以太币取不出来。
第二版:由投标者自己取回出价
这样可以了吗?
重入攻击(Re-entrancy Attack)
解决办法:先清零,再转账。
-
send和transfer有一个共同的特点:
-
转账过去的Gas费只有2300Wei
-
不足以让接收者再发起一次新的调用,只够写一个Log