防止在NFT铸造时,用户使用合约机器人批量mint

1
2
3
4
modifier callerIsUser() {
require(tx.origin == msg.sender, "The caller is another contract");
_;
}

tx.origin代表交易来源,这始终为用户,也就是支付gasfee的用户。

msg.sender代表方法的调用方,这有可能为合约地址。

因此使用tx.origin==msg.sender来判断该用户是否为直接调用方法而非第三方合约调用。

举例如下:

Demo.sol

1
2
3
4
5
6
7
8
9
10
11
12
pragma solidity ^0.7.6;

contract Demo {
uint256 public a ;
address public senderAddress;
address public originAddress;
function set(uint256 num) external {
a = num;
senderAddress = msg.sender;
originAddress = tx.origin;
}
}

IDemo.sol

1
2
3
4
5
pragma solidity 0.7.6;

interface IDemo{
function set(uint256 a) external;
}

Demo1.sol

1
2
3
4
5
6
7
8
9
pragma solidity ^0.7.6;

import "./IDemo.sol";
contract Demo {
function set(address demoAddress,uint256 num) external {
IDemo demo = IDemo(demoAddress);
demo.set(num);
}
}

执行Demo1.sol的set方法后发现,senderAddress为Demo1.sol合约地址,而originAddress为我们自己的用户地址。