ERC20令牌,函数“ balanceOf(address _owner)”返回0

时间:2018-08-21 10:49:35

标签: solidity web3 erc20

大家好:)

我有问题-从Web3调用时,包含在ERC20TokenInterface中的函数称为“ functionOf(address _owner)”返回0(将在下面提供版本)

package.json

{
  "name": "kilotzar",
  "version": "1.0.0",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bignumber.js": "^7.2.1",
    "erc20-contract-js": "^1.1.1",
    "express": "^4.16.3",
    "npm-git-install": "^0.3.0",
    "requirejs": "^2.3.5",
    "web3": "github:ethereum/web3.js"
  },
  "devDependencies": {},
  "description": ""
}

ERC20Implementation.sol

pragma solidity ^0.4.24;

import "./EIP20Interface.sol";
import "./SafeMath.sol";


/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * https://github.com/ethereum/EIPs/issues/20
 * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract EIP20Implementation is EIP20Interface {

  using SafeMath for uint256;

  mapping(address => uint256) balances;

  mapping (address => mapping (address => uint256)) internal allowed;

  string public name; 
  uint8 public decimals;
  string public symbol;

  /**
   * added up to a basic contract - create merge request on url: https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/StandardToken.sol; 
   * @dev Constructor with initial parameters
   * @param _initialAmount = intial supply of tokens to be created
   * @param _tokenName = name of the tokens
   * @param _decimalUnits = number of the decimal ( in a direct relation with _tokenSupply)
   * @param _tokenSymbol = abbreviation of token name (doens't have to really be related with _tokenName)
  */

  constructor(
    uint _initialAmount,
    string _tokenName, 
    uint8 _decimalUnits,
    string _tokenSymbol

  ) public {

    balances[msg.sender] = _initialAmount;
    totalSupply = _initialAmount; 
    name = _tokenName;
    decimals = _decimalUnits;
    symbol = _tokenSymbol;
  }
  /**
  * @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.
  */
  // We already have automatically generated getter for mapping structure ( balances ) [but it is needed in order to fulfill [ERC20 Interface];
   function balanceOf(address _owner) public view returns (uint256) {
     return balances[_owner];
   }
  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender. ( Look more careful next time, it's just a getter function for list of allowed spenders)
   * @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];
  }

  /**
  * @dev Transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(
    address _to,
    uint256 _value
   ) public 
     returns (bool)
   {
    require(_value <= balances[msg.sender]);
    require(_to != address(0));

    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _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
    ) public
      returns (bool) 
   {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
   }

  /**
   * @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
  )
    public
    returns (bool)
  {
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);
    require(_to != address(0));

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

  /**
   * @dev Increase the amount of tokens that an owner allowed to a 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
   * @param _spender The address which will spend the funds.
   * @param _addedValue The amount of tokens to increase the allowance by.
   */
  function increaseApproval(
    address _spender,
    uint256 _addedValue
  )
    public
    returns (bool)
  {
    allowed[msg.sender][_spender] = (
      allowed[msg.sender][_spender].add(_addedValue));
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   * approve should be called when allowed[_spender] == 0. To decrement
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param _spender The address which will spend the funds.
   * @param _subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseApproval(
    address _spender,
    uint256 _subtractedValue
  )
    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);
    }
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }
  /**
   * @dev (Fallback) function in order to protect ether from intermedium - idea is not to send ether to smart_contract that represents particular token;
   */
  // function () public payable{
  //   revert();
  // }

}

container.js

