
WTF Solidity 合约安全: S08. 绕过合约检查
我最近在重新学solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。 推特:@0xAA_Science|@WTFAcademy_ 社区:Discord|微信群|官网 wtf.academy 所有代码和教程开源在github: github.com/AmazingAng/WTFSolidity这一讲,我们将介绍绕过合约长度检查,并介绍预防的方法。绕过合约检查很多 freemint 的项目为了限制科学家(程序员)会用到 isContract() 方法,希望将调用者 msg.sender 限制为外部账户(EOA),而非合约。这个函数利用 extcodesize 获取该地址所存储的 bytecode 长度(runtime),若大于0,则判断为合约,否则就是EOA(用户)。 // 利用 extcodesize 检查是否为合约 function isContract(address account) public view returns (bool) { // extcodesize > 0 的地址一定是合约...

WTF Solidity 合约安全: S09. 拒绝服务
我最近在重新学solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。 推特:@0xAA_Science|@WTFAcademy_ 社区:Discord|微信群|官网 wtf.academy 所有代码和教程开源在github: github.com/AmazingAng/WTFSolidity这一讲,我们将介绍智能合约的拒绝服务(Denial of Service, DoS)漏洞,并介绍预防的方法。NFT项目 Akutar 曾因为 DoS 漏洞损失 11,539 ETH,当时价值 3400 万美元。DoS在 Web2 中,拒绝服务攻击(DoS)是指通过向服务器发送大量垃圾信息或干扰信息的方式,导致服务器无法向正常用户提供服务的现象。而在 Web3,它指的是利用漏洞使得智能合约无法正常提供服务。 在2022年4月,一个很火的 NFT 项目名为 Akutar,他们使用荷兰拍卖进行公开发行,筹集了 11,539.5 ETH,非常成功。之前持有他们社区Pass的参与者会得到 0.5 ETH的退款,但是他们处理...

WTF Solidity 合约安全 S06. 签名重放
我最近在重新学solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。 推特:@0xAA_Science|@WTFAcademy_ 社区:Discord|微信群|官网 wtf.academy 所有代码和教程开源在github: github.com/AmazingAng/WTFSolidity这一讲,我们将介绍智能合约的签名重放(Signature Replay)攻击和预防方法,它曾间接导致了著名做市商 Wintermute 被盗2000万枚 $OP。签名重放上学的时候,老师经常会让家长签字,有时候家长很忙,我就会很“贴心”照着以前的签字抄一遍。某种意义上来说,这就是签名重放。 在区块链中,数字签名可以用于识别数据签名者和验证数据完整性。发送交易时,用户使用私钥签名交易,使得其他人可以验证交易是由相应账户发出的。智能合约也能利用 ECDSA 算法验证用户将在链下创建的签名,然后执行铸造或转账等逻辑。更多关于数字签名的介绍请见WTF Solidity第37讲:数字签名。 数字签名一般有两种常见的重放攻击...
WTF Academy: wtf.academy

WTF Solidity 合约安全: S08. 绕过合约检查
我最近在重新学solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。 推特:@0xAA_Science|@WTFAcademy_ 社区:Discord|微信群|官网 wtf.academy 所有代码和教程开源在github: github.com/AmazingAng/WTFSolidity这一讲,我们将介绍绕过合约长度检查,并介绍预防的方法。绕过合约检查很多 freemint 的项目为了限制科学家(程序员)会用到 isContract() 方法,希望将调用者 msg.sender 限制为外部账户(EOA),而非合约。这个函数利用 extcodesize 获取该地址所存储的 bytecode 长度(runtime),若大于0,则判断为合约,否则就是EOA(用户)。 // 利用 extcodesize 检查是否为合约 function isContract(address account) public view returns (bool) { // extcodesize > 0 的地址一定是合约...

