2

I'm trying to implement a solidity "purchase" function into web3. Ultimately, I want to have a button where a user would then have metamask open to send a fixed amount(1 ether for a simple example) to the smart contract in exchange for an ERC20 token. I've learned how to transfer tokens between two wallets, but now I'd like to go a step further and learn how to send Ether to receive an ERC20. This is the solidity "purchase" function I've been using:

function purchase(uint amount, uint tokens) public payable{
        require (msg.value >= amount * 1 ether, "You must pay at least 1 ether per token");
        balances[address (this)] -= tokens;
        balances[msg.sender] += tokens; 

Right now I've been using this with an Onclick button in conjunction with metamask to transfer ERC20's:

async function transfer() {
        contract.methods.transfer("Address", "Token quantity").send({
        from: "Address"});

Do you have any tips on how to go about making this Ether to ERC20 function in JS? Thank you!

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • Okay, I've successfully used the Purchase function to send 1 Ether to my smart contract and receive an ERC20 token in return, although I'm only able to do this transaction with the address that I plug into the function: ``` async function purchase(){ contract.methods.purchase("1","1").send({ from: "Address", to: "Address", value: web3.utils.toWei("1", "ether") }); ``` How would any sender use this "Purchase" function to interact with the contract instead of just a specified address? Thanks! – Brian Lee Victory Aug 07 '21 at 00:10

1 Answers1

2

There is insufficient information in the question. If you are asking how to call the purchase you have written in solidity then answer is as follow:

contract.methods.purchase("amount", "Token quantity").send({
    from: "Address", value: ("amount"*"Token quantity"(in wei)) });
Arrow
  • 103
  • 9
  • Thanks for reply. Yes, I'm trying to call the Purchase function in Solidity. My goal is for a user to send 1 ether to the contract in return for 1 token. I'm making progress but I'm getting a failed transaction in metamask. I'm using: ``` async function purchase(){ contract.methods.purchase("Address","1").send({ from: "Address", to:"Address", value: web3.utils.toWei("1", "ether") }); ``` "Uncaught (in promise) Error: Transaction has been reverted by the EVM:" – Brian Lee Victory Aug 05 '21 at 00:26
  • 1
    contract.methods.purchase("Address","1") => contract.methods.purchase(1, 1) 1st parameter in you contract is amount in uint not an address also tokens should be in uint. And also i think the contract is not written properly it should only have one param tokenAmount – Arrow Aug 05 '21 at 06:14
  • If you want I can rewrite solidity code as well ! Just let me know – Arrow Aug 05 '21 at 06:17
  • Okay thanks, I'll look at the parameters again. I have my ERC20 Interface with: ``` function purchase(uint amount, uint tokens) public payable; ``` Then in my contract I inherited it with: ``` function purchase(uint amount, uint tokens) public payable{ require (msg.value >= amount * 1 ether, "You must pay at least 1 ether per token"); balances[address (this)] -= tokens; balances[msg.sender] += tokens; ``` Yes, I would like to know how you would rewrite it, thanks! – Brian Lee Victory Aug 05 '21 at 13:08
  • `pragma solidity >=0.6.0 <0.7.0; interface ERC20 { function mint(address reciever, uint256 value) external returns(bool); function transfer(address to, uint256 value) external returns(bool); } contract tokenSale { ERC20 Token; constructor(address tokenAddress) public { Token = ERC20(tokenAddress); } function purchase(uint _tokensAmount) public payable{ require (msg.value >= _tokensAmount * 1 ether, "You must pay at least 1 ether per token"); Token.mint(msg.sender, _tokensAmount) } }` – Arrow Aug 08 '21 at 07:36
  • above one is tokenSale contract and you will have ur token address as well and pass it's address in this contractor with a mint function which will create new token and assign it to user who paid. P.S sorry for the delay – Arrow Aug 08 '21 at 07:37
  • Thank you! I've successfully used the Purchase function to send 1 Ether to my smart contract and receive an ERC20 token , but I'm only able to do this transaction with an address that I plug into the function: ``` async function purchase(){ contract.methods.purchase("1","1").send({ from: "Address", to: "Address", value: web3.utils.toWei("1", "ether") }); ``` How would any sender use this "Purchase" function to interact with the contract instead of just a specified address? Thanks! – Brian Lee Victory Aug 09 '21 at 01:00
  • 1
    Are you using metamask ? And How are you calling the purchase function is there a button or what ? – Arrow Aug 09 '21 at 03:45
  • Yes, exactly! On my site I have a button that has the onclick binded to it so that when a user clicks on the button it calls the "purchase" function and opens metamask with the 1 ether requirement. I'm able to have it function but only when I have a specific address plugged into the "from:address". My problem is that I'm new to web3 and don't know how to have a sort of "msg.sender" equivalent, or a way to see a metamask user's address. Is there a way to tell the function to use current metamask address that's calling the function? – Brian Lee Victory Aug 09 '21 at 04:17
  • 1
    yes `const Web3 = require("web3"); const ethEnabled = async () => { if (window.ethereum) { await window.ethereum.send('eth_requestAccounts'); window.web3 = new Web3(window.ethereum); return true; } return false; } if (!ethEnabled()) { alert("Please install MetaMask to use this dApp!"); }` this would give you access ... If metamask is not connect to ur website this will promt it to connect – Arrow Aug 09 '21 at 04:59
  • Once connected `function getAccounts(callback) { web3.eth.getAccounts((error,result) => { if (error) { console.log(error); } else { callback(result); } }); } getAccounts(function(result) { console.log(result[0]); });` use this You will have the connect address and offcourse there is better way to make it look preatter but this would work. – Arrow Aug 09 '21 at 05:01
  • Thank you so much for the help. After tinkering with the function I was able to call the "purchsae" function from any address! In the function's from address I plugged in "window.web3.currentProvider.selectedAddress" which worked! – Brian Lee Victory Aug 09 '21 at 16:39