외부 계약 방지
                                            
                                                
                                                
                                                
                                                
                                                
                                                 8162 단어  soliditysecuritybestpractice
                    
그건 그렇고, 흥미를 느끼신다면 스마트 컨트랙트 취약점에 대한 시리즈를 만들었습니다( )
하지만 함수 호출자가 컨트랙트인지 일반 지갑 주소인지 알 수 있는 방법이 있다면 어떨까요?
그런 다음 외부 계약이 계약과 상호 작용하는 것을 중지하여 계약이 해킹되는 것을 방지할 수 있습니다.
이것이 어떻게 달성될 수 있는지 봅시다:
MyContract 함수를 호출하기 위해 외부 계약을 중지하는 경우에는 그렇지 않습니다. 😎// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.1;
contract MyContract { // this contract is vulnerable to re-entracy attack
    mapping (address => uint) balances;
    modifier noContract { // this won't allow external contracts to interact with this contract
        require(tx.origin == msg.sender, "No contracts allowed");
        _;
    }
    function deposit() external payable noContract { // using noContract 
        balances[msg.sender] += msg.value;
    }
    function withdraw() external payable noContract { // using noContract 
        uint amount = balances[msg.sender];
        require(amount > 0, "Nothing to withdraw");
        (bool sent, ) = msg.sender.call{value: amount}("");
        require(sent, "Send operation failed");
        balances[msg.sender] = 0;
    }
    function getBalance() external view returns(uint balance) {
        balance = address(this).balance;
    }
}
noContract 수정자를 사용하여 외부 스마트 계약을 중지하고 있습니다. 함수 호출자( msg.sender )가 트랜잭션 개시자( tx.origin )와 동일한지 확인합니다.tx.origin에 대해 더 알고 싶습니까? 방문이제 일부 공격자 계약이 MyContract에서 자금을 훔치려고 시도하면 거래가 실패합니다.
공격자 계약:
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.1;
interface IMyContract{
    function deposit() external payable;
    function withdraw() external payable;
}
contract Attacker {
    IMyContract myContract;
    constructor(address _myContract) payable {
        myContract = IMyContract(_myContract);
    }
    fallback() external payable {
        if (address(myContract).balance > 0) {
            myContract.withdraw();
        }
    }
    function attack() external payable {
        myContract.deposit{value: 1 ether}();
        myContract.withdraw();
    }
    function getBalance() external view returns(uint balance) {
        balance = address(this).balance;
    }
}
Reference
이 문제에 관하여(외부 계약 방지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rushanksavant/prevent-contract-to-call-1bfk텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)