Ethereum 学习记录(持续更新)

EVM

  • EVM是smart contract 的运行环境,是一个完全隔离的sandbox环境,在EVM中的合约无法与外界交互

账户

  • 外部账户:由用户控制,持有公私钥对。地址由公钥决定

  • 合约账户:由合约存储的代码控制。地址由合约创建者的地址和从该地址发出过的交易数量计算得到

交易

交易可以看作是从一个帐户发送到另一个帐户的消息。它能包含一个二进制数据(payload)和以太币。如果目标账户是零账户(账户地址为 0 ),此交易将创建一个 新合约

存储、内存、栈

每个账户有一块持久化内存区称为 存储 。 存储是将256位字映射到256位字的键值存储区。 在合约中枚举存储是不可能的,且读存储的相对开销很高,修改存储的开销甚至更高。合约只能读写存储区内属于自己的部分。

第二个内存区称为 内存 ,合约会试图为每一次消息调用获取一块被重新擦拭干净的内存实例。 内存是线性的,可按字节级寻址,但读的长度被限制为256位,而写的长度可以是8位或256位。当访问(无论是读还是写)之前从未访问过的内存字(word)时(无论是偏移到该字内的任何位置),内存将按字进行扩展(每个字是256位)。扩容也将消耗一定的gas。 随着内存使用量的增长,其费用也会增高(以平方级别)。

EVM 不是基于寄存器的,而是基于栈的,因此所有的计算都在一个被称为 栈(stack) 的区域执行。 栈最大有1024个元素,每个元素长度是一个字(256位)。对栈的访问只限于其顶端,限制方式为:允许拷贝最顶端的16个元素中的一个到栈顶,或者是交换栈顶元素和下面16个元素中的一个。所有其他操作都只能取最顶的两个(或一个,或更多,取决于具体的操作)元素,运算后,把结果压入栈顶。当然可以把栈上的元素放到存储或内存中。但是无法只访问栈上指定深度的那个元素,除非先从栈顶移除其他元素。

contract function visibility

  • public:可以被internal call 和 外部 message call

  • private:只能被contract内部成员存取

  • external:能被外部的contract和transaction呼叫。内部呼叫需要用this.f()->,直接呼叫会失败

  • internal:只能被defined contract或派生合约呼叫。

state mutability

  • pure:不读也不写state

  • view:读state但不写

  • default:会读写state

宣告function

function name(args) visibility mutability returns(returns variables){...}

constructor 构造函数

contract被建立时自动执行的function,不宣告会自动插入空constructor{ }

constructor(args..){ ... }

receive function

只用于接受ether

格式固定:receive() external payable{...}

有send(),transfer()等就会触发这个function

fallback function
  • 一个合约只有一个fallback function

  • fallback( ) external payable 代表想接收ether

以太坊与图灵完备

图灵机:可以从连续内存中读取和写入的状态机

以太坊能够执行在区块链上程序的能力是由EVM完成的。

图灵完备与gas fee

人们无法通过模拟程序来判断程序是否会结束,除非他们真正去运行这个程序,否则无法判断程序的运行路径。图灵完备的系统可以在无限循环中运行。这引出了一个问题,以太坊的每个结点在验证交易时可能陷入无限循环,从而引发类似DDOS的结果。

为了解决这个问题,以太坊引入了gas fee。gas的本质是一个预先定好的开销,在智能合约执行过程中,使用的资源开销超过了预先设定的gas,EVM就会自动停止执行合约。因此,gas的引入限制了程序可以使用的资源量。