selfdestruct函数(自毁函数)由以太坊智能合约提供,用于销毁区块链上的合约系统。当合约执行自毁操作时,合约账户上剩余的以太币会发送给指定的目标,然后其存储和代码从状态中被移除。 selfdestruct函数虽然能在紧急情况下帮助开发人员删除智能合约并将合约内的余额转移到指定的地址,但这一特性也被不法分子利用,使它成为了攻击手段。 玩家每次玩游戏时都会调用 EtherGame.deposit 函数向合约中先打入一个ETH,随后函数会检查合约中的余额(balance)是否小于等于 7 ,只有合约中的余额小于等于 7 时才能继续否则将回滚 ETH进去,所以通过正常路径是不可能一次向 EtherGame 打入大于 1 枚的ETH的,但是我们又需要打入大于 1 枚的ETH到 EtherGame 合约中,所以selfdestruct函数就登场了 修复建议 我们来分析一下攻击者的思路:利用selfdestruct函数强制转账给游戏地址,导致unit balance = address(this).balance查询出的balance的值大于7,诱发
管理用户界面的审计日志主要用来查看管理用户对管理平台的操作记录,同时可查看所有纳管的计算节点集群内普通用户的基本操作。
习题10-5 递归计算Ackermenn函数 本题要求实现Ackermenn函数的计算,其函数定义如下: ? 函数接口定义: int Ack( int m, int n ); 其中 m 和 n 是用户传入的非负整数。函数 Ack 返回Ackermenn函数的相应值。题目保证输入输出都在长整型范围内。
在具体编程中,sklearn没有直接能够传入threshold阈值的函数,但是可以使用算法的decision_function函数计算出样本的score值,然后转换为布尔向量,进而转换为元素为0,1的整型向量 通过predict函数计算逻辑回归算法对X_test的预测值。 函数都是以0作为阈值的,所以如果想要调整这个分类阈值的话,需要绕一个弯子。 ,光看函数命名就知道它是做决策的函数,直接把X_test测试集传入decision_function函数中。 现在通过decision_function函数查看前10个样本的score值,并且通过predict函数查看对于这10个样本逻辑回归算法的分类结果。 ?
2、ABI 混淆攻击 ABI 负责定义函数签名到 函数选择器(4 字节) 的映射。 攻击者可能利用选择器碰撞,让不同函数共享同一个选择器,从而调用到意料之外的逻辑。 function transfer(address to, uint256 amount) public {} function f123456789() public {} } 不同函数签名哈希后的前 防御手段: 使用最新 Solidity 编译器,避免 ABI 自动推导漏洞 避免函数名过长或构造极端签名 使用工具检测潜在冲突(如 Slither、Surya) 3、selfdestruct 的风险 selfdestruct 虽然 EIP-6049 已提出废弃 selfdestruct,但目前仍存在隐患: 强制转账:攻击者可以部署一个带余额的合约,并 selfdestruct 强行转账到任意合约,即使目标合约没写 receive 代理合约被摧毁:如果逻辑合约或代理被不慎写入 selfdestruct,可能彻底失效。
拒绝服务的原因 意外执行了SELFDESTRUCT指令 访问控制策略出错 Gas达到区块上限 非预期的异常抛出 ? 漏洞分析 selfdestruct()合约自毁函数 指令执行后,合约将拒绝服务,地址对应的字节码将被标注为删除 合约地址中所有的ETH将被发送到指定的新地址 进行ETH转移时,即使目标地址为一个合约地址 ,也不会触发该地址的fallback函数,因此不需要该合约有任何的payable函数 如果selfdestruct函数被非预期的执行,则整个合约会拒绝服务 ? (_who); } } 漏洞点:在address owner处发送地址到_who处,由于调用了selfdestruct()函数对selfdestructGame合约进行自毁,将selfdestructGame ,在经过transfer函数的时候会发生异常,导致交易回滚,从而使bid()函数拒绝服务。
,指定发红包的人和红包数量 需要一个查询红包余额的功能函数(提示:address(this).balance) 实现抢红包的功能 需要一个给抢红包的人转账的功能函数 函数中需要判断:1 红包剩余个数大于0;(提示:断言) 红包数量随着函数执行的次数相应减少; 抢红包的金额采用随机的方式(提示:用keccak256函数计算当前时间戳的哈希),红包的金额是100以内的数(提示: 哈希值对100取余) 转账功能:msg.sender.transfer(amount) (amount为金额); 实现退还红包余额 可以借助selfdestruct函数,用于销毁合约,其原型如下 : function selfdestruct(address user) user代表合约销毁时的受益人; 实现一个kill函数,用它来销毁合约,指定发红包的人为受益人; 合约代码: msg.sender] = true; } // Refund the balance of the red envelope function kill() public{ selfdestruct
12] PUSH4 0x57b9f523 [13] MSIZE [14] MSTORE [15] STATICCALL // 这里是调用caller的getInitializationCode()函数 // 将自己kill掉 [36] JUMPDEST [37] DUP1 [38] REVERT // 可以看出来,实际上上面代码完成的,就是TransientContract合约构造函数的主要内容。 caller 去执行selfdestruct来销毁合约。 destroy 有了上面deploy的解释,那这个函数就不难理解了,调用selfdesctruct函数销毁部署的合约。 临时合约 selfdestruct,将钱转到最终合约。
在 Solidity 中,事件(event)不是控制台输出,也不是日志记录函数,而是链上广播机制。 ":null,"selfdestruct_refund_target":null,"selfdestruct_transferred_value":null,"kind":"CREATE","value ":null,"selfdestruct_refund_target":null,"selfdestruct_transferred_value":null,"kind":"CALL","value": ":null,"selfdestruct_refund_target":null,"selfdestruct_transferred_value":null,"kind":"CALL","value": ":null,"selfdestruct_refund_target":null,"selfdestruct_transferred_value":null,"kind":"CREATE","value
两次重大漏洞第一次攻击(2017年7月)漏洞位置:initWallet 函数初始化逻辑错误。问题原因:合约允许任何人调用 initWallet(),从而重新设置钱包拥有者。 WalletLibrary 地址 function doSomething(bytes data) public { lib.delegatecall(data); // 调用库合约函数 关键教训库合约必须不可变(不能有 init、selfdestruct 等函数)。delegatecall 风险极大,应谨慎使用。合约升级机制必须经过严格设计和审计。4. 启示初始化函数一定要保护(onlyOwner),不能随意被调用。delegatecall 必须小心使用,库合约最好是无状态(Stateless)。 selfdestruct 是危险函数,应该避免在核心合约中出现。智能合约一旦部署,升级和错误修复极其困难。6.
自毁函数(Self-destruct) 每个合约都可以执行selfdestruct函数,这个函数会从合约地址移除所有字节码并将存储在这个地址的所有以太币转移到参数指定的地址。 因此,selfdestruct函数可以强制转移以太币到任何合约,不管这个合约中存在什么代码,甚至根本没有 payable 函数。 这就是说,攻击者可以创建一个有selfdestruct的合约,并向其发送以太币,调用selfdestruct(target),从而强制将以太币转移到target合约。 2. 攻击者可以通过selfdestruct函数(前面提到过的)强制向该合约发送少量的以太币(如 0.1 以太币),以此阻止将来有玩家达到 MileStone。 如果要求存储的以太币是一个确切数量,应该自定义变量,在 payable 函数中递增,这样才能安全的追踪存入的以太币。这种变量不会受到调用selfdestruct强制发送以太币的影响。
constant returns (uint) { return count; } function kill() { if (owner == msg.sender) { selfdestruct 构造函数(Contructor) function Counter()函数名和合约名相同时,此函数是合约的构造函数,当合约对象创建时,会先调用构造函数对相关数据进行初始化处理。 成员函数 function increment() public和function getCount() constant returns (uint)都是Counter合约的成员函数,成员函数在iOS 析构函数(selfdestruct) 析构函数和构造函数对应,构造函数是初始化数据,而析构函数是销毁数据。 在counter合约中,当我们手动调用kill函数时,就会调用selfdestruct(owner)销毁当前合约。
实现流程 开发工具:Visual Studio 2017 一、资源释放 思路:①加载文件到工程中,②使用函数查找资源,③创建文件,④写入资源。 1.在项目工程上点击右键,选择“添加资源”; ? 该Selfdestruct()函数将在计算机的temp文件夹中创建以下.bat文件,然后启动它: :Repeat del "c:\myfolder\selfdestruct.exe" if exist "c:\myfolder\selfdestruct.exe" goto Repeat rmdir "c:\myfolder" del "c:\temp\_uninsep.bat" ; .bat文件将循环删除 c:\ myfolder \ selfdestruct.exe,直到最终成功(即selfdestruct.exe完成执行后。) > 实现流程: 一、在邮件中插入一张图片,这里通过php中的readfile() 函数读取本地图片,这里的图片可以使用目标公司的logo,并写入到输出缓冲。
EIP-1967设计特定的插槽,而不是给定一个返回逻辑合约地址的函数,其目的在于防止函数签名攻击。 函数签名攻击的思路是:由于solidity中识别一个函数,靠的是函数签名,而函数签名是函数哈希后的前4个bytes,是非常容易碰撞出来的。 在一个独立的solidity文件中,编译器自己会去检查所有的external和public函数是否存在函数签名碰撞,而对于代理模式的合约文件,可能存在proxy合约中的函数签名与impl合约中的函数签名碰撞 而一旦发生这种碰撞,proxy合约中的函数就会被直接调用,而不是impl合约对应的函数。 然而在remix中执行时,发现delegatecall之后的require语句还是执行了: 这是不对的,需要进一步理解黄皮书中关于selfdestruct这个opcode的定义: selfdestruct
可以在合约构造函数中调用transfer()函数,然后调用selfdestruct()。这将退还部署智能合约部分的gas。 这是因为CREATE2检查目标地址的 nonce 是否为零(它会在构造函数的开头将其设置为1)。在这种情况下,selfdestruct()函数每次都会重置地址的 nonce。 因为我们不支付智能合约部署费用,所以将钱从充值地址到热钱包的成本大约等于调用transfer()函数的成本。 最终方案 初始准备: ● 通过user_id获取随机值(salt)的函数 ● 调用CREATE2操作码(使用适当的随机数)的智能合约 ● 具有如下构造函数的充值钱包合约的字节码: constructor to receive gas refund and reset nonce to 0 selfdestruct(address(0x0)); } } contract Fabric
特权功能暴露 漏洞分析 在 solidity 中没有被权限修饰符修饰的函数,默认可以被所有人调用(即具有 public 属性) 在 solidity 中有一个内置函数 selfdestruct() (析构函数 )销毁当前合约,并把合约余额发送到某个地址中 如果这俩情况同时发生在同一函数上,就意味着所有人都可以调用这个函数来获得合约的余额,当然,也不一定是析构函数,其他涉及敏感操作的函数(比如未鉴权的合约所有人转移 、初始化等)暴露也会造成严重的后果 代码片段 function destroycontract(address _to){ selfdestruct(_to); } 这个函数是销毁合约的函数,但是却没有进行修饰 ,导致任何人都可以调用这个函数来销毁合约 代码调试 https://cn.etherscan.com/address/0xb5c0e43a6330b9eb904ec57ea24d70269ae4652e
所有函数调用都是虚函数,这意味着会是调用派生函数最多的函数,除非明确给出了合约名称。当某一个智能合约从多个合约继承时,只在区块链上创建一个智能合约,并将所有基础合约中的代码复制到创建的智能合约中。 external函数f不能在内部调用(即f()不起作用,但this.f()起作用)。当外部函数接收大量数据时,它们有时会更有效。 public:公共函数是智能合约接口的一部分,可以在内部调用,也可以通过消息调用。对于公共状态变量,会生成自动getter函数(见下文)。 (owner); } function destroyAndSend(address _recipient) onlyOwner { selfdestruct(_recipient); (owner); } function destroyAndSend(address _recipient) onlyOwner { selfdestruct(_recipient);
主要函数kill:selfdestruct 是 ethereum 智能合约自带的自毁程序,kill对此方法进行了封装,只有合约的拥有者才可以调用该方法;greet:返回合约 greeter 里的 greeting address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) selfdestruct contract.address); console.log(contract); } }})greeterContract.new方法的第一个参数设置了这个新合约的构造函数初始化的值 , 和用于创建新合约的费用gas.gas是一个估计值,只要比所需要的gas多就可以 ,合约创建完成后剩下的gas会退还给合约创建者.greeterContract.new方法的第三个参数设置了一个回调函数
: 上海升级计划,包含取款相关的 EIP, 潜在可能都会包含 EIP 有:EOF(EVM Object Format), EIP4844(proto-danksharding), EIP4758(停用SELFDESTRUCT ),EIP1153(临时存储操作码)和 EIP2537 (BLS12 预编译) 下一次视频会议重点将是上海升级 EIP 的分类 `SELFDESTRUCT`的用户需要注意[4],计划停用SELFDESTRUCT 23]: 合约事件 hooks 开发者资料 OpenZeppelin 合约 v4.8[24]: 批量 ERC721 铸造降低 gas 成本,投票 gas 优化,两步所有权转让,log2/10/256 函数在 Christine Kim: https://www.galaxy.com/research/insights/ethereum-all-core-developers-call-149/ [4] SELFDESTRUCT 的用户需要注意: https://ethereum-magicians.org/t/eip-4758-deactivate-selfdestruct/8710 [5] Helios: https://a16zcrypto.com
=1); } if(token.balanceOf(this)==0){ //airdrop is over selfdestruct == answer) { token.safeTransfer(msg.sender,token.balanceOf(address(this))); selfdestruct =1); } if(token.balanceOf(this)==0){ //airdrop is over selfdestruct(msg.sender (msg.sender); } } 其实回到题目本身来看,我们的目的是要拿走合约里的所有eth,在合约里,唯一仅有的转账办法就是selfdestruct,所以我们的目的就是想办法触发这个函数。 销毁函数只在fallback和lottery函数中存在,其实阅读一下不难发现,lottery不可能有任何操作,没办法溢出,没办法修改,除非运气逆天,否则不可能从lottery函数触发这个函数。