Ошибка парсера криптовалюты в конечной строке смарт — контакта?

#ethereum #solidity #cryptocurrency

Вопрос:

Последние несколько часов я работал над смарт-контрактом для криптовалюты и готовился к его составлению. Но когда пришло время его компилировать, я получил сообщение об ошибке от Solidity, в котором говорилось: «Ошибка синтаксического анализа: Ожидаемая прагма, директива импорта или определение контракта/интерфейса/библиотеки». Это в последней строке, и я несколько раз проверил весь код, чтобы не увидеть ошибки. Любая помощь была бы очень кстати. Код приведен ниже:

 pragma solidity ^0.4.21;

// File: zepplin-solidity/contracts/ownership/Ownable.sol

contract Ownable {
    address public owner;
    
    event OwnershipTransferred(address indexed previousOwner,
    address indexed newOwner);
    
// @dev The Ownable constructor sets the original 'owner' of the contract to the sender
// account.

function Ownable() public {
    owner = msg.sender;
}

// if any other account besides owner

modifier onlyOwner() {
    requir(msg.sender == owner);
    _;
}

// to transfer ownership in case of event 

function transferOwnership(address newOwner) public onlyOwner 
{
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
}

}
// Safemath protocol

library SafeMath {
    function mul(uint256 a, uint256 b) internal pure returns 
    (uint256) {
        if (a == 0) {
            return 0;
        }
        uint256 c = a * b;
        assert(c / a == b);
        return c; 
    }
    function div(uint256 a, uint256 b) internal pure returns
    (uint256) {
        // assrt(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b; 
        // assert(a == b * c   a % b); // There is no case in which this doesn't hold
        return c;
    }
    function sub(unit256 a, uint256 b) internal pure returns 
    (uint256) {
        assert(b <= a);
        return a - b; 
    }
    function add(uint256 a, uint256 b) internal pure returns
    (uint256) {
        uint256 c = a   b;
        assert(c >= a);
        return c;
    }
}

// Smart contract title (ERC20)