//address of second account -> for testing purposes: 0xcce3556109e5be65be122dc9a145a4ad4d7f1125 ;
// to do: 1. fix indirect insertion of value; 
var contractAbi = [
    {
        "anonymous": false,
        "inputs": [
            {
                "indexed": true,
                "name": "_owner",
                "type": "address"
            },
            {
                "indexed": true,
                "name": "_spender",
                "type": "address"
            },
            {
                "indexed": false,
                "name": "_value",
                "type": "uint256"
            }
        ],
        "name": "Approval",
        "type": "event"
    },
    {
        "constant": false,
        "inputs": [
            {
                "name": "_spender",
                "type": "address"
            },
            {
                "name": "_value",
                "type": "uint256"
            }
        ],
        "name": "approve",
        "outputs": [
            {
                "name": "",
                "type": "bool"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": false,
        "inputs": [
            {
                "name": "_spender",
                "type": "address"
            },
            {
                "name": "_subtractedValue",
                "type": "uint256"
            }
        ],
        "name": "decreaseApproval",
        "outputs": [
            {
                "name": "",
                "type": "bool"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": false,
        "inputs": [
            {
                "name": "_spender",
                "type": "address"
            },
            {
                "name": "_addedValue",
                "type": "uint256"
            }
        ],
        "name": "increaseApproval",
        "outputs": [
            {
                "name": "",
                "type": "bool"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": false,
        "inputs": [
            {
                "name": "_to",
                "type": "address"
            },
            {
                "name": "_value",
                "type": "uint256"
            }
        ],
        "name": "transfer",
        "outputs": [
            {
                "name": "",
                "type": "bool"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "constant": false,
        "inputs": [
            {
                "name": "_from",
                "type": "address"
            },
            {
                "name": "_to",
                "type": "address"
            },
            {
                "name": "_value",
                "type": "uint256"
            }
        ],
        "name": "transferFrom",
        "outputs": [
            {
                "name": "",
                "type": "bool"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [
            {
                "name": "_initialAmount",
                "type": "uint256"
            },
            {
                "name": "_tokenName",
                "type": "string"
            },
            {
                "name": "_decimalUnits",
                "type": "uint8"
            },
            {
                "name": "_tokenSymbol",
                "type": "string"
            }
        ],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "anonymous": false,
        "inputs": [
            {
                "indexed": true,
                "name": "_from",
                "type": "address"
            },
            {
                "indexed": true,
                "name": "_to",
                "type": "address"
            },
            {
                "indexed": false,
                "name": "_value",
                "type": "uint256"
            }
        ],
        "name": "Transfer",
        "type": "event"
    },
    {
        "constant": true,
        "inputs": [
            {
                "name": "_owner",
                "type": "address"
            },
            {
                "name": "_spender",
                "type": "address"
            }
        ],
        "name": "allowance",
        "outputs": [
            {
                "name": "",
                "type": "uint256"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [
            {
                "name": "_owner",
                "type": "address"
            }
        ],
        "name": "balanceOf",
        "outputs": [
            {
                "name": "",
                "type": "uint256"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "decimals",
        "outputs": [
            {
                "name": "",
                "type": "uint8"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "name",
        "outputs": [
            {
                "name": "",
                "type": "string"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "symbol",
        "outputs": [
            {
                "name": "",
                "type": "string"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    },
    {
        "constant": true,
        "inputs": [],
        "name": "totalSupply",
        "outputs": [
            {
                "name": "",
                "type": "uint256"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    }
];
var contractAddress = "0xc591420b1575cc712995639c1c1569013a2b5498";
var contract;
var contractInstance;
var address;
var value;
var txStatus = false;
const owner = 0x2bf792e31b6a770ac5d8395e4255c102dd14c2d3;
const initialAmount = 1000000000; 

// const transactionObject = {
//   from: "0x2bf792e31b6a770ac5d8395e4255c102dd14c2d3",
//   to: contractAddress,
//   gas: 3000000,
//   gasPrice: 20000000000
// };

$(function(){

    initiate();
    valueListener();
    addressListener();
    transactListener();
    balanceListener();

    if(typeof web3!=='undefined'){
      web3 = new Web3(web3.currentProvider);
    }
    else{
      console.log("No web3 instance? You should consider trying MetaMask!")
      web3 = new Web3(new Web3.providers.HttpProvider(
          'https://ropsten.infura.io/efYr0Kza6Io9M1NPWYA7'
      ));
    }
    contract = web3.eth.contract(contractAbi);
    contractInstance = contract.at(contractAddress);

});
//util function
function hex2string(hexx) {
    var hex = hexx.toString();//force conversion
    var str = '';
    for (let i = 0; (i < hex.length && hex.substr(i, 2) !== '00'); i += 2)
        str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    return str;
}
//balance of a owner; 
function getBalance(owner){
    console.log("Getting contranct balance; ");
    console.log(web3.currentProvider);
    contractInstance.balanceOf.call(owner, function(error, success){
        if (error) console.log("error, function getBalance() : " + error);
        else {
            // let x = BigNumber(success);
            // console.log("success, function balanceOf() : " + x);
            console.log("success, function balanceOf() : " + hex2string(success));
            console.log("success, function balanceOf() : " + success);
        }
    });
}
//to do: list 1;
//transfer; 
function transfer(address, value){
    contractInstance.transfer.sendTransaction(address, value, function(error, success){
        if(error) console.log("error " + error);
        else{
            alert("Uspesno pokrenuta transakcija");
            let intervalId = window.setInterval(function(){
                transactionStatus(success);
                if (txStatus) {
                    changeTxStatus();
                    window.clearInterval(intervalId);
                }
            }, 7000);

        } 
    });
}
//listener for transaction status; 
function transactionStatus(transactionHash){
    web3.eth.getTransactionReceipt(transactionHash, function(error, success){
        if(error) console.log("Something wrong happend " + error);
        else{
            if(success != null){
                txStatus = true;
            }   
        }
    });
}
// not container (web3 related) functions;

// from dropdown menu to value bar value; 
function initiate(){
    $('#dd > a').each(function(){
    $(this).on('click', function(event){
        let temporary = $(this).html();
          $('#value').attr("value", temporary);
          $('#value').val(temporary);
    });
  });
    // totalSupply();

}
//directly inserted into value bar;
function valueListener(){
    $('#value').change(function(event){
        let temporary = $('#value').val();
            $('#value').attr("value", temporary);
            $('#value').val(temporary);
            setValue();
    });
}
//directly inserted into address bar;
function addressListener(){
    $('#address').change(function(event){
        let temporary = $('#address').val();
            $('#address').attr("value", temporary);
            $('#address').val(temporary);
            setAddress();
    });
}
// only to change status of transaction from "pending/waiting" to "success"
function changeTxStatus(){
    $('body > div > div.transactionContainer > form > div.txStatus > p').html('Success');
    $('body > div > div.transactionContainer > form > div.txStatus > p').css('color', 'green');
}
//button listeners; 
//listener that will start transaction when 'submit' button is triggered; 
function transactListener(){
    $('#transactionButton').on('click', function(){
        $('.txStatus').css('display', 'block');
        transfer(getAddress(), getValue());
    });
}
// listener that will triger "getBalance()" call when 'submit' button is trigered; 
function balanceListener(){
    $('#balanceButton').on('click', function(){
        getBalance(owner);
    });
}
function getValue(){
  return value; 
}
function getAddress(){
  return address;
}
function setValue(){
  value = $('#value').attr("value");
}
function setAddress(){
  address = $('#address').attr("value");
}

但是当我从RemixIDE界面调用它时,它可以正常工作。 提供者是MetaMask。 提前致谢! :)

0 个答案:

没有答案