代码中调用了call函数,如果call函数执行发生意外,比如转账失败,则返回值success为false。如果没有验证该返回值,即使success为false,交易仍然会正常执行。只是交易中的这笔转账没有成功。这里通过require对success进行了验证,如果是false,交易就会回滚(revert)。call函数是Solidity动态函数调用的一个关键函数,是Solidity语言层面的一个容易因为返回值而产生漏洞的典型代表。除了call函数之外,在业务层面,Solidity合约也经常使用返回值来判断函数是否执行成功,比如ERC20合约中的函数:
对于这类函数,在实际应用的时候一般需要对返回值进行校验,否则会产生漏洞,甚至会威胁到数字资产的安全性。此外,根据实际的业务逻辑,函数会返回一些业务需要的数据,这些数据也需要根据业务进行验证,进一步保证函数调用没有发生意外,包括但不限于返回值的类型、长度、范围等。比如上面的functionCallWithValue函数中,调动了verifyCallResultFromTarget函数对返回值进行校验。其不仅对返回值success进行了检查,还对retrundata的长度进行了校验和处理。
在Move合约中,从语言层面来讲,由于其静态调用的特性,不存在类似于Solidity中的call函数需要校验返回值的情况,即使有需要校验函数是否执行正确,一般会在spec模块使用规范语言在Move Prover中进行校验,校验失败则交易会中止。从业务层面来讲,Move合约中的spec模块同样可以校验函数对全局数据的修改。此外,还可以在合约中编写单元测试函数对函数直接进行单元测试,来保证函数执行的正确性。因此,一般不会将表示函数执行是否成功的布尔变量作为返回值。因此,Move函数的返回值多是实际的业务数据,是否需要校验,则需要根据实际业务需求来确定,比如需要根据返回值的不同,进入不同的函数逻辑分支,则需要对返回值进行判定和检验,比如DEX中的流动性函数:
X与Y的排序不同,需要访问的balance也是不同的,还需要校验order!=0。总的来说,Move语言静态调用特性、spec模块以及单元测试等极大地提高了函数的安全性,这一点Solidity要好很多。但也不排除函数会因为没有校验返回值而产生漏洞的情况。因此,开发人员更需要对业务和实现逻辑熟悉,开发的时候需要谨慎而行。
(2)Fortress Loans安全事件事件发生在2022年5月9日,Fortress Loans遭到黑客攻击,损失了1048.1 ETH以及40万DAI。根本原因是submit函数虽然校验了signer的数量,但却没有对signer本身和计算的数据power进行校验。
这使得攻击者可以调用submit函数修改状态变量fcds,最终修改了价格预言机中的价格。
最终,攻击者利用该漏洞窃取了1048.1 ETH以及40万DAI。类似的安全事件还有不少,它们都是因为在函数内部缺少对经济模型建立的数据结构或者计算的数据缺少校验引起的漏洞。这类漏洞是由于项目设计与开发并没有考虑到全部的情况造成的,其严重等级不一,严重的甚至会给项目带来极大的经济损失,就像上面的安全事件。在Move合约实现各类项目时,同样难以保证不会出现这类问题,尤其是新型项目。希望发生在Solidity智能合约中的这些安全事件能够给Move开发者一些警示,在开发过程中,尽可能地避免安全漏洞。
在Move合约开发中更加需要对参数进行校验。在Move中,函数的参数不仅仅是业务需求的数据,还包括了权限需要的数据,比如signer。Move没有类似Solidity中的msg.sender这种全局变量,Move中对权限的鉴定是通过参数实现的。比如下面的函数:
该函数中的account参数是代币铸造的发起账户,它必须铸币的权限,即MintCapStore,类似于Solidity中的msg.sender必须是owner。如果缺失了这部分校验,该代币就是任何账户都可以铸造的了。此外,Move生态中的项目类型跟Solidity生态相同,只是实现的语言不同。因此,Solidity合约中存在的业务逻辑上的漏洞在Move合约中有很大的可能性依然存在。因此,Move开发者在开发项目时要注意这些在Solidity合约中已经出现过的漏洞。
根本原因就是闪电贷的功能实现合约,存在借出不还的严重漏洞,造成巨额损失,是项目方fork Uniswap合约代码并修改时引入的严重漏洞,即缺少K值校验的require语句。最根本的原因还是业务的不熟悉,导致实现存在漏洞。在Move合约中, assert语句和spec模块完成require类似的功能。同样,很多Solidity生态的项目,包括DEX、借贷、农场等类型的项目在未来都将出现在Move的生态中。Move与Solidity原理以及机制是不同的,但项目的业务时相同的。鉴于Solidity生态项目踩坑无数,安全事件层出不穷,Move虽然安全性高,但是在实现各类项目时仍然要谨慎小心,尽量避免出现同类型的漏洞,希望同一个坑不要再踩一次了。我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来
我已经在mountainlion上成功安装了rbenv和rubybuild。运行rbenvinstall1.9.3-p392结束于:校验和不匹配:ruby-1.9.3-p392.tar.gz(文件已损坏)预期f689a7b61379f83cbbed3c7077d83859,得到1cfc2ff433dbe80f8ff1a9dba2fd5636它正在下载的文件看起来没问题,如果我使用curl手动下载文件,我会得到同样不正确的校验和。有没有人遇到过这个?他们是如何解决的? 最佳答案 tl:博士;使用浏览器从http://ftp.rub
我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("
默认情况下:回形针gem将所有附件存储在公共(public)目录中。出于安全原因,我不想将附件存储在公共(public)目录中,所以我将它们保存在应用程序根目录的uploads目录中:classPost我没有指定url选项,因为我不希望每个图像附件都有一个url。如果指定了url:那么拥有该url的任何人都可以访问该图像。这是不安全的。在user#show页面中:我想实际显示图像。如果我使用所有回形针默认设置,那么我可以这样做,因为图像将在公共(public)目录中并且图像将具有一个url:Someimage:看来,如果我将图像附件保存在公共(public)目录之外并且不指定url(同
root@li417-132:~#rvmpkginstallzlibFetchingzlib-1.2.7.tar.gzto/usr/local/rvm/archivesThereisnochecksumfor'http://prdownloads.sourceforge.net/libpng/zlib-1.2.7.tar.gz'or'zlib-1.2.7.tar.gz',it'snotpossibletovalidateit.Ifyouwishtocontinuewithunverifieddownloadadd'--verify-downloads1'afterthecommand.