contract ERC20 {
    uint256 public totalSupply;
  function balanceOf(address who) public view returns (uint256);

  function transfer (address to, uint256 value) public returns (bool);
  
  function allowance(address owner, address spender) public view returns (uint256);
  
  function transferFrom(addres from, address to, uint256 value) public returns (bool);
  
  function approve(address spender, uint256 value) public returns (bool);
  
  event Transfer(address indexed from, address indexed to, uint256 value);
  
  event approval(address indexed owner, address indexed spender, uint256 value);
    
}
contract HepburnA is ERC20, Ownable {
     using SafeMath for uint256; 
     
     // the controller of minting and destroying tokens
     address public hepburnDevmoon = 
     0x471E918a75A99038856eF9754368Eb1b5D15f9D5;
     
     // the controller of approving of minting and withdraw tokens 
     address public hepburnCommunitymoon = 
     0x0554c3CF2315FB98181d1FEBfaf083cDf68Fa145;
     
     struct TokensWithLock{
         uint256 value;
         uint256 blockNumber;
         
     }
     //Balances (shared with ERC20Basic replicant)
     mapping(address => uint256) balances;
     //When token numbers is less than incoming block
     mapping(address => TokenswithLock) lockTokens;
     
     mapping(address => mapping (address => uint256)) allowed; 
     // Token Cap
     uint256 public totalSupplyCap = 1e11;
     // Token Info
     string public name = "Hepburn A";
     string public symbol = "AUYHA";
     uint8 public decimals = 18;
     
     bool public mintingFinished = false;
     // the block number when deploy
     uint256 public deployBlockNumber = getCurrentBlockNumber();
     // the min threshold of lock time 
     uint256 public constant TIMETHRESHOLD = 9720;
     // the time when mintTokensWithinTime can be called 
     uint256 public constant MINTTIME = 291600;
     // the lock time of minted tokens 
     uint256 public durationOfLock = 9720;
     // True if transfers are allowed 
     bool public transferable = false; 
     // True if the transferable can be change 
     bool public canSetTransferable = true;
     
     modifier canMint() {
         require(!mintingFinished);
         _;
     }
     
     modifier only(address _address) {
         require(msg.sender == _address);
         _;
     }
     
     modifier nonZeroAddress(address _address) {
         require(_address != address(0));
         _;
     }
     
     modifier canTransfer() {
         require(transferable == true);
     }
     
     event SetDurationOfLock(address indexed _caller);
     event ApproveMintTokens(address indexed _owner, uint256 _amount);
     event WithdrawMintTokens(address indexed _owner, uint256 _amount);
     event MintTokens(address indexed _owner, uint256 _amount);
     event BurnTokens(address indexed _owner, uint256 _amount);
     event MintFinished(address indexed _caller);
     event setTransferable(address indexed _address, bool _transferable);
     event SethepburnDevmoon(address indexed _old, address indexed _new);
     event DisableSetTransferable(ddress indexed _address, bool _canSetTransferable);
     
     function transfer(address _to, uint256 _value) canTransfer public returns (bool) {
    require(_to != address(0));
    require(_value <= balances[msg.sender]);

    // SafeMath.sub will throw if there is not enough balance.
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    Transfer(msg.sender, _to, _value);
    return true;
  }

  /**
   * @dev Gets the balance of the specified address.
   * @param _owner The address to query the the balance of.
   * @return An uint256 representing the amount owned by the passed address.
   */
  function balanceOf(address _owner) public view returns (uint256 balance) 
  {
    return balances[_owner];
  }

  /**
   * @dev Transfer tokens from one address to another
   * @param _from address The address which you want to send tokens from
   * @param _to address The address which you want to transfer to
   * @param _value uint256 the amount of tokens to be transferred
   */
  function transferFrom(address _from, address _to, uint256 _value) canTransfer public returns (bool) {
    require(_to != address(0));
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    Transfer(_from, _to, _value);
    return true;
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   *
   * Beware that changing an allowance with this method brings the risk that someone may use both the old
   * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
   * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   * @param _spender The address which will spend the funds.
   * @param _value The amount of tokens to be spent.
   */
  function approve(address _spender, uint256 _value) canTransfer public returns (bool) {
    allowed[msg.sender][_spender] = _value;
    Approval(msg.sender, _spender, _value);
    return true;
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param _owner address The address which owns the funds.
   * @param _spender address The address which will spend the funds.
   * @return A uint256 specifying the amount of tokens still available for the spender.
   */
  function allowance(address _owner, address _spender) public view returns (uint256) {
    return allowed[_owner][_spender];
  }

  /**
   * approve should be called when allowed[_spender] == 0. To increment
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   */
  function increaseApproval(address _spender, uint256 _addedValue) canTransfer public returns (bool) {
    allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
    Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

  function decreaseApproval(address _spender, uint256 _subtractedValue) canTransfer public returns (bool) {
    uint256 oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue > oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }
  /**
   * @dev Enables token holders to transfer their tokens freely if true
   * @param _transferable True if transfers are allowed
   */
  function setTransferable(bool _transferable) only(hepburnDevmoon) public {
    require(canSetTransferable == true);
    transferable = _transferable;
    SetTransferable(msg.sender, _transferable);
  }

  /**
   * @dev disable the canSetTransferable
   */
  function disableSetTransferable() only(hepburnDevmoon) public {
    transferable = true;
    canSetTransferable = false;
    DisableSetTransferable(msg.sender, false);
  }

  /**
   * @dev Set the hepburnDevmoon
   * @param _hepburnDevmoon The new hepburnDevmoon
   */
  function SethepburnDevmoon(address _hepburnDevmoon) only(hepburnDevmoon) nonZeroAddress(_hepburnDevmoon) public {
   hepburnDevmoon = _hepburnDevmoon;
    SethepburnDevmoon(msg.sender, _hepburnDevmoon);
  }
  /**
   * @dev Set the hepburnCommunitymoon
   * @param _hepburnCommunitymoon The new hepburnCommunitymoon
   */
  function sethepburnCommunitymoon(address _hepburnCommunitymoon) only(hepburnCommunitymoon) nonZeroAddress(_hepburnCommunitymoon) public {
   hepburnCommunitymoon = _hepburnCommunitymoon;
    sethepburnCommunitymoon(msg.sender, _hepburnCommunitymoon);
  }
  /**
   * @dev Set the duration of lock of tokens approved of minting
   * @param _durationOfLock the new duration of lock
   */
  function setDurationOfLock(uint256 _durationOfLock) canMint only(hepburnCommunitymoon) public {
    require(_durationOfLock >= TIMETHRESHOLD);
    durationOfLock = _durationOfLock;
    SetDurationOfLock(msg.sender);
  }
  /**
   * @dev Get the quantity of locked tokens
   * @param _owner The address of locked tokens
   * @return the quantity and the lock time of locked tokens
   */
   function getLockTokens(address _owner) nonZeroAddress(_owner) view public returns (uint256 value, uint256 blockNumber) {
     return (lockTokens[_owner].value, lockTokens[_owner].blockNumber);
   }

  /**
   * @dev Approve of minting `_amount` tokens that are assigned to `_owner`
   * @param _owner The address that will be assigned the new tokens
   * @param _amount The quantity of tokens approved of mintting
   * @return True if the tokens are approved of mintting correctly
   */
  function approveMintTokens(address _owner, uint256 _amount) nonZeroAddress(_owner) canMint only(hepburnCommunitymoon) public returns (bool) {
    require(_amount > 0);
    uint256 previousLockTokens = lockTokens[_owner].value;
    require(previousLockTokens   _amount >= previousLockTokens);
    uint256 curTotalSupply = totalSupply;
    require(curTotalSupply   _amount >= curTotalSupply); // Check for overflow
    require(curTotalSupply   _amount <= totalSupplyCap);  // Check for overflow of total supply cap
    uint256 previousBalanceTo = balanceOf(_owner);
    require(previousBalanceTo   _amount >= previousBalanceTo); // Check for overflow
    lockTokens[_owner].value = previousLockTokens.add(_amount);
    uint256 curBlockNumber = getCurrentBlockNumber();
    lockTokens[_owner].blockNumber = curBlockNumber.add(durationOfLock);
    ApproveMintTokens(_owner, _amount);
    return true;
  }
  /**
   * @dev Withdraw approval of minting `_amount` tokens that are assigned to `_owner`
   * @param _owner The address that will be withdrawn the tokens
   * @param _amount The quantity of tokens withdrawn approval of mintting
   * @return True if the tokens are withdrawn correctly
   */
  function withdrawMintTokens(address _owner, uint256 _amount) nonZeroAddress(_owner) canMint only(hepburnCommunitymoon) public returns (bool) {
    require(_amount > 0);
    uint256 previousLockTokens = lockTokens[_owner].value;
    require(previousLockTokens - _amount >= 0);
    lockTokens[_owner].value = previousLockTokens.sub(_amount);
    if (previousLockTokens - _amount == 0) {
      lockTokens[_owner].blockNumber = 0;
    }
    WithdrawMintTokens(_owner, _amount);
    return true;
  }
  /**
   * @dev Mints `_amount` tokens that are assigned to `_owner`
   * @param _owner The address that will be assigned the new tokens
   * @return True if the tokens are minted correctly
   */
  function mintTokens(address _owner) canMint only(hepburnDevmoon) nonZeroAddress(_owner) public returns (bool) {
    require(lockTokens[_owner].blockNumber <= getCurrentBlockNumber());
    uint256 _amount = lockTokens[_owner].value;
    uint256 curTotalSupply = totalSupply;
    require(curTotalSupply   _amount >= curTotalSupply); // Check for overflow
    require(curTotalSupply   _amount <= totalSupplyCap);  // Check for overflow of total supply cap
    uint256 previousBalanceTo = balanceOf(_owner);
    require(previousBalanceTo   _amount >= previousBalanceTo); // Check for overflow
    
    totalSupply = curTotalSupply.add(_amount);
    balances[_owner] = previousBalanceTo.add(_amount);
    lockTokens[_owner].value = 0;
    lockTokens[_owner].blockNumber = 0;
    MintTokens(_owner, _amount);
    Transfer(0, _owner, _amount);
    return true;
  }
  /**
   * @dev Mints `_amount` tokens that are assigned to `_owner` within one day after deployment
   * the tokens minted will be added to balance immediately
   * @param _owner The address that will be assigned the new tokens
   * @param _amount The quantity of tokens withdrawn minted
   * @return True if the tokens are minted correctly
   */
  function mintTokensWithinTime(address _owner, uint256 _amount) nonZeroAddress(_owner) canMint only(hepburnDevmoon) public returns (bool) {
    require(_amount > 0);
    require(getCurrentBlockNumber() < (deployBlockNumber   MINTTIME));
    uint256 curTotalSupply = totalSupply;
    require(curTotalSupply   _amount >= curTotalSupply); // Check for overflow
    require(curTotalSupply   _amount <= totalSupplyCap);  // Check for overflow of total supply cap
    uint256 previousBalanceTo = balanceOf(_owner);
    require(previousBalanceTo   _amount >= previousBalanceTo); // Check for overflow
    
    totalSupply = curTotalSupply.add(_amount);
    balances[_owner] = previousBalanceTo.add(_amount);
    MintTokens(_owner, _amount);
    Transfer(0, _owner, _amount);
    return true;
  }
  /**
   * @dev Transfer tokens to multiple addresses
   * @param _addresses The addresses that will receieve tokens
   * @param _amounts The quantity of tokens that will be transferred
   * @return True if the tokens are transferred correctly
   */
  function transferForMultiAddresses(address[] _addresses, uint256[] _amounts) canTransfer public returns (bool) {
    for (uint256 i = 0; i < _addresses.length; i  ) {
      require(_addresses[i] != address(0));
      require(_amounts[i] <= balances[msg.sender]);
      require(_amounts[i] > 0);

      // SafeMath.sub will throw if there is not enough balance.
      balances[msg.sender] = balances[msg.sender].sub(_amounts[i]);
      balances[_addresses[i]] = balances[_addresses[i]].add(_amounts[i]);
      Transfer(msg.sender, _addresses[i], _amounts[i]);
    }
    return true;
  }

  /**
   * @dev Burns `_amount` tokens from `_owner`
   * @param _amount The quantity of tokens being burned
   * @return True if the tokens are burned correctly
   */
  function burnTokens(uint256 _amount) public returns (bool) {
    require(_amount > 0);
    uint256 curTotalSupply = totalSupply;
    require(curTotalSupply >= _amount);
    uint256 previousBalanceTo = balanceOf(msg.sender);
    require(previousBalanceTo >= _amount);
    totalSupply = curTotalSupply.sub(_amount);
    balances[msg.sender] = previousBalanceTo.sub(_amount);
    BurnTokens(msg.sender, _amount);
    Transfer(msg.sender, 0, _amount);
    return true;
  }
  /**
   * @dev Function to stop minting new tokens.
   * @return True if the operation was successful.
   */
  function finishMinting() only(hepburnDevmoon) canMint public returns (bool) {
    mintingFinished = true;
    MintFinished(msg.sender);
    return true;
  }

  function getCurrentBlockNumber() private view returns (uint256) {
    return block.number;
  }
}
}
}
 

Ответ №1:

У вас есть две дополнительные правые фигурные скобки ( } ) в конце кода. Я думаю, что именно поэтому вы получаете ошибку.

