我正在尝试在 Solidity 中创建自己的代币,并使用 Web3 使用
NodeJS/ExpressJS
将代币从一个帐户转移到另一个帐户。
我一直将
Infura
与 rinkeby
一起使用。
我可以调用我的方法
balanceOf
,但我无法调用transferFrom
错误:
返回错误:执行已恢复
const express = require('express');
const app = express();
const web3 = require('web3');
const INFURA_BASE_URL = 'https://rinkeby.infura.io/v3/';
const INFURA_API_KEY = '........';
web3js = new web3(new web3.providers.HttpProvider(INFURA_BASE_URL + INFURA_API_KEY));
/*
Sender & Receiver keys
*/
const SENDER_PUBLIC_KEY = '........';
const SENDER_PRIVATE_KEY = '.......';
const RECEIVER_PUBLIC_KEY = '......';
/*
Contract ABI.
*/
const CONTRACT_ABI = [
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [
{
"name": "",
"type": "uint8"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_value",
"type": "uint256"
}
],
"name": "burn",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "burnFrom",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
},
{
"name": "_extraData",
"type": "bytes"
}
],
"name": "approveAndCall",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
},
{
"name": "",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"name": "initialSupply",
"type": "uint256"
},
{
"name": "tokenName",
"type": "string"
},
{
"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"
},
{
"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"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Burn",
"type": "event"
}
];
const CONTRACT_ABI_ADDRESS = '............';
/*
A controller listening at: http://localhost:3000/send
*/
app.get('/send', async function (req, apiResponse) {
// Creating contract object
const contract = new web3js.eth.Contract(CONTRACT_ABI, CONTRACT_ABI_ADDRESS, {from: SENDER_PUBLIC_KEY});
// Check the balance (working good)
await contract.methods.balanceOf(RECEIVER_PUBLIC_KEY)
.call()
.then(res => {
const str = web3.utils.fromWei(res);
console.log('balance: ', str);
})
.catch(err => {
console.log(err);
});
// Set the allowance (working)
await contract.methods.approve(SENDER_PUBLIC_KEY, 1)
.call()
.then(res => {
console.log('approve: ', res);
})
.catch(err => {
console.log('Error [approve]', err);
});
// Initiate a transfer (not working)
await contract.methods.transferFrom(SENDER_PUBLIC_KEY, RECEIVER_PUBLIC_KEY, 1)
.call()
.then(res => {
console.log('transferFrom: ', res);
})
.catch(err => {
console.log('Error [transferFrom]', err);
});
});
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000`)
})
我的 Solidity 代码在这里。
我已经奋斗了好几天了,没有任何进展。看不出问题出在哪里。
我的目标是将代币从 NodeJS 中的一个帐户转移到另一个帐户。
第 106 行抛出异常,因为不满足此条件:
_value <= allowance[_from][msg.sender]
您需要在调用
allowance
函数之前设置 transferFrom()
,最有可能通过调用 approve()
函数来设置。
或者,如果您想要简单转账(不使用津贴),请使用
transfer()
功能。
此外,
call()
用于读取纯函数/视图函数的输出。要与外部/公共功能交互(发送以太坊交易),请使用 .send({from: <senderAddress>})
。
示例来自 https://web3js.readthedocs.io/en/v1.3.4/web3-eth-contract.html#web3-eth-contract
contract.methods.somFunc().send({from: ....})
当调用者不是所有者时它也会恢复,同时检查合约的所有者。