Я пытаюсь создать контракт erc827token, который принимает различное количество эфира (0 для раздачи, 0,001, 0,002 >> для пожертвований.
code::
contract Airdrop coin is ERC827Token, Ownable {
string public constant name = "SimpleToken"; // solium-disable-line uppercase
string public constant symbol = "SIM"; // solium-disable-line uppercase
uint8 public constant decimals = 18; // solium-disable-line uppercase
uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(decimals));
/**
* @dev Constructor that gives msg.sender all of existing tokens.
*/
constructor() public {
totalSupply_ = INITIAL_SUPPLY;
}
function getAirdrop() external payable {
if (msg.value < 0.005 ether) {
balances[msg.sender] += 4000;
} else if ( (msg.value >= 0.005 ether) && (msg.value < 0.008)) {
balances[msg.sender] += 9000;
} else if ( (msg.value >= 0.008 ether) && (msg.value < 0.016)) {
balances[msg.sender] += 13000;
} else balances[msg.sender] += 25000;
}
problem::
Развертывание этого контракта работает, но токены не зачисляются на адреса, которые отправляют эфир на контракт токена.
Как мне изменить контракт, чтобы обеспечить ожидаемое поведение, и как переслать полученный eth во внешний кошелек (т. е. реализовать что-то вроде этого function withdraw() public onlyowner{}
)?
В вашем договоре есть ошибки:
getAirdrop
первом условном запросе требуется что-то между 0 и 0,005 эфира, поэтому люди могут получить столько токенов, сколько захотят, просто вызывая это много раз, отправляя 0 эфиров. Вместо этого вы можете спросить, например:if((msg.value <= 0.003 ether) && (msg.value < 0.005 ether))
(msg.value < 0.008)
должно быть (msg.value < 0.008 ether)
одинаковым для (msg.value < 0,016), которое должно быть (msg.value < 0,016 эфира)Добавление getAirdrop
функции в фолбэк решит проблему получения токенов в обмен на эфир и последующая передача владельцу даст эфир владельцу контракта.
Вот пример, использующий в основном код, который вы предоставили.
Обратите внимание , что это не удастся, если отправителем эфира является другой контракт, потому что transfer
функция только предоставляет 2300 gas
, а getAirdrop
функция потребляет больше.
pragma solidity ^0.4.24;
contract Airdrop {
mapping(address => uint256) public balances;
address public admin;
constructor() public {
owner = msg.sender;
}
function getAirdrop() public payable {
if (msg.value < 0.005 ether) {
balances[msg.sender] += 4000;
} else if ( (msg.value >= 0.005 ether) && (msg.value < 0.008 ether)) {
balances[msg.sender] += 9000;
} else if ( (msg.value >= 0.008 ether) && (msg.value < 0.016 ether)) {
balances[msg.sender] += 13000;
} else balances[msg.sender] += 25000;
}
function () payable public {
getAirdrop();
admin.transfer(msg.value);
}
}
Надеюсь это поможет
Скоп Мартин
if (msg.value < 0.005 ether)
однако было преднамеренным, так как я пытаюсь внедрить какой-то черный список в блоке, чтобы ограничить доступ (например, потребовать, чтобы msg.sender не был внесен в черный список, а затем добавить в черный список после этого утверждения).