Ответ №2:

Некоторые Замечания:

  1. две дополнительные правые фигурные скобки в конце.
  2. в модификаторе onlyOwner () их опечатка (requir -> требуется).
  3. функция sub(unit256 a) опечатка, (unit256 -> uint256).
  4. опечатка адреса -> событие отключает возможность передачи(адрес _адрес с индексом ddr, bool _canSetTransferable);
  5. функция переноса из(адреса из) опечатки, (адреса -> адрес).
  6. модификатор canTransfer() должен содержать «_;».
  7. функция setTransferable -> попробуйте изменить имя этой функции, так как оно>
    совпадает с именем события, которое вы вызываете изнутри. (и может быть связано с префиксом «set» в имени функции, компилятор может выдать ошибку)
  8. рекомендуется, если вы вызываете какую-либо функцию, вызывать ее с тем же именем и в том же регистре
    (например, утверждение не как утверждение)
  9. Вызовите правильный метод SethepburnDevmoon, а не sethepburnCommunitymoon внутри функции sethepburnCommunitymoon.
  10. всякий раз, когда вы вызываете какое-либо событие, вы должны вызывать его, добавляя к нему префикс «испускать».
  11. ГАЗ, используемый по этому контракту при развертывании, составит почти 3800000 -> 0,07562 eth ->> почти 210 долларов США (на случай, если вы хотите знать) -счастливое кодирование 🙂

Комментарии:

1. Большое внимание к деталям! … Просто фактическое примечание к вашему пункту 10: В версии 0.4 (устаревшей) Solidity, которую использует OP, события генерируются без emit выражения, поэтому этот фрагмент на самом деле правильный.