将 ERC20 代币从 DApp/Smart 合约转移到 Node.js 服务器上的用户

Transfering ERC20 Tokens from DApp/Smart Contract to user on a Node.js server

我有一个已发送到我的 DApp 的自定义令牌,我正在尝试向我的用户发送一些 'rewards' 用于在网站上发布内容。但是,我的后端 server/DApp 似乎没有向用户发送任何内容。我想知道我在这里可能做错了什么。代码如下:

server.js

(基本思路 - 调用 approve 然后 transferFrom

app.post('/send-TOKEN-to-addr', async (req, res) => {

    const post_addr = req.body.addr; // the client sends in user's addr
    var transfer_amt = 5000; // token reward to user
    

    try {
        console.log('send-TOKEN-to-addr gets called for :: '+String(post_addr));
        TOKEN_Contract.methods.approve(DAppAddr, regular_post_transfer_amt).call((err, result) => { 
            console.log('approve:: '+String(result));
            //return res.send(result);
        });
        TOKEN_Contract.methods.transferFrom(DAppAddr, post_addr, transfer_amt).call((err, result) => { 
            //console.log(result);
            return res.send(result);
        });
    
    } catch (e) { throw e; }
});

在后端我得到:

send-TOKEN-to-addr gets called for :: 0xb65ec054bd7f633efd8bd0b59531de464046a7c0

approve:: true

但是在前端我没有得到任何回应。同样,当我检查 TOKEN 的 DApp 和 addr 的余额时,没有任何变化,所以我认为这里没有发生任何事情。

我正在寻求有关让我的 DApp 将其拥有的代币发送到其他地址的建议。我确认 DApp 已经有了令牌,我似乎无法在我的 node.js 框架内代表它发送。

编辑 1

我的令牌(在 DApp 中)已经有一些基本功能,例如下面的调用:

app.post('/balanceOf-TOKEN-by-addr', async (req, res) => {

    //console.log('balanceOf-TOKEN-by-addr - server');
    const post_addr = req.body.addr;
    //console.log(post_addr);

    try {
        
        TOKEN_Contract.methods.balanceOf(post_addr).call((err, result) => { 
            //console.log(result);
            return res.send(result);
        });
    
    } catch (e) { throw e; }
});

编辑 2

为我如何初始化我的 DApp 添加代码 - 我需要私钥来调用它的 send() 方法?因为我的DApp有一堆TOKEN我要发出去

const WEB3_PROVIDER = "HTTP://127.0.0.1:7545"
if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
    console.log("web3 already initialized.");
} else {
    // set the provider you want from Web3.providers
    web3 = new Web3(new Web3.providers.HttpProvider(WEB3_PROVIDER));
    console.log("New web3 object initialized.");
}

const DAppABIFile = require('./assets/abis/DAppABI'); 
const DAppABI = DAppABIFile.DAppABI;
const DAppAddr = "0x5C7704a050286D742............"; // public key
const DAppContract = new web3.eth.Contract(DAppABI, DAppAddr);

首先检查你用来调用函数的钱包是否是代币的所有者而不是 dapp,如果 dapp 是所有者我会推荐你​​用来调用合约的地址拥有所有者权限并添加 dapp 合约功能以将令牌发送到某个地址,如果您使用的地址是令牌的所有者,只需调用 ´TOKEN_CONTRACT.methods.transfer(post_addr,transfer_amt)´

现在,作为一个解释,因为那个端点没有发送令牌的原因是,在那个操作中使用了 4 个地址,用户地址,合约地址,令牌地址和你正在使用的地址从后端发送交易,当您调用 TOKEN_Contract.methods.approve(DAppAddr, regular_post_transfer_amt) 时,您正在批准合约地址以移动拥有您在后端使用的地址的代币,反之亦然,因为合约会进行该调用并传递为a参数后端地址,所以当你调用TOKEN_Contract.methods.transferFrom(DAppAddr, post_addr, transfer_amt)时,你试图将已批准的合约令牌移动到后端地址并将其发送到用户地址,但此批准令牌的数量为0,因为我之前解释过的事情

调用(只读)和事务(读写)是有区别的。

您的代码段仅调用合约但不发送交易。因此,合同无法仅从调用中写入状态更改。

TOKEN_Contract.methods.<method>.call((err, result) => {});

Web3 使用 .send() 函数 (docs) 发送交易。

TOKEN_Contract.methods.<method>.send({
    from: '0x<sender_address>'
}, (err, result) => {});

注意交易需要用from地址的私钥进行签名。这可以通过两种方式完成:

  1. 节点提供者(很可能在 new Web3(<provider_url>) 构造函数中传递)知道发件人地址的私钥并解锁其帐户 - 这通常仅在用于发展。

  2. 您已使用 wallet.add() 函数 (docs) 将发件人私钥传递给您的 web3 实例。然后它在你的 JS 应用程序中被签名,并且在后台发送到节点的有效负载只包含签名的交易(而不是私钥)。

您也可以将此地址设置为 defaultAccount (docs),这样您就不必一直将其传递给 .send() 函数。