WTF Solidity 合约安全: S09. 拒绝服务
我最近在重新学solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。 推特:@0xAA_Science|@WTFAcademy_ 社区:Discord|微信群|官网 wtf.academy 所有代码和教程开源在github: github.com/AmazingAng/WTFSolidity这一讲,我们将介绍智能合约的拒绝服务(Denial of Service, DoS)漏洞,并介绍预防的方法。NFT项目 Akutar 曾因为 DoS 漏洞损失 11,539 ETH,当时价值 3400 万美元。DoS在 Web2 中,拒绝服务攻击(DoS)是指通过向服务器发送大量垃圾信息或干扰信息的方式,导致服务器无法向正常用户提供服务的现象。而在 Web3,它指的是利用漏洞使得智能合约无法正常提供服务。 在2022年4月,一个很火的 NFT 项目名为 Akutar,他们使用荷兰拍卖进行公开发行,筹集了 11,539.5 ETH,非常成功。之前持有他们社区Pass的参与者会得到 0.5 ETH的退款,但是他们处理...

WTF Solidity 合约安全 S06. 签名重放
我最近在重新学solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。 推特:@0xAA_Science|@WTFAcademy_ 社区:Discord|微信群|官网 wtf.academy 所有代码和教程开源在github: github.com/AmazingAng/WTFSolidity这一讲,我们将介绍智能合约的签名重放(Signature Replay)攻击和预防方法,它曾间接导致了著名做市商 Wintermute 被盗2000万枚 $OP。签名重放上学的时候,老师经常会让家长签字,有时候家长很忙,我就会很“贴心”照着以前的签字抄一遍。某种意义上来说,这就是签名重放。 在区块链中,数字签名可以用于识别数据签名者和验证数据完整性。发送交易时,用户使用私钥签名交易,使得其他人可以验证交易是由相应账户发出的。智能合约也能利用 ECDSA 算法验证用户将在链下创建的签名,然后执行铸造或转账等逻辑。更多关于数字签名的介绍请见WTF Solidity第37讲:数字签名。 数字签名一般有两种常见的重放攻击...
WTF Academy: wtf.academy

Subscribe to 0xAA

Subscribe to 0xAA


