[英]Solidity crowdsale function fails on my web page but is successful when sent directly but doesn't send ERC20 on successful transaction
[英]ERC 20 Token transferFrom isn't working in my smart contract. Doesn't throw any Exception either
我在 Solidity 中编写了一份合同,并考虑了以下任务:
用户批准智能合约从他们的钱包中转移一定数量的代币。
智能合约使用此金额转移到作为参数给出的地址。 但它也需要从这个数量中提取 1 个代币才能转移给合约的开发者。
如果一切成功,用户会收到“支付成功”。 信息。
第一步(批准)是使用 React 和 Web3 完成的:
const derc20contract = '0x36850b80ad73fe66216609B9796ed6ceae8BE29F';
const handleClick = async (e) => {
e.preventDefault();
const prtmp = await detectEthereumProvider();
// -------------------- Approve Part ------------------------------//
const web3 = new Web3(prtmp);
const erc20contract = new web3.eth.Contract(
erc20abi,
derc20token,
{ from: '0xFromAddress' }
);
await erc20contract.methods.approve(derc20contract, web3.utils.toHex(3e18)).send();
// ---------------------------------------------------------------//
const contract = new web3.eth.Contract(derc20abi, derc20contract);
const response = await contract.methods.send_usdt(
'0xToAddress',
web3.utils.toHex(3e18)
)
.call({ from: '0xFromAddress'});
console.log(response);
};
一旦批准成功,function 的第二部分就解决了。 我部署的合约有一个名为 send_usdt 的send_usdt
。 通过这个 function 是我的智能合约能够转移批准的金额。
/ SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
interface IERC20 {
function transfer(address _to, uint256 _value) external returns(bool);
function transferFrom(address _from, address _to, uint _amount) external returns (bool);
function allowance(address _owner, address _contract) external returns (uint256);
function balanceOf(address _buyer) external view returns (uint256);
function approve(address _contract, uint tokens) external returns (bool);
}
contract DPortalSubscription {
address private owner;
mapping(address => uint32) subscription_fees;
constructor()
{
owner = msg.sender;
}
function check_balance() external view returns (uint256)
{
// TestToken ( Plasma Bridge ) in Mumbai Network
IERC20 usdt = IERC20(address(0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1));
uint256 balance = usdt.balanceOf(msg.sender);
return balance;
}
function check_sender_address() external view returns (address)
{
return msg.sender;
}
function check_allowance()external returns(uint256)
{
// TestToken ( Plasma Bridge ) in Mumbai Network
IERC20 usdt = IERC20(address(0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1));
uint256 allowance = usdt.allowance(msg.sender, address(this));
return allowance;
}
function send_usdt(address _to, uint256 _amount) external returns (string memory)
{
// TestToken ( Plasma Bridge ) in Mumbai Network
IERC20 usdt = IERC20(address(0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1));
require(_amount > 1, "Purchases must be higher than 1 usdt");
require(usdt.balanceOf(msg.sender) >= _amount, "The buyer doesn't have enough funds");
require(usdt.allowance(msg.sender, address(this)) >= _amount, "Permissions to transfer tokens denied");
require(usdt.transferFrom(msg.sender, _to, _amount-1) == true, "Couldn't transfer tokens to seller");
require(usdt.transferFrom(msg.sender, owner, 1) == true, "Couldn't transfer tokens to support");
return "Payment successful!";
}
}
一旦 React 中 function 的第二部分解析完成,我就会收到“付款成功”的确认信息。 但是代币没有被转移,我在“来自钱包”中保留了相同的金额。 像以前一样“到钱包”和“部署钱包”。
问题出在反应片段中。 通过更改方法call
sell
的钱可以成功转移。
const response = await contract.methods.send_usdt
(
'0xToAddress',
web3.utils.toHex(3e18)
)
.call({ from: '0xFromAddress' });
改为:
const response = await contract.methods.send_usdt
(
'0xToAddress',
web3.utils.toHex(3e18),
{ from: '0xFromAddress' }
)
.send();
这有效,但提出了另一个问题。 当我使用前面的call
方法时,function 返回“支付成功”。 并使用 sell 方法收到一个对象。
由于“付款成功”不是真的,我想知道当有人使用 call 方法与我的合约交互时是否可以抛出异常。
那可能吗?
尝试将其从 require 语句中移出应该可以工作。
按照@Kuly14 的回答,为了更清楚,您可能需要创建以下 function :
function send_usdt(address _to, uint256 _amount) external returns (string memory) {
// TestToken ( Plasma Bridge ) in Mumbai Network
IERC20 usdt = IERC20(address(0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1));
require(_amount > 1, "Purchases must be higher than 1 usdt");
usdt.transferFrom(msg.sender, owner, 1);
usdt.transferFrom(msg.sender, _to, _amount-1);
return "Payment successful!";
}
注1:只要调用transferFrom方法,如果出错就会跳转到对应的错误。 你不需要处理它们。
注2:我已更改您转移代币的顺序。 首先,我将它们发送给所有者,然后发送给所需的收件人以避免费用支付问题,但如果您更喜欢相反的方式,这是可能的。
我希望这个信息对您有所帮助:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.