EVM是smart contract 的运行环境,是一个完全隔离的sandbox环境,在EVM中的合约无法与外界交互
外部账户:由用户控制,持有公私钥对。地址由公钥决定
合约账户:由合约存储的代码控制。地址由合约创建者的地址和从该地址发出过的交易数量计算得到
交易可以看作是从一个帐户发送到另一个帐户的消息。它能包含一个二进制数据(payload)和以太币。如果目标账户是零账户(账户地址为 0 ),此交易将创建一个 新合约 。
每个账户有一块持久化内存区称为 存储 。 存储是将256位字映射到256位字的键值存储区。 在合约中枚举存储是不可能的,且读存储的相对开销很高,修改存储的开销甚至更高。合约只能读写存储区内属于自己的部分。
第二个内存区称为 内存 ,合约会试图为每一次消息调用获取一块被重新擦拭干净的内存实例。 内存是线性的,可按字节级寻址,但读的长度被限制为256位,而写的长度可以是8位或256位。当访问(无论是读还是写)之前从未访问过的内存字(word)时(无论是偏移到该字内的任何位置),内存将按字进行扩展(每个字是256位)。扩容也将消耗一定的gas。 随着内存使用量的增长,其费用也会增高(以平方级别)。
EVM 不是基于寄存器的,而是基于栈的,因此所有的计算都在一个被称为 栈(stack) 的区域执行。 栈最大有1024个元素,每个元素长度是一个字(256位)。对栈的访问只限于其顶端,限制方式为:允许拷贝最顶端的16个元素中的一个到栈顶,或者是交换栈顶元素和下面16个元素中的一个。所有其他操作都只能取最顶的两个(或一个,或更多,取决于具体的操作)元素,运算后,把结果压入栈顶。当然可以把栈上的元素放到存储或内存中。但是无法只访问栈上指定深度的那个元素,除非先从栈顶移除其他元素。
public:可以被internal call 和 外部 message call
private:只能被contract内部成员存取
external:能被外部的contract和transaction呼叫。内部呼叫需要用this.f()->,直接呼叫会失败
internal:只能被defined contract或派生合约呼叫。
pure:不读也不写state
view:读state但不写
default:会读写state
function name(args) visibility mutability returns(returns variables){...}
contract被建立时自动执行的function,不宣告会自动插入空constructor{ }
constructor(args..){ ... }
只用于接受ether
格式固定:receive() external payable{...}
有send(),transfer()等就会触发这个function
一个合约只有一个fallback function
fallback( ) external payable 代表想接收ether
图灵机:可以从连续内存中读取和写入的状态机
以太坊能够执行在区块链上程序的能力是由EVM完成的。
人们无法通过模拟程序来判断程序是否会结束,除非他们真正去运行这个程序,否则无法判断程序的运行路径。图灵完备的系统可以在无限循环中运行。这引出了一个问题,以太坊的每个结点在验证交易时可能陷入无限循环,从而引发类似DDOS的结果。
为了解决这个问题,以太坊引入了gas fee。gas的本质是一个预先定好的开销,在智能合约执行过程中,使用的资源开销超过了预先设定的gas,EVM就会自动停止执行合约。因此,gas的引入限制了程序可以使用的资源量。
