我有一个带有铸造代币功能的 ERC20 代币合约。
此功能应允许用户在网站上执行特定操作或活动后铸造代币。如果用户成功执行操作,他将能够使用 mint 功能发送交易并接收代币。
我的工作流程和问题:为了防止用户直接与合约交互,想铸币就铸币,合约只允许某个 eth 地址调用铸币函数。如果操作成功执行,该特定地址将在服务器上设置并签署交易。但是,这意味着该地址也必须支付汽油费。
目前我正在考虑实现另一个合约,它将作为唯一可以调用 ERC20 合约上的 mint 函数的地址。这份新合约将接收来自用户的交易,其中包含由服务器地址签名和散列的变量、字符串和随机数。新合约将能够破译数据并知道交易确实得到了服务器的批准,并从代币合约中调用 mint 函数。这样,用户将无法直接尝试铸造代币或一遍又一遍地重新发送交易以获取更多代币。
我设想的一个可能且简单的实现如下:
服务器签署三条信息:用户地址、要铸造的数量和每笔交易递增的整数(又名 mintRequestId)——这种递增可以是随机的。
这三个散列字符串被传递给我的用户的客户端逻辑,并作为我的合同方法的参数,该方法提示发送:
myContract.methods.Mint(signedAddresses, signedMintAmount, signedMintRequestId).send({from: userWallet})
在我的合同中,我使用我的服务器的钱包公钥记录了三个参数,并且:
A. 将 msg.sender 与 signedAddresses 进行比较。
B. 获取金额。
C. 确保 mintRequestId 大于合约中保存的值。如果满足所有要求,则合同将批准铸币和 mintRequestId 合同更改。
这种方法是不是太简单了?弱点在哪里,你将如何修补它们?可以以某种方式伪造签名以及如何伪造?
谢谢你。