Share Dialog
Share Dialog
>100 subscribers
>100 subscribers
我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。
欢迎关注我的推特:@0xAA_Science
WTF技术社群discord,内有加微信群方法:链接
所有代码和教程开源在github(1024个star发课程认证,2048个star发社群NFT): github.com/AmazingAng/WTFSolidity
开发者写智能合约来调用其他合约,这让以太坊网络上的程序可以复用,从而建立繁荣的生态。很多web3项目依赖于调用其他合约,比如收益农场(yield farming)。这一讲,我们介绍如何在已知合约代码(或接口)和地址情况下调用目标合约的函数。
我们先写一个简单的合约OtherContract来调用。
contract OtherContract {
uint256 private _x = 0; // 状态变量x
// 收到eth的事件,记录amount和gas
event Log(uint amount, uint gas);
// 返回合约ETH余额
function getBalance() view public returns(uint) {
return address(this).balance;
}
// 可以调整状态变量_x的函数,并且可以往合约转ETH (payable)
function setX(uint256 x) external payable{
_x = x;
// 如果转入ETH,则释放Log事件
if(msg.value > 0){
emit Log(msg.value, gasleft());
}
}
// 读取x
function getX() external view returns(uint x){
x = _x;
}
}
这个合约包含一个状态变量x,一个事件Log在收到ETH时触发,三个函数:
getBalance(): 返回合约ETH余额。
setX(): external payable函数,可以设置x的值,并向合约发送ETH。
getX(): 读取x的值。
我们可以利用合约的地址和合约代码(或接口)来创建合约的引用:_Name(_Address),其中_Name是合约名,_Address是合约地址。然后用合约的引用来调用它的函数:_Name(_Address).f(),其中f()是要调用的函数。
下面我们介绍4个调用合约的例子:
我们可以在函数里传入目标合约地址,生成目标合约的引用,然后调用目标函数。以调用OtherContract合约的setX函数为例,我们在新合约中写一个callSetX函数,传入已部署好的OtherContract合约地址_Address和setX的参数x:
function callSetX(address _Address, uint256 x) external{
OtherContract(_Address).setX(x);
}
我们可以直接在函数里传入合约的引用,只需要把上面参数的address类型改为目标合约名,比OtherContract。下面例子实现了调用目标合约的getX()函数。
function callGetX(OtherContract _Address) external view returns(uint x){
x = _Address.getX();
}
我们可以创建合约变量,然后通过它来调用目标函数。下面例子,我们给变量oc存储了OtherContract合约的引用:
function callGetX2(address _Address) external view returns(uint x){
OtherContract oc = OtherContract(_Address);
x = oc.getX();
}
如果目标合约的函数是payable的,那么我们可以通过调用它来给合约转账:_Name(_Address).f{value: _Value}(),其中_Name是合约名,_Address是合约地址,f是目标函数名,_Value是要转的ETH数额(以wei为单位)。
OtherContract合约的setX函数是payable的,在下面这个例子中我们通过调用setX来往目标合约转账。
function setXTransferETH(address otherContract, uint256 x) payable external{
OtherContract(otherContract).setX{value: msg.value}(x);
}
转账后,我们可以通过Log事件和getBalance()函数观察目标合约ETH余额的变化。
这一讲,我们介绍如何在通过目标合约代码(或接口)和地址来创建合约的引用,从而调用目标合约的函数。
我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。
欢迎关注我的推特:@0xAA_Science
WTF技术社群discord,内有加微信群方法:链接
所有代码和教程开源在github(1024个star发课程认证,2048个star发社群NFT): github.com/AmazingAng/WTFSolidity
开发者写智能合约来调用其他合约,这让以太坊网络上的程序可以复用,从而建立繁荣的生态。很多web3项目依赖于调用其他合约,比如收益农场(yield farming)。这一讲,我们介绍如何在已知合约代码(或接口)和地址情况下调用目标合约的函数。
我们先写一个简单的合约OtherContract来调用。
contract OtherContract {
uint256 private _x = 0; // 状态变量x
// 收到eth的事件,记录amount和gas
event Log(uint amount, uint gas);
// 返回合约ETH余额
function getBalance() view public returns(uint) {
return address(this).balance;
}
// 可以调整状态变量_x的函数,并且可以往合约转ETH (payable)
function setX(uint256 x) external payable{
_x = x;
// 如果转入ETH,则释放Log事件
if(msg.value > 0){
emit Log(msg.value, gasleft());
}
}
// 读取x
function getX() external view returns(uint x){
x = _x;
}
}
这个合约包含一个状态变量x,一个事件Log在收到ETH时触发,三个函数:
getBalance(): 返回合约ETH余额。
setX(): external payable函数,可以设置x的值,并向合约发送ETH。
getX(): 读取x的值。
我们可以利用合约的地址和合约代码(或接口)来创建合约的引用:_Name(_Address),其中_Name是合约名,_Address是合约地址。然后用合约的引用来调用它的函数:_Name(_Address).f(),其中f()是要调用的函数。
下面我们介绍4个调用合约的例子:
我们可以在函数里传入目标合约地址,生成目标合约的引用,然后调用目标函数。以调用OtherContract合约的setX函数为例,我们在新合约中写一个callSetX函数,传入已部署好的OtherContract合约地址_Address和setX的参数x:
function callSetX(address _Address, uint256 x) external{
OtherContract(_Address).setX(x);
}
我们可以直接在函数里传入合约的引用,只需要把上面参数的address类型改为目标合约名,比OtherContract。下面例子实现了调用目标合约的getX()函数。
function callGetX(OtherContract _Address) external view returns(uint x){
x = _Address.getX();
}
我们可以创建合约变量,然后通过它来调用目标函数。下面例子,我们给变量oc存储了OtherContract合约的引用:
function callGetX2(address _Address) external view returns(uint x){
OtherContract oc = OtherContract(_Address);
x = oc.getX();
}
如果目标合约的函数是payable的,那么我们可以通过调用它来给合约转账:_Name(_Address).f{value: _Value}(),其中_Name是合约名,_Address是合约地址,f是目标函数名,_Value是要转的ETH数额(以wei为单位)。
OtherContract合约的setX函数是payable的,在下面这个例子中我们通过调用setX来往目标合约转账。
function setXTransferETH(address otherContract, uint256 x) payable external{
OtherContract(otherContract).setX{value: msg.value}(x);
}
转账后,我们可以通过Log事件和getBalance()函数观察目标合约ETH余额的变化。
这一讲,我们介绍如何在通过目标合约代码(或接口)和地址来创建合约的引用,从而调用目标合约的函数。
No activity yet