在这里插入图片描述

在这里插入图片描述

每一回你于以太坊之上开展操作,不论其是进行转账抑或是调用合约,实质上皆是发起了一笔交易。差异仅仅在于收款方究竟是谁:要是转给普通地址那便是转账,要是转给合约地址那便是调用合约。调用哪一个函数是写在DATA域当中的,就如同在包裹之上写明要触发哪一个开关。好多人认为智能合约十分神秘,实际上它跟普通账户一般拥有余额、能够接收ETH,只不过背后多了一段代码。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

调用失败不一定会报错

在这里插入图片描述

调用其他合约之际,运用call()函数之时,要是被调用的合约出现了异常状况,call()仅仅会返回false,然而发起调用的那个函数自身并不会抛出异常,代码会持续朝着下方执行。这一点极为隐蔽,好多新手未曾检查返回值,认定交易已然成功,实际上内部调用早就已然失败了。在2024年,存在多个DeFi项目由于没有检查call返回值而被黑客利用,致使损失达数百万美元。正确的做法是每一次call之后都要借助require去判断返回值,不能够默认其成功。以太坊有着这样的设计,其目的在于给予开发者更多的控制权,可是与此同时,这样又使得安全责任有所增加。

在这里插入图片描述

在这里插入图片描述

接收转账必须打标记

在这里插入图片描述

在这里插入图片描述

Solidity里,要是有函数能够接收外部转来的钱,那就得标记成payable。就拿拍卖合约来说,bid()是用来出价的函数,用户在调用它的时候得发送ETH,所以必须得加上payable关键字。而withdraw()是把锁定的钱取回来,并不涉及转账,于是就不需要标记。好多人写合约的时候忘了加payable,结果用户把钱转进去就直接报错了,Gas费白白浪费掉了。以太坊如此规定是为了清晰地区分哪些函数是能够收钱的,以此防止出现意外的转账。要是你调用一个未曾带有payable标记的函数,还附上了ETH,那么交易就会被径直拒绝,而且Gas费也不会退还。

没有指定函数时走回退函数

在这里插入图片描述

倘若你朝着一个合约地址去进行转账,然而却并未于DATA域之中阐明要调用哪一个函数,又或者书写了一个并不存在的函数名称,那么合约便会执行回退函数。回退函数是没有名字的,并且无法接收参数,一般是用于处理意外转账或者记录日志。这样的一个机制防止了因调用错误从而致使交易卡住。不过需要留意的是,回退函数的Gas限制仅仅只有2300,是做不了复杂操作的。在2020年的时候就有项目由于在回退函数里书写了复杂逻辑进而导致Gas耗尽,使得用户没办法取回资产。在设计合约的时候,回退函数应当尽量保持简单,仅仅做必要的日志记录。

在这里插入图片描述

Gas费和转账金额是两笔钱

付给矿工打包交易的报酬是汽油费,你真正要转给对方的ETH是转账金额,二者全然不同。转账金额能够为0,然而汽油费必须给付。以太坊运用预扣机制:全节点会先依据你所设置的最大Gas费,从账户一次性扣除,接着执行交易,实际使用多少便计算多少,剩余的会按原路退回。要是Gas费在中途用尽,交易将会回滚,已经消耗的Gas不会退还,这是用以防止恶意节点发起无限循环攻击。2025年1月,有数据显示,以太坊之上,每日约3%的交易,因Gas不足,而被回滚,用户平均损失0.02个ETH。

全节点先执行后挖矿

矿工在进行打包交易之际,务必要先将区块之中的所有交易予以逐一执行完毕,进而对状态树、交易树、收据树这三棵树的根哈希实施更新操作,如此方可计算出区块哈希,紧接着尝试进行挖矿活动。而要是未能成功挖到矿,那么先前执行过程所消耗的资源不会获得任何形式的补偿,所产生的Gas费会全部归属成功挖出区块的那名矿工。并且每一个全节点在收到新发布出去的区块后,其势必要对里面所包含的交易再次执行一遍以此来验证交易的正确性。这也就意味着即便交易失败了,同样会被发布到区块链之上,Gas费依旧会照样扣除,只不过状态不会发生变化而已。以太坊是一种由交易驱动的状态机,所有的节点都得执行同一组操作,以此来到达同一状态,不然的话,三棵树的根哈希就会对不上标点用错。

在这里插入图片描述

在这里插入图片描述

你是否理解了?要是你正着手准备去部署一份合约,你会倾向性地做出抉择是先至测试网运行一番,还是径直前往主网?欢迎于评论区域分享你的经历体验,可别忘了点赞并进行转发从而让更多的人能够避开这些陷阱。

在这里插入图片描述

在这里插入图片描述