
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讲:数字签名。 数字签名一般有两种常见的重放攻击...
Share Dialog
Share Dialog
WTF Academy: wtf.academy

Subscribe to 0xAA

Subscribe to 0xAA
>100 subscribers
>100 subscribers
我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。
欢迎关注我的推特:@0xAA_Science
WTF技术社群discord,内有加微信群方法:链接
所有代码和教程开源在github(1024个star发课程认证,2048个star发社群NFT): github.com/AmazingAng/WTFSolidity
不知不觉我已经完成了Solidity极简教程的前13讲(基础),内容包括:Helloworld.sol,变量类型,存储位置,函数,控制流,构造函数,修饰器,事件,继承,抽象合约,接口,库,异常。在进阶内容之前,我决定做一个ERC721的专题,把之前的内容综合运用,帮助大家更好的复习基础知识,并且更深刻的理解ERC721合约。希望在学习完这个专题之后,每个人都能发行自己的NFT。
ERC721的主合约一共引用了4个接口合约:IERC721.sol, IERC721Receiver.sol, IERC721Metadata.sol,和间接引用的ERC165的IERC165.sol。这一讲我们将逐个介绍这4个接口合约。
首先我们介绍一下EIP165(以太坊改进建议第165条),他的目的是创建一个标准方法来发布和检测智能合约实现的接口。讲一个去年年底发生的真实事件,PeopleDAO有个朋友错转了4000w枚PEOPLE到代币合约。但合约没有实现转出代币的功能,只能进不能出,这些代币直接锁死在里面销毁了。试想一下,如果在转账的时候自动判断接收方合约是否实现了相应的接口,没实现的话就revert交易,很多错转代币的悲剧都不会发生。EIP165就是干这个的,而ERC165就是EIP165的实现。
IERC165是ERC165的接口合约,只有一个函数supportsInterface(),输入想查询的接口的interfaceId,返回一个bool告诉你合约是否实现了该接口。
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
ERC721主合约对supportsInterface()的实现如下:
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
可以看到,ERC721实现了IERC721,IERC721Metadata和IERC165的接口,查询的时候会返回true;否则返回false。我会在进阶内容中更详细的介绍function selector和interfaceId。
IERC721是ERC721的接口合约,里面包括3个event和9个function:
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}
其中event包括:
Transfer事件:在转账时被释放,记录代币的发出地址from,接收地址to和tokenid。
Approval事件:在授权时释放,记录approve的发出地址owner,被授权地址approved和tokenid。
ApprovalForAll事件:在批量授权时释放,记录approve的发出地址owner,被授权地址operator和是否被授权approved。
其中function包括:
balanceOf:参数为要查询的地address,返回该地址的NFT持有量balance。
ownerOf:参数为要查询的tokenId,返回这个tokenId的主人owner。
safeTransferFrom:安全转账(如果接收方是合约地址,会要求实现ERC721的接收接口)。参数为转出地址from,接收地址to和tokenId。
transferFrom:普通转账(不检查对方是否实现ERC721的接收接口),参数为转出地址from,接收地址to和tokenId。
approve:授权,批准另一个地址使用你的NFT。参数为被授权地址approve和tokenId。
getApproved:查询NFT被批准给了哪个地址,参数为
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
IERC721Receiver接口包含了一个函数onERC721Received()。这个函数会在safeTransferFrom()中被调用,代币的接收合约必须实现这个接口才能转账成功。
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
IERC721Metadata是ERC721的拓展接口,实现了3个查询metadata的常用函数:
name():返回代币名称。
symbol():返回代币代号
tokenURI():通过tokenId查询metadata所在url。
本文是ERC721专题的第二讲,我们介绍了ERC721主合约调用的4个接口合约IERC165,IERC721,IERC721Receiver和IERC721Metadata。下一讲终于该介绍ERC721主合约了!LFG!
我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。
欢迎关注我的推特:@0xAA_Science
WTF技术社群discord,内有加微信群方法:链接
所有代码和教程开源在github(1024个star发课程认证,2048个star发社群NFT): github.com/AmazingAng/WTFSolidity
不知不觉我已经完成了Solidity极简教程的前13讲(基础),内容包括:Helloworld.sol,变量类型,存储位置,函数,控制流,构造函数,修饰器,事件,继承,抽象合约,接口,库,异常。在进阶内容之前,我决定做一个ERC721的专题,把之前的内容综合运用,帮助大家更好的复习基础知识,并且更深刻的理解ERC721合约。希望在学习完这个专题之后,每个人都能发行自己的NFT。
ERC721的主合约一共引用了4个接口合约:IERC721.sol, IERC721Receiver.sol, IERC721Metadata.sol,和间接引用的ERC165的IERC165.sol。这一讲我们将逐个介绍这4个接口合约。
首先我们介绍一下EIP165(以太坊改进建议第165条),他的目的是创建一个标准方法来发布和检测智能合约实现的接口。讲一个去年年底发生的真实事件,PeopleDAO有个朋友错转了4000w枚PEOPLE到代币合约。但合约没有实现转出代币的功能,只能进不能出,这些代币直接锁死在里面销毁了。试想一下,如果在转账的时候自动判断接收方合约是否实现了相应的接口,没实现的话就revert交易,很多错转代币的悲剧都不会发生。EIP165就是干这个的,而ERC165就是EIP165的实现。
IERC165是ERC165的接口合约,只有一个函数supportsInterface(),输入想查询的接口的interfaceId,返回一个bool告诉你合约是否实现了该接口。
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
ERC721主合约对supportsInterface()的实现如下:
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
可以看到,ERC721实现了IERC721,IERC721Metadata和IERC165的接口,查询的时候会返回true;否则返回false。我会在进阶内容中更详细的介绍function selector和interfaceId。
IERC721是ERC721的接口合约,里面包括3个event和9个function:
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}
其中event包括:
Transfer事件:在转账时被释放,记录代币的发出地址from,接收地址to和tokenid。
Approval事件:在授权时释放,记录approve的发出地址owner,被授权地址approved和tokenid。
ApprovalForAll事件:在批量授权时释放,记录approve的发出地址owner,被授权地址operator和是否被授权approved。
其中function包括:
balanceOf:参数为要查询的地address,返回该地址的NFT持有量balance。
ownerOf:参数为要查询的tokenId,返回这个tokenId的主人owner。
safeTransferFrom:安全转账(如果接收方是合约地址,会要求实现ERC721的接收接口)。参数为转出地址from,接收地址to和tokenId。
transferFrom:普通转账(不检查对方是否实现ERC721的接收接口),参数为转出地址from,接收地址to和tokenId。
approve:授权,批准另一个地址使用你的NFT。参数为被授权地址approve和tokenId。
getApproved:查询NFT被批准给了哪个地址,参数为
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
IERC721Receiver接口包含了一个函数onERC721Received()。这个函数会在safeTransferFrom()中被调用,代币的接收合约必须实现这个接口才能转账成功。
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
IERC721Metadata是ERC721的拓展接口,实现了3个查询metadata的常用函数:
name():返回代币名称。
symbol():返回代币代号
tokenURI():通过tokenId查询metadata所在url。
本文是ERC721专题的第二讲,我们介绍了ERC721主合约调用的4个接口合约IERC165,IERC721,IERC721Receiver和IERC721Metadata。下一讲终于该介绍ERC721主合约了!LFG!
approvesetApprovalForAll:将自己持有的这类NFT批量授权给某个地址,参数为被授权的地址operator和是否授权approved。
isApprovedForAll:查询某人的NFT是否批量授权给了某个地址,参数为授权方owner和被授权地址operator,返回bool。
safeTransferFrom:安全转账,与3.不同的地方在于参数里面包含了data,可以做额外处理。
approvesetApprovalForAll:将自己持有的这类NFT批量授权给某个地址,参数为被授权的地址operator和是否授权approved。
isApprovedForAll:查询某人的NFT是否批量授权给了某个地址,参数为授权方owner和被授权地址operator,返回bool。
safeTransferFrom:安全转账,与3.不同的地方在于参数里面包含了data,可以做额外处理。
No activity yet