7

I've created an ERC20 token. Now I want to use this token. Is it available to swap between ETH and the token automatically like the followings?

What I want:

  1. UserA send 1 ETH to the token owner's address.
  2. UserA receive 10 Token automatically.

To do that, should I deploy another contract?

I read the definition of ERC20 on this page. Is "approve" what I should use...?

What are the key criteria for meeting the ERC20 token standard?

I've used zeppelin-solidity to create the token.


Update 1

Thanks to travis-jacobs. I confirmed after I sent the created contract address 1 ETH then transfer the 1 ETH to transfer address.

Now, I'm trying to create call "getBalance" transaction.

deploy the contract

$ mkdir /tmp/zonotoken-infra
$ cd /tmp/zonotoken-infra
$ truffle unbox tutorialtoken
$ npm install ethereumjs-wallet bip39 web3-provider-engine@8.6.1 web3@0.18.4 zeppelin-solidity --save
$ vi ./truffle.js
$ vi ./contracts/ZonoToken.sol
$ vi ./migrations/2_deploy_contracts.js
$ truffle compile
$ truffle deploy —network ropsten

truffle.js

var bip39 = require("bip39");
var hdkey = require('ethereumjs-wallet/hdkey');
var ProviderEngine = require("web3-provider-engine");
var WalletSubprovider = require('web3-provider-engine/subproviders/wallet.js');
var Web3Subprovider = require("web3-provider-engine/subproviders/web3.js");
var Web3 = require("web3");
var FilterSubprovider = require('web3-provider-engine/subproviders/filters.js');

// Get our mnemonic and create an hdwallet
var mnemonic = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var hdwallet = hdkey.fromMasterSeed(bip39.mnemonicToSeed(mnemonic));

// Get the first account using the standard hd path.
var wallet_hdpath = "m/44'/60'/0'/0/";
var wallet = hdwallet.derivePath(wallet_hdpath + "0").getWallet();
var address = "0x" + wallet.getAddress().toString("hex");

var providerUrl = "https://testnet.infura.io";
var engine = new ProviderEngine();
engine.addProvider(new FilterSubprovider());
engine.addProvider(new WalletSubprovider(wallet, {}));
engine.addProvider(new Web3Subprovider(new Web3.providers.HttpProvider(providerUrl)));
engine.start(); // Required by the provider engine.

module.exports = {
  networks: {
    "ropsten": {
      network_id: 3,    // Official ropsten network id
      provider: engine, // Use our custom provider
      from: address,    // Use the address we derived
      gas: 4600000
    }
  },
  rpc: {
    // Use the default host and port when not using ropsten
    host: "localhost",
    port: 8545
  }
};

contracts/ZonoToken.sol

pragma solidity ^0.4.4;
import 'zeppelin-solidity/contracts/token/StandardToken.sol';
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';

contract ZonoToken is StandardToken {
  string public name = 'ZONO';
  string public symbol = 'ZONO';
  address public owner = 0x683821afb3f4f4fafffdb259254ae870a091e3b4;
  uint public decimals = 0;
  uint public INITIAL_SUPPLY = 100;

  function ZonoToken() {
    totalSupply = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
  }

  function() payable { deposit(); }

  function deposit() payable {
    owner.transfer(msg.value);
    uint newTokens = (msg.value * 10) / 1 ether;
    balances[msg.sender] = balances[msg.sender] + newTokens;
  }
}

migrations/2_deploy_contracts.js

var ZonoToken = artifacts.require("./ZonoToken.sol");

module.exports = function(deployer) {
  deployer.deploy(ZonoToken);
};

send ETH to the contract address and transfer automatically

from:0x5dbb9793537515398a1176d365b636a5321d9e39
to:0x5a65585ce8213d1c9433e63d53d4e468540a5019 (Contract)
transfer to:0x683821afb3f4f4fafffdb259254ae870a091e3b4

https://ropsten.etherscan.io/tx/0xea44ce75c9c8a27df1a570b73bfda32f86444d715acb14c7cdb20401d8a49a9f


Update 2

Now, I'm trying to create call "getBalance" transaction.

I found the way.

npm install

npm install truffle-contract --save

src/js/app.js

var Web3 = require("web3");
var TruffleContract = require("truffle-contract");
var TutorialTokenArtifact = require("../../build/contracts/ZonoToken.json");

App = {
  web3Provider: null,
  contracts: {},

  init: function() {
    return App.initWeb3();
  },

  initWeb3: function() {
    if (typeof web3 !== 'undefined') {
      App.web3Provider = web3.currentProvider;
      web3 = new Web3(web3.currentProvider);
    } else {
      App.web3Provider = new Web3.providers.HttpProvider('https://testnet.infura.io');
      web3 = new Web3(App.web3Provider);
    }
    return App.initContract();
  },

  initContract: function() {
    App.contracts.TutorialToken = TruffleContract(TutorialTokenArtifact);
    App.contracts.TutorialToken.setProvider(App.web3Provider);
    return App.getBalances();
  },

  getBalances: function(adopters, account) {
    console.log('Getting balances...');
    var tutorialTokenInstance;
    web3.eth.getAccounts(function(error, accounts) {
      if (error) {
        console.log(error);
      }
      var account = "0x5dbb9793537515398a1176d365b636a5321d9e39";
      App.contracts.TutorialToken.deployed().then(function(instance) {
        tutorialTokenInstance = instance;
        return tutorialTokenInstance.balanceOf(account);
      }).then(function(result) {
        balance = result.c[0];
        console.log(balance);
      }).catch(function(err) {
        console.log(err.message);
      });
    });
  }

};

App.init();

execute

$ node src/js/app.js 
Getting balances...
10

I'm still not sure my contract is the best way to exchange between ETH and Token. I'm looking into it.

7

You could add a function similar to this, either in a new contract, or by extending the token contract you are using.

A contract implementing this might be:

import "token/BasicToken.sol";
import "ownership/Ownable.sol";  // link to these contracts below

contract ZonoToken is BasicToken { 

    function deposit() payable
    {
        owner.transfer(msg.value); // see Note 2
        uint newTokens = (msg.value * 10) / 1 ether;
        balances[msg.sender] = balances[msg.sender] + newTokens;
    }

    // fallback function
    function() payable { deposit(); }
}

Notes:

  1. The math of "1 ETH for 10 Tokens" depends on how many decimal places your token has. Above, I assumed that the tokens are indivisible (0 decimals), but with decimals places you would need to adjust the math on the line setting newTokens.
  2. Security consideration: we are assuming that owner is not a contract here. This link explains why we may want to use another pattern for sending ether around (e.g. the withdrawal pattern)

Links:

  • 1
    thanks! I confirmed the ETH transfer. I added findings. Now I'm looking into getBlance call. – zono Aug 15 '17 at 10:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.